バッチ処理の実装方法

僕はHive, Pythonバッチ処理を書いてAzkabanでジョブ管理するシステムを構築、運用してかれこれ2年経つのでその経験をもとにバッチ処理の実装方法を書いてみようかと思う。

バッチ処理、ジョブ管理について書いてみる - wyukawa’s blogでは主にジョブ管理について書いたので今回はバッチそのもののに焦点をあてる。

ジョブ管理のときはつらつら書いて読みにくかったように思うので今回は箇条書きする。


バッチ処理は以下のように実装すると良いと思ってる。なおここではHadoopのようなIOメインな処理を前提としている。


LL言語で実装する
コンパイルがいらないからね。もしJavaで実装したらコンパイル、パッケージングしてデプロイしないといけない。バッチなんてどうせデータ処理がメインだからローカルでは実装しづらいことが多いし、どうせサーバー上で直接作業するでしょ。障害時は特にね。


・書き方を統一する
フレームワークを使うなどして書き方を統一する。


・引数に日付を持つ
例えば常に前日日付を見るようにハードコーディングしてたら過去分の再集計とかできないよね。コードをそのたびに変更しないといけない。マシンの日付を変えたりしないよね。なお上記でLL言語で書いた方がいい理由はそのようなケースでも対応しやすいということもある。


・一時ファイル、一時テーブル名はユニークにする
tempみたいな名前で一時テーブルを作ると複数日付同時に実行できないので最低限日付をつける。同日付で同時実行するケースがあるなら時間やプロセスIDを使う。


・ありがちなエラーに対してはわかりやすいエラーメッセージをもつ例外をなげる
例えばPythonで「TypeError: 'NoneType' object is not iterable」のようなエラーが出たらそれはプログラムのバグだと思う。
が、しかし、例えば不安定な外部システムにアクセスした結果データが無いから結果的にこのようなエラーが出たというケースを考えてみよう。そのような場合は「xxx API result is not found」のようなエラーを返せばプログラムにバグは無いけど外部システムが問題だったんだなということが一目瞭然である。
それ以外にもinfoログ的なものをprintしておくのもよい。僕の環境では例外はhipchatに通知しているからinfoログは見れないが、Azkabanからinfoログを見る事が出来る。