夢とガラクタの集積場

落ちこぼれ三流エンジニアである管理人の夢想=『夢』と、潰えた夢=『ガラクタ』の集積場です。

並列バッチデータ転送OSSのEmbulkをソースコードリーディングしてみる(その1

こんにちは。

ようやくKinesisSpoutが一段楽したので次のネタを。

先日「データ転送ミドルウェア勉強会」が開催され、
そこでバルクデータロードツール『Embulk』が公開されました。

データのバルクロードというと、定番のOSSというのがなくて、
HDFSにバルクデータをロードする時はhadoopコマンドで行う・・などを行っていたのですが、
それがツールでできるというのは非常にありがたいですね。

で、既に使ってみた方の事例はいくつか挙がっていますので、実際にどう作られているかを見てみようと思います。
・・・ええ、Javaプラグインが書けるようになるまで実際に動かすかソース読むしか出来ないからですね。

1.embulkのモジュール構成

embulkのGitHubを確認してみますと、下記3つのモジュールで構成されています。

  1. embulk-cli
  2. embulk-core
  3. embulk-standards

各モジュールが何か、を見てみるとどうやら下記のような感じのようです。

embulk-cli

embulkをjavaコマンドで起動した際に呼ばれるMainクラスのみを保持するモジュール。
起動引数の前に「classpath:embulk/command/embulk.rb」を追加し、JRubyを呼び出しているのみです。
・・ソースがJavaと期待して読み始めるとしょっぱなからRuby突入している!?

embulk-core

embulkのコアモジュールでモジュールをロードする機能や実行する機能を保持。

embulk-standards

下記のような基本機能と、ロード処理を行うモジュール。

  1. CSVファイルフォーマッタ、パーサ、トークナイザー
  2. GZipファイルのエンコーダ/デコーダ
  3. ローカルファイル出力/入力
  4. NullOutput
  5. S3への出力
  6. 標準出力

2.起動の流れ

軌道制御部分がJRubyで書かれていることがわかったため、KinesisSpoutのようにJavaコードから追っていくやり方は多分出来ない・・・
ということで、JRubyの起動処理部分を追ってみます。
Rubyについては構文を知っている位のレベルなのでボケかましていたら生温かく突っ込んで頂けると幸いです。
尚、Rubyのコードはlibディレクトリ配下に配置されていました。

起動する際にはJRuby経由で「embulk/command/embulk.rb」が呼び出され、そこから起動します。

embulk.rb
  1. 環境変数「EMBULK_BUNDLE_PATH」または起動引数を基にGemのインストールパスを取得する。
  2. Gemのインストールパスを指定してEmbulk#run(embulk_run.rb)を呼び出す。
    • 指定されていない場合はembulk_runで設定される。
embulk_run.rb
  1. 起動引数から「-」が付与されない引数のうちはじめの引数を取得し、「サブコマンド」とする。
    • 「サブコマンド」が存在しない場合はその時点でusageエラー
  2. 「サブコマンド」が下記のいずれかの場合は指定引数に応じて後のusageメッセージに内容を追加。
    • bundle/run/preview/guess/example(usageメッセージの追加はなし)
  3. 「サブコマンド」が上記のいずれでもなく、下記のいずれかの場合は処理を起動
    • gem(Rubyのgemコマンドを起動)、exec(引数を用いてそのままプロセス起動)
  4. その他のオプションの形式チェックを実施、NGであればusageエラー
  5. 「サブコマンド」に応じて下記のように処理を分岐
    • bundle
      • bundleディレクトリをコピー後、bundlerをインストール後、Bundler::CLI開始(詳細はわからず)
    • example
      • 指定パスに対してexampleを出力する
    • 上記以外
      1. org.embulk.command.Runnerのコンストラクタに引数をJSONに変換して実行
      2. 「サブコマンド」「設定ファイルパス」を引数として指定してmainメソッドを実行

・・というわけで、CLIからJRubyを起動してGemやClasspathの解決を行い、
org.embulk.command.Runnerから再度Javaコードに戻ってツール本体が本格的に起動する・・
という流れのようです。

早い段階でJavaに戻ってきてちょっと安心。

とりあえず、次回はJavaコードの構造を確認した上でJava側の流れを追ってみます。