What is it, naokirin?

Embulkでバッチ処理をしてみよう 其の2

前回の其の1では、簡単なEmbulkの説明とサンプルをもとにデータインプットとアウトプットに対してEmbulkを動かすところまでを見ていきました。

前回: Embulkでバッチ処理をしてみよう 其の1 - what is it, naokirin?

今回は embulkコマンドや設定の詳細についてを掘り下げていきます。細かい点については help で出てくる内容を見ることである程度わかるかと思いますので、使用頻度の高いコマンドやオプションだけに絞って書いていきます。ただし、プラグインの詳細については書いていかないため、共通した部分のみなので実際の実行の際には各プラグインを見て貰う必要があります。

embulkコマンド

前回、embulkコマンドを利用してバッチ処理実行を行いましたが、そのときには bundlerun コマンドのみを用いました。 実際にはこれ以外にもいくつかコマンドが存在しています。それでは embulk --help で確認してみましょう。

$ docker run -it --rm embulk_examples sh -c '/embulk/embulk --help'

Embulk v0.9.12
Usage: embulk [-vm-options] <command> [--options]
Commands:
   mkbundle   <directory>                             # create a new plugin bundle environment.
   bundle     [directory]                             # update a plugin bundle environment.
   run        <config.yml>                            # run a bulk load transaction.
   cleanup    <config.yml>                            # cleanup resume state.
   preview    <config.yml>                            # dry-run the bulk load without output and show preview.
   guess      <partial-config.yml> -o <output.yml>    # guess missing parameters to create a complete configuration file.
   gem        <install | list | help>                 # install a plugin or show installed plugins.
   new        <category> <name>                       # generates new plugin template
   migrate    <path>                                  # modify plugin code to use the latest Embulk plugin API
   example    [path]                                  # creates an example config file and csv file to try embulk.
   selfupdate [version]                               # upgrades embulk to the latest released version or to the specified version.

VM options:
   -E...                            Run an external script to configure environment variables in JVM
                                    (Operations not just setting envs are not recommended nor guaranteed.
                                     Expect side effects by running your external script at your own risk.)
   -J-O                             Disable JVM optimizations to speed up startup time (enabled by default if command is 'run')
   -J+O                             Enable JVM optimizations to speed up throughput
   -J...                            Set JVM options (use -J-help to see available options)
   -R...                            Set JRuby options (use -R--help to see available options)

Use `<command> --help` to see description of the commands.

この中でもよく使うコマンドは bundle , run のほか、 preview , selfupdateguess が多いかと思います。自分は guess が使えないプラグインを利用していたりしたのであまり利用したことがありませんが、対応している場合は設定を作成してくれるため便利です。

ここでは run , preview , bundle のみ書いておきます。

run コマンド: バッチ処理を実行する

run コマンドはバッチ処理実行のためのコマンドです。実際に実行する際には run を用います。

それでは run コマンドの詳細を見ていきましょう。

$ docker run -it --rm embulk_examples sh -c '/embulk/embulk run --help'

Embulk v0.9.12
Usage: embulk run <config.yml>
  Help:
    -h, --help                       Print help.

  Options:
    -r, --resume-state PATH          Path to a file to write or read resume state
    -o, --output PATH                (deprecated)
    -c, --config-diff PATH           Path to a file to read & write the next configuration diff

  Plugin load options:
    -L, --load PATH                  Add a local plugin path
    -I, --load-path PATH             Add ruby script directory path ($LOAD_PATH)
    -C, --classpath PATH             Add java classpath separated by : (CLASSPATH)
    -b, --bundle BUNDLE_DIR          Path to a Gemfile directory (create one using "embulk mkbundle" command)

  Other options:
        --log PATH                   Output log messages to a file (default: -)
    -l, --log-level LEVEL            Log level (error, warn, info, debug or trace)
    -X KEY=VALUE                     Add a performance system config

この中では主に -r , -c , -L あたりを利用することが多いのではないかと思います。 --log , -l なども利用しますが、見た通りの機能なので割愛します。

-r: レジューム用ファイルを出力する

-r を使うことで、途中で失敗した場合に resume コマンドを利用して途中から実行するためのファイルを生成、また前回失敗時のしてくれるようになります。これにより自前で再ロード処理を書くなどせずに再実行することができます。

もちろん、対応できる場面と二重にロードされてしまうなどの問題で対応できない場面があるため、常に使えるわけではありません。プラグインの挙動などを確認した上で利用するようにしましょう。

-c: 次回実行用の差分ファイルの生成をする

-c を使うことで、次回実行時にどこから実行するかを記録したファイルを生成してくれます。これは特に liquid と呼ばれるテンプレート形式の設定ファイルを利用する際に役に立ちます。 liquid テンプレートについては別途書いていきます。

