タイトルの通りの内容をただやってみたという内容の記事です。
インストール
Java8インストール
最初にJavaをインストールします。
Embulkは公式サイトに以下のように書いてありました。
Embulk v0.9 and v0.10 run on Java 8. Java 9 is not supported officially.
手元の環境にJava 11が入っていたので、最初手抜きでJava 11のままembulkコマンドを試してみたら以下のようなエラーになりました。
[ERROR] Embulk does not support Java 11 yet.
なので、素直にJava 8を別途インストールします。Ubuntuであれば以下のようなコマンドだと思います。
$ sudo apt install -y openjdk-8-jdk
私はデフォルトのJavaを切り替えたくなかったので、embulkコマンドにだけJava 8が適用されるように設定しました。ここでは詳細は省略しますが、ともかくJava 8がインストールできたものとします。
Embulkインストール
curlコマンドでファイルをダウンロードして実行権限を付与するのみです。
$ curl --create-dirs -o ~/.embulk/bin/embulk -L "https://dl.embulk.org/embulk-latest.jar"
$ chmod +x ~/.embulk/bin/embulk
これをPATHに通しておきます。
インストール完了です。
$ embulk --version
embulk 0.9.23
EmbulkはBashスクリプトに偽装したjarファイル
ダウンロードしたファイルはURLを見ると一見jarファイルですが、先頭にBashスクリプトが書かれており、スクリプトとして直接実行できます。
jarファイルはzipファイルであり、zipファイルはその構造上zipに無関係のデータを埋め込むことができるため、スクリプトを埋め込むことでBashスクリプトに偽装しています。BashだけでなくWindowsのバッチファイルも書かれているようです。Linuxで実行権限を付与すればBashスクリプトになるし、Windowsで拡張子を .bat
にすればバッチファイルになります。
つまり、jarファイル、Bashスクリプトファイル、Windowsバッチファイルの3役を1ファイルで兼務しています。
プラグインインストール
Embulkのプラグインをインストールします。Embulkはfluentdと同じく、プラグインをインストールすることでデータのさまざまな入力元や出力先に対応させられるようです。
PostgreSQLからの入力とS3への出力のためのプラグインをインストールします。
$ embulk gem install embulk-input-postgresql
$ embulk gem install embulk-output-s3
gem
でプラグインをインストールするあたり、fluentdに似てるし、Rubyでできてるんだなって思ったけど、あれ?最初にJavaが必要という話じゃなかったっけ?ってなって混乱しました。なんとJRubyで動いているらしい。
PostgreSQL準備
PostgreSQLに以下のようなサンプルデータを用意しました。
create table sample1 (
id integer,
timestamp1 timestamp,
timestamp2 timestamp with time zone,
msg text
);
insert into sample1 (id, timestamp1, timestamp2, msg) values (1, '2021-11-14T16:00:00', '2021-11-14T16:00:00', 'msg 1');
insert into sample1 (id, timestamp1, timestamp2, msg) values (2, '2021-11-15T16:00:00', '2021-11-15T16:00:00', 'msg 2');
作成結果
postgres=> \d sample1
Table "public.sample1"
Column | Type | Collation | Nullable | Default
------------+-----------------------------+-----------+----------+---------
id | integer | | |
timestamp1 | timestamp without time zone | | |
timestamp2 | timestamp with time zone | | |
msg | text | | |
postgres=> select * from sample1;
id | timestamp1 | timestamp2 | msg
----+---------------------+------------------------+-------
1 | 2021-11-14 16:00:00 | 2021-11-14 16:00:00+00 | msg 1
2 | 2021-11-15 16:00:00 | 2021-11-15 16:00:00+00 | msg 2
(2 rows)
設定ファイル作成
EmbulkはYAMLで設定ファイルを手で書いたら、embulk guess
コマンドで設定ファイルを事前に生成しなおし、実行はembulk run
コマンドという流れです。
-
seed.yml
を手で書く $ embulk guess seed.yml -o config.yml
$ embulk run config.yml
ただ、今回の使い方では seed.yml
と config.yml
の内容にまったく差異がありませんでした。
ひとまず設定ファイルを書きます。PostgreSQLへの接続情報と、S3への接続情報、出力のフォーマットなどを書きます。
in:
type: postgresql
host: xxxxxxxx.xxxxxxxx.ap-northeast-1.rds.amazonaws.com
user: postgres
password: "xxxxxxxx"
database: postgres
table: sample1
out:
type: s3
endpoint: s3-ap-northeast-1.amazonaws.com
access_key_id: XXXXXXXX
secret_access_key: xxxxxxxx
bucket: xxxxxxxx
path_prefix: embulk
file_ext: .csv.gz
sequence_format: .%03d.%02d
formatter:
type: csv
delimiter: ","
newline: LF
charset: UTF-8
default_timezone: "Asia/Tokyo"
encoders:
- type: gzip
embulk guess
コマンドで設定ファイルを生成
$ embulk guess seed.yml -o config.yml
以下のコマンドで見てみたら、まったく差異がなかったです。
$ diff <(yq . < seed.yml) <(yq . < config.yml)
実行
上述の通りembulk guess
コマンドに意味がなかったので、以下のどちらのコマンドで同じように動きました。
$ embulk run seed.yml
$ embulk run config.yml
S3バケットに embulk.000.00.csv.gz
という名前のファイルができます。中身は以下のようなCSVファイルでした。
$ aws s3 cp s3://xxxxxxxx/embulk.000.00.csv.gz - | gunzip -c
id,timestamp1,timestamp2,msg
1,2021-11-14 16:00:00.000000 +0900,2021-11-15 01:00:00.000000 +0900,msg 1
2,2021-11-15 16:00:00.000000 +0900,2021-11-16 01:00:00.000000 +0900,msg 2
以上。