■ メモリ不足
前回(
COBOLからJavaに書き換えたらCOBOLの偉大さを感じた今日この頃(前編))、
COBOLからJavaにプログラムを書き換えて、テストまで完了しました。
これで一安心と思ったのですが、念のために実際の運用で発生するだろうデータ量を用意して実行してみたのですが、ここから長い戦いが始まりました。
DWHの更新処理は日々実行されていて、基本的には前日の処理実行日時の後に登録、更新されたデータを対象にします。
そのため、月次処理などで一括フラグ更新などが走った後には大量のデータが対象になりえます。具体的には、20〜30万件程度です。
そして、Java側の処理は、こんな感じ。
① 基幹DBから対象データ抽出
② ①の抽出結果をメモリに蓄積
③ メモリに蓄積した1行を読込
④ ③でDWHの対象テーブルをPK検索
⑤ ④の抽出結果の有無で、UPDATE か INSERT
・・・結果、②のメモリに蓄積する処理で、10万件くらい蓄積した辺りで
OutOfMemoryErrorが発生しました。
うん、そんな気はしてたんですよね。
■ 性能劣化
OS側の物理メモリに余裕はあるので、Javaに割り当てるメモリ量を増やすという手もあったのですが、キリがないのでメモリ量を少なくするようにプログラムを書き換えました。
① 基幹DBから対象データ抽出
② ①の抽出結果をメモリに蓄積③ メモリに蓄積した1行を読込② 抽出結果から1行読込③ ②でDWHの対象テーブルをPK検索
④ ③の抽出結果の有無で、UPDATE か INSERT
メモリに蓄積する処理を省く改修です。これでメモリ使用量は激減します。
この修正でメモリ不足は発生しなくなったのですが、いま一つ性能が良くありません。1万件の処理を行うのに、5分くらい時間が掛かります。30万件処理するとなると、250分です。
遅延箇所を調べると、③④の
Oracleの辺りの処理が地味に遅いです。1件の処理時間は0.07秒とかなのですが、件数があると累積時間が結構なものになりました。
同じ処理を
COBOLでやった場合、15分程度で終わるので、ここは無理に書き換えなくても良いと思ったのですが、大誤算ですよ。
■ 後書き
しっかし、COBOLから
Oracleに接続する仕組み(Pro*COBOL)って結構優秀なんですね。COBOL自体がコンパイルが必要な言語っていう特性もあるせいか、この手のバッチ処理はCOBOLに一日の長があるようです。
単純にロジックごとJavaに移植しても、上手く行かないことってあるようです。まぁ、Javaも
Oracleの一連の処理をガリガリ作りこんで最適化すれば、結果は違うのかも知れませんが。
結局どうしたかって言うと、MERGE文を発行することにしました。基本的には項目の移送なので、実はMERGE文一発で終わるのです。
ロジック変えないことに拘るのであれば、PL/
SQLを使うって方法も考えられたのですが、ここまで来ると元のロジックに拘ってもしょうがないですし、ゼロベースで見直すことにしたのです。
結果、数分で終わるようになりました。こんなことなら、最初からMERGE文を使えば良かったですよ。
投稿記事の一覧:
http://harikofu.web.fc2.com/--- blog end ---
スポンサードリンク