レジューム実行との違いは失敗した分を再実行するのではなく、前回分からの増分のみを実行するためのものです。特に定期実行している場合に前回実行から増えたファイル分だけを対象にするなどに向いています。

-L: プラグインのパスを追加する

-L によりローカルのプラグインのパスを追加することができます。

特に自分で作成したプラグインや、既存のプラグインに手を入れた場合の検証などをすることができます。

preview コマンド: 実行結果を確認する

次に preview コマンドですが、実際の出力をせずに出力結果となる一部データのみを標準出力に出してくれます。出力が想定通りかを確認するのに便利ですが、最終的なチェックは run コマンドを利用してテスト実行してみるのがいいでしょう。

使えるオプションは表示用のオプションを除き run コマンドから少し削ったものとなっているので割愛します。

前回のサンプルで実行してみると以下のようになります。

$ docker run -it --rm embulk_examples sh -c '/embulk/embulk preview config/example_1.yaml'
Embulk v0.9.12
[WARN] (main): DEPRECATION: JRuby org.jruby.embed.ScriptingContainer is directly injected.
[INFO] (main): Gem's home and path are set by default: "/root/.embulk/lib/gems"
[INFO] (main): Started Embulk v0.9.12
[INFO] (0001:preview): Loaded plugin embulk-input-randomj (0.5.1)
+---------+--------------+
| id:long | value:string |
+---------+--------------+
|       1 |   ALVkQXyqgZ |
|       2 |   4DHlyvzutT |
|       3 |   pTBGjcnBCs |
|       4 |   MLmywueWRb |
|       5 |   LPXWIftwmb |
|       6 |   zJJoKDHHI7 |
|       7 |   nEgsdUrrzv |
|       8 |   T8YL3U2isH |
|       9 |   Lp76bIh0A1 |
|      10 |   DcitTnygtF |
+---------+--------------+

bundle コマンド: Gemfileからプラグインパッケージをインストールする

bundle コマンドは、Gemfile に書かれたプラグインパッケージをインストールすることができます。基本的には Bundler と同じなのですが、オプションをつけずにパッケージのインストールとして使うことが多いと思います。

設定ファイル

バッチ処理の手順を記載する設定ファイルはYAMLで記載します。その設定ファイルには主に以下の3つを記載します。

  • in: インプットの設定
  • out: アウトプットの設定
  • filters: フィルターの設定

それではまたサンプルのリポジトリから設定を見ていきましょう。もし前回を読んでいなければ、そちらも参考にしてください。

GitHub - naokirin/embulk_examples

今回は example_2 をチェックアウトして、 config/example_2.yaml をみてみましょう。

$ git checkout example_2
$ cat config/example_2.yaml
in:
  type: randomj
  rows: 10
  threads: 1
  primary_key: id
  schema:
    - {name: id, type: long}
    - {name: value, type: string, length: 10}
filters:
  - type: column
    columns:
      - {name: id, type: long}
      - {name: user_name, src: value}
out:
  type: command
  command: "cat - > '/workdir/output.txt'"
  formatter:
    type: fast_jsonl

まずは各項目で type という項目が共通していることがわかると思います。これはプラグインの名称になります。実際のパッケージ名は embulk-input-xxxembulk-output-xxx , embulk-filter-xxx などになっており、 in の下の type に書いた場合は embulk-input-xxxプラグインが利用されることになります。

さて in , out については其の1と同じですが、 filters が追加されています。

filters では設定された上から順に処理されます。今回はcolumnプラグインによるフィルターのみを設定しています。columnフィルタープラグインは、キーの名前の変更や、固定されたデータの追加、データの削除などに使うことができます。

それではこれによってどのような出力に変わるか見てみましょう。

$ docker build -t embulk_examples .
$ docker run -it --rm embulk_examples sh -c '/embulk/embulk preview config/example_2.yaml' 

--- 省略 ---

+---------+------------------+
| id:long | user_name:string |
+---------+------------------+
|       1 |       xn544iT0a9 |
|       2 |       8LxHXHxlOz |
|       3 |       hDZhNDcGeK |
|       4 |       F7MLGwa2AA |
|       5 |       EdcXJZ84Zq |
|       6 |       VnrTPNrHaw |
|       7 |       pjtLNnfQGB |
|       8 |       LrcnVFAARz |
|       9 |       yrEIpvfA36 |
|      10 |       Ctj1AEOZGa |
+---------+------------------+

このように fliters の項目によってフィルター処理をでき、より柔軟なインプットからアウトプットへの変換やバリデーション処理を挟むことができるようになります。