実現したこと
MySQLの特定のテーブルをBigQueryへ毎日転送する
雑ですがイメージこんな感じです!
定期実行には、EventBridge Schedulerを使いました!
Embulkとは
Embulkは、さまざまなデータベースやクラウドサービス間のデータ転送を可能にする並列バルクデータローダーです。
今回で言うと、AWS->GCP でのデータ転送に使いました!
作業手順
1. Embulkを起動するECS TaskをDockerfileで作成
embulkのインストールがもっとスッキリいくはずだったのですが、上手くいかず結局手動で必要なものをインストールしました・・・・
FROM openjdk:8-jre-slim
WORKDIR /home
ENV EMBULK_VERSION 0.9.25
RUN apt-get update && apt-get install -y \
curl \
# Install embulk
&& curl -o /usr/local/bin/embulk --create-dirs -L "http://dl.embulk.org/embulk-${EMBULK_VERSION}.jar" \
&& chmod +x /usr/local/bin/embulk \
# Install independencies for embulk-output-bigquery
&& embulk gem install faraday -v 0.17.4 \
&& embulk gem install multi_json -v 1.15.0 \
&& embulk gem install jwt -v 2.3.0 \
&& embulk gem install public_suffix -v 4.0.7 \
&& embulk gem install addressable -v 2.7.0 \
&& embulk gem install signet -v 0.11.0 \
&& embulk gem install multipart-post -v 2.1.1 \
&& embulk gem install multipart-post -v 2.1.1 \
&& embulk gem install declarative-option -v 0.1.0 \
&& embulk gem install declarative -v 0.0.20 \
&& embulk gem install uber -v 0.1.0 \
&& embulk gem install representable -v 3.0.4 \
&& embulk gem install retriable -v 3.1.2 \
&& embulk gem install mini_mime -v 1.0.2 \
&& embulk gem install memoist -v 0.16.2 \
&& embulk gem install os -v 1.1.0 \
&& embulk gem install googleauth -v 0.9.0 \
&& embulk gem install httpclient -v 2.8.3 \
&& embulk gem install google-api-client -v 0.32.1 \
&& embulk gem install google-cloud-env -v 1.2.1 \
&& embulk gem install google-cloud-core -v 1.3.0 \
# Install gem at ~/.embulk
&& embulk gem install embulk-input-mysql \
&& embulk gem install embulk-output-bigquery
# Embulk用の設定ファイルを定義
COPY ./config ./config
# TODO:GPCでサービスアカウントを発行する
COPY ./service-account.json ./service-account.json
COPY ./entrypoint.sh ./entrypoint.sh
RUN chmod +x entrypoint.sh
CMD ["/bin/sh", "entrypoint.sh"]
# entrypoint.shファイル
#!/bin/bash
# Use -Xmx800m option to prevent Java heap error
java -Xmx800m -jar /usr/local/bin/embulk run ./config/mysql.yml.liquid
2. Embulk用の設定ファイルの作成
embulkの設定が結構大変でした、、、
# config/mysql.yml.liquidファイル
in:
type: mysql
host: {{ env.DB_HOST }}
user: {{ env.DB_USER }}
password: {{ env.DB_PASSWORD }}
database: {{ env.DB_NAME }}
table: {{ env.table }}
ssl: true
options: { enabledTLSProtocols: TLSv1.2 }
parser:
type: json
out:
type: bigquery
mode: replace
auth_method: service_account
json_keyfile: /home/service-account.json
file_ext: .jsonl.gz
source_format: NEWLINE_DELIMITED_JSON
auto_create_dataset: true
dataset: mysql
auto_create_table: true
table: {{ env.table }}
formatter: {type: jsonl}
encoders:
- {type: gzip}
3. 定期実行の設定
EventBridge Schedulerはこれがわかりやすかったです!
<参考にさせていただいた記事>
躓いたところ
①タスクが起動しない・・・
ポリシーにこれが必要だった AmazonECSTaskExecutionRolePolicy
とにかく動かすことベースで良いなら下記あたりを付与すると良いと思います!
<参考にさせていただいた記事>
②やっぱりタスクが起動しない・・・
タスク定義時にCloudWatch Logsを設定して、起動時のエラーを確認すると、タスク起動時に以下のエラーが出ていました。
(ECSデバッグしにくい・ログ見にくいのが辛い。。。)
exec /docker-entrypoint.sh: exec format error
ちょっと調べてみると、多分ECRのイメージのプラットフォームと、実行するプラットフォームに互換性が無い場合に発生するエラーらしいです(多分)
■手元で確認してみると
タスク定義で設定したplatformがx86_64で
作成したコンテナイメージがarm64だった(んだと思います)
■解決方法 ECR上げ直し
プッシュコマンドは基本コピペだと思いますが、buildするときに
docker build --platform linux/x86_64 -t test-ecr .
のように --platform linux/x86_64
を入れてあげると治りました。
終わりに
EmbulkやECS/ECRの知見があまりなく、、、もっと良い方法があったら是非教えてください!
ここまで読んでいただきありがとうございました!