弊社では最近、JOB管理をJenkinsからKuroko2へ移行しました。
Kuroko2についての概要や導入方法は、以下の記事などが詳しいため割愛させて頂き、弊社での具体的な導入内容について紹介したいと思います。
- https://github.com/cookpad/kuroko2
- http://dev.classmethod.jp/server-side/kuroko2/
- https://blog.mwed.info/posts/kuroko2-mwed-2016-10.html
導入の背景
元々、数百ほどあるバッチ処理をJenkinsで運用していました。Jenkinsから、各JOBサーバにsshして、JOBを起動するという単純な構成で運用していたため、下記の課題がありました。
- 一つのホスト上で同時に起動されるJOB数を厳密に制御できず、CPU/メモリのリソースを逼迫してしまう
- 夜間だけホスト増やすなど、ピークに応じた実行環境の増減に対応しづらい
Kuroko2は、ジョブ管理システムとして必要な「スケジュール、エラー通知、JOBの依存関係制御」等の機能に加え、Wokerを増やすことで動的にJOB起動数を制御できるため、上記課題を解決可能と考えました。
構成
Kuroko2の基本的なアーキテクチャは、以下の図のようになっています。(GitHubから抜粋)
弊社では、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を強制終了させることができます。
参考) https://github.com/cookpad/kuroko2/issues/23
HOST追加時にWokerが認識されない
Kuroko2では、Host名+Queue名をキーとしてWokerを管理しているため、HOSTを追加した場合に、既に同名のQueueがある場合は、Host名を変更する必要がありました。
拡張機能
いくつかChromeの拡張機能を作っていますので、少し紹介します。
デフォルト入力
新しくJOBを作製する際、デフォルトで入力する項目はある程度決まっています。デフォルトボタン(下記の図のオレンジボタン)を用意して、デフォルト値を設定するようにしています。
スケジュール削除ミス防止
スケジュールのDeleteボタンを押すと、確認なく削除されるため、間違えて押下した際に、以前のスケジュールがわからなくなって困るケースがありました。ミス防止のため、拡張機能でダイアログを出すようにしています。
まとめ
JenkinsからKuroko2への移行することで、JOBサーバを柔軟に増減することが可能となりました。今後は、ECSやスポットフリートを利用して、よりJOBの効率化・コスト削減を実施していきたいと思います。
LCLではエンジニア・インターンを積極的に募集中です。興味のある方は採用ホームページからお気軽に、ご連絡よろしくお願いいたします。