search
LoginSignup
3

posted at

updated at

EmbulkでMySQLからPostgreSQLへデータ転送

はじめに

異なるRDBMS間で、データを転送する業務が発生しました。
調べている中で、今更ながらEmbulkを知ったのでその使い方のメモです。
今回は、MySQL -> PostgreSQLのデータロードを行います。

Embulkとは

公式のGitHubより

Embulk is a parallel bulk data loader that helps data transfer between various storages, databases, NoSQL and cloud services.
Embulk supports plugins to add functions. You can share the plugins to keep your custom scripts readable, maintainable, and reusable.

ザックリ説明すると

  • Embulkとは大量のデータを並列でロードを行うツール
  • ロードの入出力先はストレージ、データベース、NoSQLやクラウドサービスが対応
  • プラグインを使用することで、機能を追加することが可能

環境構築

Dockerを利用して、環境構築を行います。

前提

  • Docker, Docker Composeをインストール済み

ディレクトリ構成

embulk
├── Dockerfile
├── docker-compose.yml
├── mysql
│   └── init
│       ├── 01_database.sql
│       └── 02_mock_data.sql
└── postgres
    └── init
        └── 01_database.sql

データベース

Docker Composeを利用してMySQLとPostgreSQlを構築します。

docker-compose.yml
version: "3"
services:
  mysql:
    image: mysql:5.7
    ports:
      - "3306:3306"
    volumes:
      - ./mysql/init:/docker-entrypoint-initdb.d
    command: --default-authentication-plugin=mysql_native_password
    environment:
      MYSQL_ROOT_PASSWORD: root

  postgres:
    image: postgres:12
    ports:
      - "5432:5432"
    environment:
      POSTGRES_USER: root
      POSTGRES_PASSWORD: root
    volumes:
      - ./postgres/init:/docker-entrypoint-initdb.d/

  adminer:
    image: adminer
    ports:
      - 8080:8080

データベースの初期化

MySQL

ここからサンプルデータのsqlをダウンロードします。

mysql/init/01_database.sql
create database embulk_in;
mysql/init/02_mock_data.sql
se embulk_in;

create table MOCK_DATA (
	id INT,
	first_name VARCHAR(50),
	last_name VARCHAR(50),
	email VARCHAR(50),
	gender VARCHAR(50),
	ip_address VARCHAR(20)
);
insert into MOCK_DATA (id, first_name, last_name, email, gender, ip_address) values (1, 'August', 'Stribling', 'astribling0@meetup.com', 'Male', '11.65.224.59');
insert into MOCK_DATA (id, first_name, last_name, email, gender, ip_address) values (2, 'Ian', 'Danovich', 'idanovich1@i2i.jp', 'Male', '135.187.239.143');
...

PostgreSQL

postgres/init/01_database.sql
create database embulk_out;

embulk

Embulk用のDockerfileを作成します。

こちらを参考にDockerfileを作成します。

Dockerfile
FROM openjdk:8-jre-alpine

# install Embulk
RUN wget -q https://dl.embulk.org/embulk-latest.jar -O /bin/embulk \
    && chmod +x /bin/embulk

# add plugin
RUN apk add --no-cache libc6-compat \
    && embulk gem install embulk-input-mysql \
    && embulk gem install embulk-output-postgresql 

WORKDIR /embulk

ENTRYPOINT ["java", "-jar", "/bin/embulk"]

プラグイン

起動

embulkのイメージ作成し、コンテナを起動します。

# embulkのイメージを作成
docker build -y embulk .
# MySQLとPostgreSQLのコンテナを起動
docker-compose up -d

確認

AdminerからMySQLのデータを確認します。

ロード

コンフィグファイルの作成

MySQLからPostgreSQLへデータをロードするためのコンフィグファイルを作成します。

embulk/seed.yml
in:
  type: mysql
  host: {localhostのプライベートアドレス}
  user: root
  password: "root"
  database: embulk_in
  table: MOCK_DATA
out:
  type: postgresql
  host: {localhostのプライベートアドレス}
  user: root
  password: "root"
  database: embulk_out
  table: MOCK_DATA
  mode: insert
  column_options:
    id: { type: "INT" }
    first_name: { type: " VARCHAR(50)" }
    last_name: { type: " VARCHAR(50)" }
    email: { type: " VARCHAR(50)" }
    gender: { type: " VARCHAR(50)" }
    ip_address: { type: " VARCHAR(20)" }

実行

ロードを行います。

# seed.ymlから完全なコンフィグファイルを生成
docker run --rm -it -v $(pwd):/embulk embulk guess seed.yml -o config.yml
# dry run
docker run --rm -it -v $(pwd):/embulk embulk preview config.yml
# 実行
docker run --rm -it -v $(pwd):/embulk embulk run config.yml

確認

AdminerからPostgreSQLのデータを確認します。

終わりに

利用したいプラグインがない場合でも(Hiveとか)、JDBCが存在すればembulk-input-jdbcでロードでき、利用範囲が広いと感じました。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
3