Job管理をAirflowからKuroko2に乗り換えたら幸せになった

Speeeアドベントカレンダー 2日目の記事です。

前日の記事は@hiragramTravisCIでiOSの依存ライブラリの更新を自動化する - TECHNICA Speee engineer blog

エンジニアの@hatappiです。 前年度のアドベントカレンダーでこんな記事書いてました。 hatappi.hatenablog.com

要するに定期処理をうまいこと実現したい!そのためにAirflowを使ってはどうかっていう記事です
※ Airflowはデータパイプラインのスケジュールとかモニタリングできるツールです。簡単にいうとジョブ管理ができるシステム

Airflowを使うと

  • 定期実行したい
  • 成功、失敗において通知したい
  • 画面上から再実行したい
  • logを画面からおいたい

といった定期処理でやりたいことを実現できるので、あれから実際に会社でも導入して
現在稼働しておりディレクターの方が画面上から再実行しており エンジニアが再取得の対応をしなくてもよくなりました 🎉

ただ タスクをPythonでかかないといけない
これがちょっと辛い
※これはPythonが悪いわけではなく単にRubyを書いていてPythonに慣れてないだけなんですが

会社ではRubyを使うので、どうしてもでないかぎりRubyで扱えると嬉しい
Rubyで扱えると

  • プロジェクトに他の人が入っても、このジョブは何をやっているか把握しやすい
  • ドキュメントにのってなくても最悪ソースを追うことができる
  • 何か不具合があったらコミットできる

1年前に記事を書いた時はRuby製の良いものがなく クックパッドのジョブ管理システム kuroko2 の紹介 - クックパッド開発者ブログ この記事をみて良いなと思いつつAirflowを導入したのが良い思い出。 そんな中今年Kuroko2がOSS化しました!
めでたい 🎉

github.com

使ってみたのですが まず感想から言うと ジョブ管理でしたいことがシンプルに始められるのでよさげ

ジョブ管理では

  • 通知機能
  • GUIでのリトライ処理
  • logの閲覧
  • ジョブの実行環境の分散

があると良いのですがAirflowも網羅してましたがKuroko2も網羅してます
これ以外にもタスクの実行時間やメモリ使用量をグラフで見れたり
GoogleOAuth認証 も標準でついてます

通知機能

Airflowの時は自分で通知タスクを作りジョブのcallbackに通知タスクを設定するコードでかいてましたが、
Kuroko2ではSlackやHipChatや他のwebhookを設定するだけでタスクの実行にあわせて通知してくれます。

f:id:hatappi1225:20161201192515p:plain

またエラーの時はメンションつけたりメッセージを追加したい時もFailure notification textに追加するだけで通知される
このちょっと痒いところに手が届く感じが良い

f:id:hatappi1225:20161201192717p:plain

GUIでのリトライ処理

GUIで単に再実行できるだけでなく、定期実行の場合次の日にタスクが走った時に
実行するか、エラーが解消されるまでキャンセルするかなども画面上から設定できる
Airflowの時はコードでそれを記載しないといけなかった...

f:id:hatappi1225:20161201192755p:plain

logの閲覧

標準出力やエラーなどを各ジョブごとにブラウザから確認が出来るので
エラーがおきた際もなぜ起きたかなどをサーバーに確認せずともGUIから確認できる 設定すればCloudWatch Logsに流すなんてことも出来る

ジョブの実行環境の分散

アプリケーションが大きくなるにつれて色んなバッチができて、動いているバッチがメモリ食いつぶして 他のジョブに影響が出たりしたことはないだろうか Kuroko2では実行する環境を別サーバーにわけることが出来るのでこれも回避できる

workerをそれぞれのインスタンスで起動させる際に環境変数QUEUE に任意の値を設定し jobの定義でコマンド実行前に QUEUE に設定した名前を指定するだけ

QUEUE=hoge でworkerを立ち上げた時はjobの定義にて

queue: hoge
execute: bundle exec rails hoge:fuga

この他のKuroko2のアーキテクチャなどの紹介は クックパッドのジョブ管理システム kuroko2 の紹介 - クックパッド開発者ブログ が詳しいです

実用編

ローカルで試す分にはKuroko2にProcfileが用意されているので foremanコマンドを実行すれば良いので時間はかからないと思う
ただ実運用となるとデプロイしたりworkerやschedulerを再起動させたりしたい
Kuroko2のWebは通常のrailsプロジェクト作成時にKuroko2のアプリケーションテンプレートを流しただけなのでCapistrano使うなりすれば実現できる

executor, processor, schedulerの各プロセスをどう再起動するかに関しては
Kurko2にSystemdのサービスのサンプル用意されてる kuroko2/docs/systemd at master · cookpad/kuroko2 · GitHub が使える

ただ起動はされるが、僕のDebian jessie環境では再起動すると停止されずに次のプロセスが立ち上がってしまい最初それに気づかないままworkerがメモリを食いつぶす事件があったのでpidの場所を定義するようにしてあげた
stopするときはQUITシグナルを送っているので今やっている処理を終えるととまってくれる

gist.github.com

ここまで定義すれば後はCapistranoならdeploy後にhookするなどして再起動してあげれば終わり

最後に

定期実行の話をするとcronからJenkins, Rundeckとか今色々選択肢がある
今回紹介した部分は他のシステムでも実現可能だがRubyを普段から使っており慣れているならジョブ管理としてKuroko2はオススメです
メンテナンスや拡張して独自タスクをかくときもRubyでかけるしなにより手の込んだセットアップやプラグインの追加の必要なくシンプルにジョブ管理をはじめられるのが最高です
今後も使っていこうと思います!