脱cron! SOS JobschedulerでRailsのジョブ管理をしてみる


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)です。

SOSJOB01.png

この売買履歴情報から、日ごとの仕入額計算、売上計算を行うのが、仕入計算バッチ(ジョブ名: BatchCalcPurchases)と売上計算バッチ(ジョブ名: BatchCalcSales)です。これらバッチで計算されたデータは以下のような感じ。

SOSJOB02.png

最後に行うのが利益計算バッチ(ジョブ名: BatchCalcBenefit)。今月はどの商品がどれだけ利益だしたか?を出力します。

SOSJOB03.png

今月はカシミアのコート30個仕入れたけど、全然さばけてないなー、赤字だな。とか言った事を把握できる、便利システムです。

で、以下の図のようにジョブを毎日夜間に動かしたい。

BatchJobnet.png

まずは商品売買履歴取込バッチを動かしてデータ取得。その後仕入計算と売上計算バッチを動かす。ただし、これらの処理は重いので同時に別サーバで並行実行したい!(そうしないと夜間の間に計算できない)

最後に利益計算バッチを動かす。ただし仕入計算と売上計算バッチが両方終わったら実行したい!(じゃないと利益計算おかしくなるもんね)

こういうシステムが作りたいわけです。頑張れば自前実装できそうですが、辛いですよね。。。特に構成変わったときとか。こういう時こそジョブ管理システムの出番です。

SOS Jobschedulerとは?

SOS Jobschedulerはオープンソースのジョブ管理システムです。JP1のオープンソース版といえば分かる人には分かるかと。SOS Jobscheduler自体はJavaで作られているため、WindowsでもLinuxでも動作します。

SOS JobschedulerはJobScheduler Engine, JobScheduler Agent, JOC, JOE といった複数のソフトウェアから成り立っています。同じような名前でどれがどれだかよくわからなくなりますが、以下のようなものです。

  • Jobscheduler Engine
    • Jobschedulerのメインとなるエンジン。こいつがジョブの実行命令をAgentに対して出したりする
  • JobScheduler Agent
    • ジョブを実際に実行するマシンに入れるAgent。Jobscheduler Engineから受け取った命令に従って、ジョブを実行する
  • JOC (Job Operation Center)
    • ジョブの実行履歴をWEB上で確認するためのもの。またジョブの実行をここから行うこともできる
  • JOE (JobScheduler Object Editor)
    • ジョブを定義するときに使うGUIアプリ。別にこいつを使わなくてもジョブを定義できるが、使うと楽かも。

Jobschedulerの構成は以下のような感じになるかと。

JobSchedule_kousei.png

JOCはWeb上でジョブの実行や実行履歴の確認ができますが、ジョブの定義はWeb上では行えません。JOCの見た目は以下のような感じ。

SOSJOB04.png

ジョブを実際に作成するのは、JOEというエディタです。これは自分のマシンに入れてJobを定義します。単なるXMLなので別にJOEを使って定義する必要はありませんが、GUIでグラフィカルにジョブ定義できた方がいいですよね。

そして定義したジョブXMLをJobscheduler Engineが動いているサーバに送れば、ジョブ登録完了です。

JOEをMacOSXで動かすのは苦労しました。というのもJava64bit版に対応していないため、起動時に色々オプションを指定したり、SWT(javaのGUIライブラリ)の64bit版をネットから落としてきて、ライブラリ置き換える、なんていう事をしないといけません。なんと面倒な。。。

JOEの見た目は以下のような感じ。

SOSJOB05.png

ジョブはShellScriptやperl, JavascriptやJavaといった言語で実装可能です。

SOSJobschedulerのインストール方法は割愛します。詳しくはSOS Jobscheduler公式サイトを参照してください。でも結構苦労します。何度挫折しかかったか。

JobとJobchainについて

私がやりたいようなジョブネットを実現するためには、JOEを使ってJobとJobchainを定義します。

  • Jobとは
    • バッチ等を実行するスクリプトをかいたり、どのサーバで動かすかを定義するためのもの
  • Jobchainとは
    • ジョブネットの定義ができます。このジョブ動いたら次はこれ!とか、失敗したときはこのジョブ動かすとか定義できます

ジョブの定義はそんなに複雑じゃないです。単に実行したいスクリプトと、どのサーバで動かすのか(Process Class)の定義をするだけです。

問題はJobchainの方です。私がやりたいのは、途中2つのジョブを並列実行し、両方とも成功したら最後に利益計算バッチを実行する、というものです。この要件を満たすために、なんと二つのJobchainを定義し、かつ並列実行、待機のためのジョブを定義しないといけないのです。これもまた面倒な。。。

Jobchainを定義する

これ結構複雑です。ブログ1記事で書ける量じゃないです。なので詳しくは私が参照したサイト、[CentOS6] ジョブ管理 – SOS JobSchedulerを参照してください。

Jobchainは状態遷移図のようなものです。ジョブがスタートするための状態、実行するジョブ、ジョブ成功時の次の状態、失敗時の状態をワンセットとし、これらを組み合わせてジョブチェーンを構築します。

JobChainBasic.png

こんな感じのものを、JOEで定義していきます。

SOSJOB06.png

で、私がやりたいバッチ処理をジョブチェーンで表現すると以下のような感じになります。

JobChainFormyself.png

え。。。こんなに面倒なの。。。実行したいバッチ以外に2つ、並列実行のためのジョブを作らないといけません。

長くなるので詳細は省きますが、Executorは単にジョブ実行の依頼を行うためのジョブです。で、SyncPurchasesSalesは2つのジョブが完了になるまで待機するためのジョブです。こういう風に定義しないと、私が目指した要件を満たすジョブネットは作れませんでした。これは結構面倒なのでなんとかならないものでしょうか。。。

頑張ってジョブを作った結果

こんな感じでジョブが動いてます。ちょっと画面小さいので、全画面表示にして目を凝らして見てください。(タイミングによって画面全体がぼやけてしまったりしてます。その場合、youtube右下の解像度あげると見えます。youtube難しい。。。)

動画へのリンク: http://www.youtube.com/watch?v=XkxVMVc3WHY

SOS Jobschedulerのこれからに期待すること

SOS Jobschedulerで、とりあえず要件を満たすジョブネットを作成することができました。
ただ、プロダクションで使えるか? という点で考えると、ちょっと厳しいものがあるかも(海外ではプロダクションで採用しているところはあるみたい)。理由は以下の通り。

  • 日本語対応してない。WebUIは最近日本語に対応したようだが、日本語でログ出力すると化けて表示される
  • ジョブ名も日本語じゃだめ。試しに日本語で作ってみたら、Jobschedulerが死んだ! (まあ日本語使うなよ、っていう話ではありますが)

ただこの問題はいずれ解決されるかと。最近日本JobSchedulerユーザグループが発足し、そこの人たちが日本語化してくれているみたい。是非頑張ってほしいです。

あと以下は不満点。

  • JOC WebUIが見にくい。もっとこう、Hinemosジョブマップオプション のような図がでてきて欲しい
  • JOCで、今どのジョブが実行中か? もなんか見づらい
  • Web上でジョブ定義したいしたい!
  • ジョブチェーンが複雑。もっと楽に定義できれば。。。

ただ、SOS Jobschedulerの凄いところは、なんでもAPIで操作、取得できることだと思います。なのでUI周りとかは、頑張れば自前で実装できるんじゃないかと思います。

だれかかっこいいWebUIとか作ってくれたりしませんかね?