Embulkを業務システムで使った話
背景
自分はSIerのエンジニアである。
いろいろなお客様の、いろいろな業務システムと格闘するのがお仕事である。
また、今はembulk-input-jdbcとかembulk-output-jdbcのコミッタもやっている。
業務システムとRDBとテキストファイル
業務システムでは、たいていRDBを使っている。
そして、サーバ間でデータを連携するために、RDBからテキストファイルにエクスポートしたり、テキストファイルをRDBにインポートしたりすることが結構ある。
そんなときどうするかと言うと、RDB付属のツールを使うことが多い。
例えば、OracleへのインポートであればSQL*Loader、MySQLへのインポートであればmysqlimport、というように。
RDB付属のツールの問題点
いろいろなお客様がいて、いろいろなシステムがあるので、RDBもいろいろである。
ちなみに、うちの会社では、Oracle、SQL Server、MySQLが多い。
なので、RDB毎にいろいろなエクスポート/インポートツールを使い分けなくてはならず、これが結構大変。
ツールごとに仕様が違うし、制約も異なる。
特定の文字コードにしか対応していなかったり、特定の区切り文字にしか対応していなかったり、特殊文字のエスケープが不十分だったり、1行の文字数に制限があったり、…。
調べるのが大変、というだけならまだいいが、結局付属ツールでは対応できず、自作の変換ツールで一旦変換して…、みたいなこともある。
Embulkに注目した理由
プラグイン機構により、様々な入出力に対応している。
もちろんCSVやTSVなどのファイルの入出力もできるし、RDBからの入力、RDBへの出力もできる。
Embulkの良いところは、RDBの種類によらず基本的に使い方が同じことだ。
これにより、RDB毎に仕様が異なる煩わしさから解放される(ただしEmbulkプラグイン自体の開発者を除く)。
そして、一番嬉しいのは、あらゆるファイルフォーマットに対応できることだ。
Embulk標準のCSV Parser/Formatterも柔軟だが、それでだめなら自分で新たなプラグインを書くこともできる。
この柔軟さはRDB付属のツールには無い。
実際に使ったEmbulkプラグイン、使わなかったプラグイン
この業務システムでは、Oracleからタブ区切りファイルへのエクスポート、タブ区切りファイルからOracleへのインポートが必要だった。
そして、エクスポートの方にembulk-input-oracleプラグインを使った。
インポートにはembulk-output-oracleプラグインは使わず、SQL*Loaderを使った。
SQL*Loaderの方が高速だったし、パフォーマンス要件も厳しかったから。
(ただ、embulk-output-oracleも近い将来SQL*Loaderに追いつくと思う)
エクスポートの方は、SQL*PlusでSPOOLを使う方法と比べたが、embulk-input-oracleの方が高速だった。
Embulkを使った際の工夫点
EmbulkはJRubyを使っているのだが、これの初期化に結構時間が掛かる。
と言っても1~2秒だが。
で、エクスポートしたいテーブルは数十個あって、データ量もエクスポートするタイミングもいろいろである。
で、件数の少ない10個のテーブルを同時にエクスポート、というとき、件数の割に数十秒も掛かってしまい、Embulk遅いよ、ということになってしまう。
そこで、Embulkをプロセスと起動するのではなく、EmbulkEmbedを使ってクラスライブラリとして呼び出すことにした。
つまり、1つのEmbulkEmbedインスタンスで10回のエクスポートを行うのである。
これなら、初期化は1回で済む。
また、エクスポートした件数をログに出して欲しい、という要望があり、簡単なフィルタプラグインを作って対応した。
これもEmbulkだからこそ簡単にできる芸当である。
Embulkの稼働状況
開発時に、closeが正しく呼ばれない、というバグがあったが、これは修正済み。
それ以外では、テスト、本番稼働後も、一度も落ちることなく、非常に安定して動作している。
今後Embulk(というかembulk-output-jdbc)に必要なこと
バルクローダに求められるのは、メンテナンス性とか柔軟性もあるが、やはりパフォーマンスが最重要であることが多い。
という訳で、embulk-output-jdbcのパフォーマンスを向上すべく、いろいろと試行錯誤している今日この頃である。