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
    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
    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', '[email protected]', 'Male', '11.65.224.59');
insert into MOCK_DATA (id, first_name, last_name, email, gender, ip_address) values (2, 'Ian', 'Danovich', '[email protected]', '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等でロードでき、利用範囲が広いと感じました。