Docker コンテナで Embulk を動かせるようにし、テストとして csv ファイルを orc ファイルに変換してみる
Embulk ?
バッチ的にファイルやデータベースからデータを吸い出し、別のストレージやデータベースにロードできるツール
詳細は公式ドキュメントか、下記開発者の方のブログを参照ください
環境情報
- Mac OS X Catalina 10.15.7
- Docker version: 20.10.0
- orc-tools version: ORC 1.6.6
- 最後に orc ファイルの中身を見る時に使用
- Homebrew でインストール可能
Docker コンテナ内で、手動で Embulk をインストール
とりあえずコンテナ立ち上げて、手動で入れてみる
docker run -it --rm java:8 bash
公式ドキュメントにあるやり方で embulk をインストール
- 後々イメージ化することを考えると
$HOME
配下にパスを通すのが難しいので、実行ファイルのインストール場所は、/usr/local/bin
にする - なので、公式の手順内の
~/.embulk/bin/embulk
の箇所は、/usr/local/bin/embulk
に書き換える - 手順内の PATH の更新の箇所も行わない
curl --create-dirs -o /usr/local/bin/embulk -L "https://dl.embulk.org/embulk-latest.jar"
chmod +x /usr/local/bin/embulk
公式ドキュメントにあるクイックスタートに沿って実際に動かしてみる
embulk example ./try1
embulk guess ./try1/seed.yml -o config.yml
embulk run config.yml
embulk run
の結果、以下のような結果が標準出力されればOK
1,32864,2015-01-27 19:23:49,20150127,embulk
2,14824,2015-01-27 19:01:23,20150127,embulk jruby
3,27559,2015-01-28 02:20:02,20150128,Embulk "csv" parser plugin
4,11270,2015-01-29 11:54:36,20150129,
↑ で何をやったのか
-
try1/csv/sample_01.csv.gz
の中身を、stdout (標準出力) に出力した
config.yml の中身
root@7e9764e79b83:/# cat config.yml
in:
type: file
path_prefix: /./try1/csv/sample_
decoders:
- {type: gzip}
parser:
charset: UTF-8
newline: LF
type: csv
delimiter: ','
quote: '"'
escape: '"'
null_string: 'NULL'
trim_if_not_quoted: false
skip_header_lines: 1
allow_extra_columns: false
allow_optional_columns: false
columns:
- {name: id, type: long}
- {name: account, type: long}
- {name: time, type: timestamp, format: '%Y-%m-%d %H:%M:%S'}
- {name: purchase, type: timestamp, format: '%Y%m%d'}
- {name: comment, type: string}
out: {type: stdout}
try1/csv/sample_01.csv.gz
の中身確認
root@7e9764e79b83:/# zcat try1/csv/sample_*
id,account,time,purchase,comment
1,32864,2015-01-27 19:23:49,20150127,embulk
2,14824,2015-01-27 19:01:23,20150127,embulk jruby
3,27559,2015-01-28 02:20:02,20150128,"Embulk ""csv"" parser plugin"
4,11270,2015-01-29 11:54:36,20150129,NULL
Dockerfile作成 & コンテナ起動
動作確認が終わったので、上記手動手順を Dockerfile 化する
- ENTRYPOINT で、
/usr/local/vin/embulk
を指定したかったが、ENTRYPOINT では jar を直接的に起動できないので、java -jar
で起動
Dockerfile
FROM java:8
# Install embulk
RUN curl --create-dirs -o /usr/local/bin/embulk -L "https://dl.embulk.org/embulk-latest.jar" &&\
chmod +x /usr/local/bin/embulk
ENTRYPOINT ["java", "-jar", "/usr/local/bin/embulk"]
build
docker build -t embulk .
確認
docker run -it --rm embulk:latest embulk --version
Embulk v0.9.23
コンテナ内の embulk で csv ファイルを orc 変換
せっかくなので、実際に embulk を使用して csv ファイルを orc ファイルに変換してみる
Dockerファイルを修正
- 先程の Docker ファイルに以下を追加
-
embulk-output-orc プラグイン のインストール
- プラグインは、
embulk gem install ${パッケージ名}
のようにしてインストールする
- プラグインは、
- WORKDIR を /work に設定
-
embulk-output-orc プラグイン のインストール
Dockerfile
FROM java:8
# Install embulk
RUN curl --create-dirs -o /usr/local/bin/embulk -L "https://dl.embulk.org/embulk-latest.jar" &&\
chmod +x /usr/local/bin/embulk
RUN embulk gem install embulk-output-orc
WORKDIR /work
ENTRYPOINT ["java", "-jar", "/usr/local/bin/embulk"]
build
docker build -t embulk .
作業ディレクトリの構成
.
├── Dockerfile
└── work
├── config.yml
├── csv_inputs
│ └── sample_01.csv.gz
└── orc_outputs
動作イメージ
-
work/config.yml
に書いてある設定に沿って、./work/csv_inputs/sample_01.csv.gz
を orc 変換して、./work/orc_outputs/
配下に出力
work/config.yml
ファイル中身
- 先程のクイックスタートでできた
config.yml
内のout
をtype: orc
に書き換えている - 今回はデータ量が少なく、空ファイルが出来てしまうのを防ぐため、
exec
の内で、min_output_tasks
を1にしてファイルを分散させないようする
config.yml
exec:
min_output_tasks: 1
in:
type: file
path_prefix: /work/csv_inputs/sample_
decoders:
- {type: gzip}
parser:
charset: UTF-8
newline: LF
type: csv
delimiter: ','
quote: '"'
escape: '"'
null_string: 'NULL'
trim_if_not_quoted: false
skip_header_lines: 1
allow_extra_columns: false
allow_optional_columns: false
columns:
- {name: id, type: long}
- {name: account, type: long}
- {name: time, type: timestamp, format: '%Y-%m-%d %H:%M:%S'}
- {name: purchase, type: timestamp, format: '%Y%m%d'}
- {name: comment, type: string}
out:
type: orc
path_prefix: /work/orc_outputs/sample
compression_kind: ZLIB
overwrite: true
input となる csv ファイルの中身も、クイックスタートの時と同じ
# Mac では、zcat は gzcat なので注意
gzcat work/csv_inputs/sample_01.csv.gz
id,account,time,purchase,comment
1,32864,2015-01-27 19:23:49,20150127,embulk
2,14824,2015-01-27 19:01:23,20150127,embulk jruby
3,27559,2015-01-28 02:20:02,20150128,"Embulk ""csv"" parser plugin"
4,11270,2015-01-29 11:54:36,20150129,NULL
実行
- コンテナ内の
WORKDIR (/work)
を、./work
でマウントしている
docker run -it --rm -v $(pwd)/work:/work embulk:latest run config.yml
確認
- orc ファイルができている
ls work/orc_outputs
sample.000.orc
orc ファイルの中身確認
- orc-tools で確認可能
orc-tools data work/orc_outputs/sample.000.orc
log4j:WARN No appenders could be found for logger (org.apache.hadoop.util.Shell).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.apache.hadoop.security.authentication.util.KerberosUtil (file:/usr/local/Cellar/orc-tools/1.6.6/libexec/orc-tools-1.6.6-uber.jar) to method sun.security.krb5.Config.getInstance()
WARNING: Please consider reporting this to the maintainers of org.apache.hadoop.security.authentication.util.KerberosUtil
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
Processing data file work/orc_outputs/sample.000.orc [length: 787]
{"id":1,"account":32864,"time":"2015-01-27 19:23:49.0","purchase":"2015-01-27 00:00:00.0","comment":"embulk"}
{"id":2,"account":14824,"time":"2015-01-27 19:01:23.0","purchase":"2015-01-27 00:00:00.0","comment":"embulk jruby"}
{"id":3,"account":27559,"time":"2015-01-28 02:20:02.0","purchase":"2015-01-28 00:00:00.0","comment":"Embulk \"csv\" parser plugin"}
{"id":4,"account":11270,"time":"2015-01-29 11:54:36.0","purchase":"2015-01-29 00:00:00.0","comment":null}
________________________________________________________________________________________________________________________
変換できている!