この記事では、Embulk を使ってデータ転送を行う方法について述べていく。
今回は題材として Amazon RDS から Google Cloud の BigQuery にデータを転送する。Embulk の実行はローカルマシンで行う。
使っている Embulk のバージョンは0.9.25。
0.10や0.11だと異なる手順や設定が必要になると思われるので注意。
事前準備
まずは Amazon RDS のインスタンスを作成する。今回はデータベースの種類は MySQL にした。バージョンは8.0.35。
ローカルマシンから Embulk を実行する都合上、パブリックアクセスを「あり」にしておく必要がある。そして、セキュリティグループを適切に設定し、ローカルマシンの IP アドレスからのアクセスを許可しておく必要もある。
作成後は$ docker run -it --rm mysql mysql -u admin -p -h <RDSインスタンスのエンドポイント>でインスタンスにログインし、以下のクエリを実行する。
CREATE DATABASE source_db; USE source_db; CREATE TABLE user ( id INT NOT NULL AUTO_INCREMENT, name VARCHAR(191) NOT NULL, PRIMARY KEY (id) ); INSERT INTO user (name) VALUES ('Alice'), ('Bob');
source_dbというデータベースを作り、そのなかにuserテーブルを作成、以下のデータを投入した。
mysql> SELECT * FROM user; +----+-------+ | id | name | +----+-------+ | 1 | Alice | | 2 | Bob | +----+-------+ 2 rows in set (0.01 sec)
このデータを BigQuery に転送するのが今回の目的。
次に BigQuery 側の準備を行う。
任意の GCP プロジェクトの BigQuery にdestination_datasetというデータセットを用意しておく。テーブルは作らなくてよい。
RDS だけでなく BigQuery にアクセスする権限も必要なので、サービスアカウントキーを JSON 形式で発行しておく。
ローカルマシンで Embulk を実行できるようにする
今回は Docker を使って Embulk の実行環境を用意する。
Dockerfileとinit_embulk_commands.sh、2 つのファイルを用意する。
まずはDockerfile。
FROM openjdk:8-jdk
# embulk.jarをダウンロード
RUN mkdir -p /root/.embulk/bin && \
curl -o /root/.embulk/bin/embulk.jar -L "https://dl.embulk.org/embulk-0.9.25.jar"
# 必要なgemをインストールするためのスクリプトを追加
COPY init_embulk_commands.sh /root/init_embulk_commands.sh
RUN chmod +x /root/init_embulk_commands.sh && /root/init_embulk_commands.sh
WORKDIR /workspace
# embulk実行のためのシェルコマンドを設定
RUN echo '#!/bin/bash\njava -classpath "/root/.embulk/bin/embulk.jar:/root/.embulk/lib/postgresql.jar" org.embulk.cli.Main "$@"' > /usr/local/bin/embulk && \
chmod +x /usr/local/bin/embulk
CMD [ "embulk", "--version" ]
このなかでinit_embulk_commands.shをコピーしそれを実行している。
Dockerfileのコメントに書いたようにこれは、必要な gem をインストールするためのシェルスクリプト。
まずは以下の内容にする。
#!/bin/bash # embulk.jarへのパス EMBULK_JAR="/root/.embulk/bin/embulk.jar" # 必要なgemをインストール java -jar $EMBULK_JAR gem install embulk -v 0.9.25
この状態で$ docker build -t embulk-image .を実行して Docker image を作成する。
そしてその image から Docker container を作成・実行して Embulk のバージョンが表示されれば、Embulk の実行は成功。
$ docker run --rm embulk-image embulk 0.9.25
転送設定を記述し実行する
Embulk を動かすことに成功したので次は、転送元と転送先を設定し、実際に転送を行うようにする。
Embulk は多種多様なデータソースを対象としており、今回対象とした MySQL と BigQuery 以外にも、 Redshift や Snowflake なども対象にすることができる。
これを可能にしているのがプラグインシステムであり、対応するプラグインさえあれば、転送元や転送先を自由に設定できる。
今回の例では MySQL を転送元、BigQuery を転送先にするので、embulk-input-mysqlとembulk-output-bigqueryというプラグインが必要になる。
init_embulk_commands.shを以下のように書き換えて、Docker image の作成時に必要なプラグインがインストールされるようにする。
#!/bin/bash # embulk.jarへのパス EMBULK_JAR="/root/.embulk/bin/embulk.jar" # 必要なgemをインストール java -jar $EMBULK_JAR gem install embulk -v 0.9.25 java -jar $EMBULK_JAR gem install embulk-input-mysql java -jar $EMBULK_JAR gem install jwt -v 2.3.0 java -jar $EMBULK_JAR gem install multipart-post -v 2.1.1 java -jar $EMBULK_JAR gem install public_suffix -v 4.0.7 java -jar $EMBULK_JAR gem install mini_mime -v 1.0.2 java -jar $EMBULK_JAR gem install representable -v 3.0.4 java -jar $EMBULK_JAR gem install embulk-output-bigquery -v 0.6.4
使いたいプラグイン以外にも様々な gem をインストールしているが、それらは、embulk-output-bigqueryの依存関係を解決するために必要な gem。
必要な gem とそのバージョンは以下の記事を参考にした。
embulk-input-bigqueryのインストールでエラー - kikukawa's diary
そしてDockerfileのCMD [ "embulk", "--version" ]をCMD ["embulk", "run", "config.yml"]に書き換える。
config.ymlは Embulk の転送設定を記述するファイルであり、どのデータをどこに転送するのか記述していく。
今回は以下の内容のembulk/config.ymlを用意する。
in: type: mysql host: RDSインスタンスのエンドポイント port: 3306 user: admin password: "rds password" database: source_db table: user select: "*" out: type: bigquery mode: replace auth_method: json_key json_keyfile: "key.json" project_id: BigQueryのプロジェクト名 dataset: destination_dataset table: user auto_create_table: true
inが転送元でoutが転送先。
out.json_keyfileにはサービスアカウントキーのパスを記述する。今回はkey.jsonにしたので、config.ymlと同じディレクトリ、つまりembulkディレクトリにkey.jsonとして置いておく。
つまり以下の構成になる。
. ├── Dockerfile ├── embulk │ ├── config.yml │ └── key.json └── init_embulk_commands.sh
この状態で再び image を作り、そこから container を作成し実行する。container がconfig.ymlやkey.jsonを利用できるように、-vオプションで Volume を作っている。
$ docker build -t embulk-image . $ docker run --rm -v "$(pwd)/embulk:/workspace" embulk-image
そうするとdestination_datasetにuserテーブルが作られ、RDS に入れておいたのと同じデータが入っている。

