この記事では、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 に入れておいたのと同じデータが入っている。