2014年 03月 03日
夜間バッチのジョブ管理、皆様どのようにしておられるでしょうか。
私はというと、cronとWheneverというRubyでcronが管理できるGemで頑張っております。
「cronって。。。このジョブ動いたら次これね! みたいな処理はどうやって書いてるの?」
と知り合いに聞かれたのですが、そりゃShellScriptでコマンド列挙して、それをcronで動かしてたりします。って言ったら、そんなんでジョブ管理できるんだ、みたいな反応されました。
そうですよね。バリバリの業務系システムを作ってる人は皆、JP1やA-Autoといったジョブ管理システムを採用しているわけです。でもRailsでこういったジョブ管理システムを使っているっていう話、聞いた事がありません。(私が知らないだけで、実は皆使ってたりするの?)
非同期なバックグラウンド処理ならばsidekiqのようなGemを使えばよいわけですが、やりたいのは定期的に実行するバッチのジョブ管理です。
JP1はLinux版もあるようなので調べてみたのですが、、、ちょっとお値段高いです。気軽に採用できる感じじゃありません。できればフリーで利用できるものがよいです。
と調べているうちに、「SOS Jobscheduler」と「Hinemos」という、オープンソースのジョブ管理システムを発見しました。Hinemosと比べ、SOS Jobschedulerの方がAPIが充実してそうという印象だったため、今回は「SOS Jobscheduler」を試してみることとします。
とある販売管理システムを作っているとしましょう。システムの概要は以下の通りです。
文字で書くと分かりにくいので、サンプルのデータを使って説明してみます。
データ連携されてくる売買履歴は以下のようなデータです。毎日どの商品をどれだけ仕入れたか、どれだけ販売されたのかというデータが入ってます。この情報を取り込むのが、データ連携バッチ(ジョブ名: BatchDBSync)です。
この売買履歴情報から、日ごとの仕入額計算、売上計算を行うのが、仕入計算バッチ(ジョブ名: BatchCalcPurchases)と売上計算バッチ(ジョブ名: BatchCalcSales)です。これらバッチで計算されたデータは以下のような感じ。
最後に行うのが利益計算バッチ(ジョブ名: BatchCalcBenefit)。今月はどの商品がどれだけ利益だしたか?を出力します。
今月はカシミアのコート30個仕入れたけど、全然さばけてないなー、赤字だな。とか言った事を把握できる、便利システムです。
で、以下の図のようにジョブを毎日夜間に動かしたい。
まずは商品売買履歴取込バッチを動かしてデータ取得。その後仕入計算と売上計算バッチを動かす。ただし、これらの処理は重いので同時に別サーバで並行実行したい!(そうしないと夜間の間に計算できない)
最後に利益計算バッチを動かす。ただし仕入計算と売上計算バッチが両方終わったら実行したい!(じゃないと利益計算おかしくなるもんね)
こういうシステムが作りたいわけです。頑張れば自前実装できそうですが、辛いですよね。。。特に構成変わったときとか。こういう時こそジョブ管理システムの出番です。
SOS Jobschedulerはオープンソースのジョブ管理システムです。JP1のオープンソース版といえば分かる人には分かるかと。SOS Jobscheduler自体はJavaで作られているため、WindowsでもLinuxでも動作します。
SOS JobschedulerはJobScheduler Engine, JobScheduler Agent, JOC, JOE といった複数のソフトウェアから成り立っています。同じような名前でどれがどれだかよくわからなくなりますが、以下のようなものです。
Jobschedulerの構成は以下のような感じになるかと。
JOCはWeb上でジョブの実行や実行履歴の確認ができますが、ジョブの定義はWeb上では行えません。JOCの見た目は以下のような感じ。
ジョブを実際に作成するのは、JOEというエディタです。これは自分のマシンに入れてJobを定義します。単なるXMLなので別にJOEを使って定義する必要はありませんが、GUIでグラフィカルにジョブ定義できた方がいいですよね。
そして定義したジョブXMLをJobscheduler Engineが動いているサーバに送れば、ジョブ登録完了です。
JOEをMacOSXで動かすのは苦労しました。というのもJava64bit版に対応していないため、起動時に色々オプションを指定したり、SWT(javaのGUIライブラリ)の64bit版をネットから落としてきて、ライブラリ置き換える、なんていう事をしないといけません。なんと面倒な。。。
JOEの見た目は以下のような感じ。
ジョブはShellScriptやperl, JavascriptやJavaといった言語で実装可能です。
SOSJobschedulerのインストール方法は割愛します。詳しくはSOS Jobscheduler公式サイトを参照してください。でも結構苦労します。何度挫折しかかったか。
私がやりたいようなジョブネットを実現するためには、JOEを使ってJobとJobchainを定義します。
ジョブの定義はそんなに複雑じゃないです。単に実行したいスクリプトと、どのサーバで動かすのか(Process Class)の定義をするだけです。
問題はJobchainの方です。私がやりたいのは、途中2つのジョブを並列実行し、両方とも成功したら最後に利益計算バッチを実行する、というものです。この要件を満たすために、なんと二つのJobchainを定義し、かつ並列実行、待機のためのジョブを定義しないといけないのです。これもまた面倒な。。。
これ結構複雑です。ブログ1記事で書ける量じゃないです。なので詳しくは私が参照したサイト、[CentOS6] ジョブ管理 – SOS JobSchedulerを参照してください。
Jobchainは状態遷移図のようなものです。ジョブがスタートするための状態、実行するジョブ、ジョブ成功時の次の状態、失敗時の状態をワンセットとし、これらを組み合わせてジョブチェーンを構築します。
こんな感じのものを、JOEで定義していきます。
で、私がやりたいバッチ処理をジョブチェーンで表現すると以下のような感じになります。
え。。。こんなに面倒なの。。。実行したいバッチ以外に2つ、並列実行のためのジョブを作らないといけません。
長くなるので詳細は省きますが、Executorは単にジョブ実行の依頼を行うためのジョブです。で、SyncPurchasesSalesは2つのジョブが完了になるまで待機するためのジョブです。こういう風に定義しないと、私が目指した要件を満たすジョブネットは作れませんでした。これは結構面倒なのでなんとかならないものでしょうか。。。
こんな感じでジョブが動いてます。ちょっと画面小さいので、全画面表示にして目を凝らして見てください。(タイミングによって画面全体がぼやけてしまったりしてます。その場合、youtube右下の解像度あげると見えます。youtube難しい。。。)
動画へのリンク: http://www.youtube.com/watch?v=XkxVMVc3WHY
SOS Jobschedulerで、とりあえず要件を満たすジョブネットを作成することができました。
ただ、プロダクションで使えるか? という点で考えると、ちょっと厳しいものがあるかも(海外ではプロダクションで採用しているところはあるみたい)。理由は以下の通り。
ただこの問題はいずれ解決されるかと。最近日本JobSchedulerユーザグループが発足し、そこの人たちが日本語化してくれているみたい。是非頑張ってほしいです。
あと以下は不満点。
ただ、SOS Jobschedulerの凄いところは、なんでもAPIで操作、取得できることだと思います。なのでUI周りとかは、頑張れば自前で実装できるんじゃないかと思います。
だれかかっこいいWebUIとか作ってくれたりしませんかね?