LCL Engineers' Blog

夜行バス比較なび(高速バス比較)・格安移動・バスとりっぷを運営する LCLの開発者ブログ

JOB管理をJenkinsからKuroko2へ移行しました

弊社では最近、JOB管理をJenkinsからKuroko2へ移行しました。

Kuroko2についての概要や導入方法は、以下の記事などが詳しいため割愛させて頂き、弊社での具体的な導入内容について紹介したいと思います。

導入の背景

元々、数百ほどあるバッチ処理をJenkinsで運用していました。Jenkinsから、各JOBサーバにsshして、JOBを起動するという単純な構成で運用していたため、下記の課題がありました。

  • 一つのホスト上で同時に起動されるJOB数を厳密に制御できず、CPU/メモリのリソースを逼迫してしまう
  • 夜間だけホスト増やすなど、ピークに応じた実行環境の増減に対応しづらい

Kuroko2は、ジョブ管理システムとして必要な「スケジュール、エラー通知、JOBの依存関係制御」等の機能に加え、Wokerを増やすことで動的にJOB起動数を制御できるため、上記課題を解決可能と考えました。

構成

Kuroko2の基本的なアーキテクチャは、以下の図のようになっています。(GitHubから抜粋)

f:id:lcl-engineer:20171029232828p:plain

弊社では、kuroko2-consoleとkuroko2用のDBは同インスタンス上に構築し、kuroko2-workerは各サービス毎のJOBサーバに導入しています。つまり、一つのconsoleで、複数サービスのJOBを横断して管理しています。

現時点のkuroko2(v0.4.2)では、権限制御機能がないため、メンバー毎に管理可能なJOBを制御したい場合は、kuroko2-consoleを分割する必要があります。

Queueの設計

弊社では、サービス・JOB種類別にQueueを分けています。例えば日中に定期的に稼働するJOBはQueue-A,夜間に集中的に稼働するJOBにはQueue-Bとしています。

あるJOBがCPUやメモリを極端に使用する場合、そのJOBだけでサーバリソースを圧迫してしまうことになるため、同じQueueに所属するJOBは、できるだけ似通った処理特性のOJOBにしています。

エラー通知

Kuroko2では、メールとチャット等(Webhook)に各種通知可能です。弊社では、メールは利用せず専用のチャットルームへ通知し、通知があればそこで都度チャットで確認をしています。若干、オオカミ少年化している通知もあるため、通知の精度向上に取り込んでいます。

タグのルール

Kuroko2では、JOBに複数のタグを設定でき、タグによる絞込ができます。当初は複数のタグを細かく付与していましたが、タグが増えすぎると絞込時に探しづらい状態になりました。結局、以下の2種類付与しておけば問題なく運用できています。

  • Queueの名称
  • JOBの分類

実行ログ

Kuroko2では、JOB内で標準出力したログは、管理コンソール上で確認ができます。ただし、リアルタイムではなくJOBが完了後に初めて確認できます。(ログが多いと途中までしか表示されません)

AWS CloudWatch Logsを利用することで、管理コンソール上でリアルタイムにログが確認できるようになりますが、ログの出力量が多いと、JOBの実行時間が遅くなってしまったため、弊社では採用を見送りました。

バックアップ

管理コンソール上で定義したJOBの情報等は、kuroko2のDBに格納されているため、mysqldumpを利用してバックアップを取得するようにしています。

ログの削除

現時点のKuroko2では、ログは自動的に削除されないため、弊社では定期的にログの削除を実施しています。kuroko2は以下のテーブルで構成されます。

mysql> show tables;
+---------------------------------+
| Tables_in_workerdb              |
+---------------------------------+
| kuroko2_admin_assignments       |
| kuroko2_ar_internal_metadata    |
| kuroko2_executions              |
| kuroko2_job_definition_tags     |
| kuroko2_job_definitions         |
| kuroko2_job_instances           |
| kuroko2_job_schedules           |
| kuroko2_job_suspend_schedules   |
| kuroko2_logs                    |
| kuroko2_memory_consumption_logs |
| kuroko2_memory_expectancies     |
| kuroko2_process_signals         |
| kuroko2_schema_migrations       |
| kuroko2_stars                   |
| kuroko2_tags                    |
| kuroko2_ticks                   |
| kuroko2_tokens                  |
| kuroko2_users                   |
| kuroko2_workers                 |
+---------------------------------+

kuroko2_job_instances,kuroko2_logsが、特にデータが貯まりやすいテーブルです。これらのテーブルの過去N日以前のデータを定期的に削除するようにしています。(オフィシャルな情報ではないので、自己責任で)

監視

Kuroko2が正常に動作しているかは、下記の観点で監視しています。

  • 管理コンソールURLを外形監視
  • Workflow,Schedulerのプロセス監視

また、JOBが滞りなく実行されているかは、以下のAPIを利用してWaiting JOB数を監視しています。

/v1/stats/waiting_execution

Waitingが増えた場合には、JOBスケジュールの見直しやWokeの追加(HOSTの追加)を検討します。

その他

最後に少しハマったところや、TIPS的なものを紹介します。

PostgreSQLでの稼働

Kuroko2の動作環境として、System requirementsには「MySQL >= 5.6」と記載がありますが、PostgreSQLの方が運用に慣れているため、最初はPostgreSQLで構築しておりました。ある程度は正しく動いていたのですが、細かいところでSQLエラーが発生していたため、結局はMySQLでの運用に切り替えました。

強制キャンセル

Workerの強制終了等の理由により、Kuroko2上でJOBが完了しないまま残りつづける場合がありました。

その場合は、「Job Instance Details」画面で、Backslashを押下することで、Force Cancelボタンが有効になり、Force CancelでJOBを強制終了させることができます。

f:id:lcl-engineer:20171029233213p:plain

参考) https://github.com/cookpad/kuroko2/issues/23

HOST追加時にWokerが認識されない

Kuroko2では、Host名+Queue名をキーとしてWokerを管理しているため、HOSTを追加した場合に、既に同名のQueueがある場合は、Host名を変更する必要がありました。

拡張機能

いくつかChromeの拡張機能を作っていますので、少し紹介します。

デフォルト入力

新しくJOBを作製する際、デフォルトで入力する項目はある程度決まっています。デフォルトボタン(下記の図のオレンジボタン)を用意して、デフォルト値を設定するようにしています。

f:id:lcl-engineer:20171029233228p:plain

スケジュール削除ミス防止

スケジュールのDeleteボタンを押すと、確認なく削除されるため、間違えて押下した際に、以前のスケジュールがわからなくなって困るケースがありました。ミス防止のため、拡張機能でダイアログを出すようにしています。

f:id:lcl-engineer:20171029233236p:plain

まとめ

JenkinsからKuroko2への移行することで、JOBサーバを柔軟に増減することが可能となりました。今後は、ECSやスポットフリートを利用して、よりJOBの効率化・コスト削減を実施していきたいと思います。

LCLではエンジニア・インターンを積極的に募集中です。興味のある方は採用ホームページからお気軽に、ご連絡よろしくお願いいたします。