今日もプログラミング

IT技術とかプログラミングのこととか特にJavaを中心に書いていきます

embulk-output-oracleのパフォーマンスを向上する!

背景

ここでも書いたが、embulk-output-oracleを業務システムで使うには、もう少し速くしたい。

そこで、embulk-output-oracleのパフォーマンスを向上することにした!

 

embulk-output-oracleの現状のパフォーマンス

まずは、現状(embulk 0.8.12 + embulk-output-oracle 0.6.1 + embulk-input-filesplit 0.1.3)のパフォーマンスを確認しておく。

AWS上で以下の2つの環境で確認した。なお、OSはWindows 2012 Serverである。

No.OracleClient入力データ
1 c3.xlarge (4 vCPU, Magnetic disk) c3.xlarge (4 vCPU, Magnetic disk) 50,000,000レコード (10GB)
2 c3.2xlarge (8 vCPU, SSD) c3.2xlarge (8 vCPU, SSD) 200,000,000レコード (40GB)

 

計測結果は、以下の通り。

なお、比較のため、名前は言えないが高速な某ツールでも計測している。

ちなみに、環境は異なるが、以前は某ツールより2割ほど遅かった。

[環境1]

ツール時間
某ツール 11.1m
embulk-output-oracle + embulk-input-filesplit 11.2m

[環境2]

ツール 
某ツール 10.6m
embulk-output-oracle + embulk-input-filesplit 22.0m

 

現状のパフォーマンスに関する考察

環境2の方が4倍も入力が多いのに、時間があまり変わらないのは、SSDのおかげだ。

実際、環境1でも2でも、ディスクI/Oがかなり高負荷になっていた。

 

環境1では、embulkは某ツールと同じくらいだが、環境2では倍も時間が掛かっている。

つまり、環境1ではディスクが遅いためOracle側がボトルネックになっているが、環境2ではembulk側がボトルネックになっている。

改善せねば!

 

embulk-output-oracleのパフォーマンス改善

いろいろと計測したり分析したり試行錯誤した結果、修正したのは以下の2点。

なお、プルリクエストまでは作成したが、まだマージはされていない。

ネイティブライブラリ呼び出し回数を減らす

embulk-output-oracleは、Oracleのネイティブライブラリを利用することにより高速化している。

しかし、Java→ネイティブライブラリの呼び出し回数が非常に多いため、オーバーヘッドが大きくなっていた。

そこで、embulk-output-oracleOracleライブラリの間に挟むネイティブライブラリを開発し、呼び出し回数を減らした。

詳細はこちら

 

ロード処理回数を減らす

embulk-output-oracleの中の挙動をよく調べてみると、Oracleライブラリによるロード処理は約200レコード毎に行われていた。

これだとロード回数が非常に多いため、オーバーヘッドが大きくなっていたようである。

そこで、Oracleのネイティブライブラリのバッファサイズを大きくしたりして、ロード間隔をうまいこと調整するようにした(いろいろな条件によって変わるが、環境2の場合は4,000レコード毎くらい)。

 

embulk-output-oracleのパフォーマンス改善結果

改善版を使って、パフォーマンスを計測してみた。

タスク数(並列数)を変えたり、embulk-input-filesplit無しでも測ってみた。

[環境1]

ツール時間
某ツール 11.1m
embulk-output-oracle + embulk-input-filesplit 4タスク 11.3m
2タスク 11.3m
1タスク 12.2m
embulk-output-oracleのみ 11.5m

[環境2]

ツール時間
某ツール 10.6m
embulk-output-oracle + embulk-input-filesplit 8タスク 10.1m
4タスク 10.9m
2タスク 20.1m
1タスク 36.7m
embulk-output-oracleのみ 25.6m

 

環境1の方は、Oracle側が非力なので、どれで測っても大差ない。

さすがに1タスクだとちょっと遅くなるが。

 

環境2の方は、パフォーマンス改善の効果が顕著に出ている!

4タスク以上であれば某ツールと互角だ。

embulk-input-filesplit無しの場合、出力タスクは並列化されるが、入力タスクが並列化されないため、パフォーマンスが落ちるのだろう。

 

まとめ

もちろん、環境やテーブル設計にもよるので一概には言えないが、embulk-output-oracleが某ツールと互角のパフォーマンスを出せたのは非常に嬉しい結果である。

他の環境(より高性能な環境とか、高いが…)でも計測してみたい。

と言うか、早く実システムでも使ってみたい!