背景
Nextdoorでは、毎日数千万のダイジェストメールをユーザーに送信したり、成長に関する内部レポートを生成したり、いくつかの運 他の多くのインターネット企業(AirbnbやQuoraなど)と同様に、私たちはCronから始め、Nextdoor Schedulerと呼ばれる独自のcron代替品を構築しました。
私たちは18ヶ月以上Nextdoor Schedulerを使用してきましたが、私たちはそれに非常に満足しています。
では、Cronの問題は何ですか?
Cronには主に4つの問題があります。
まず、Cronの使い方はスケーラブルではありませんでした。 私たちは、すべてのCronジョブをbeefy schedulerマシン(c3.8xlarge)で実行しました。 私たちが牽引力を得るにつれて、Cronジョブは計算リソースの使用量の面でマシンを限界まで押し進めました。
第二に、プレーンテキストのcrontabを編集すると、ジョブの追加、ジョブの削除、ジョブの一時停止など、ジョブの管理にエラーが発生しやすくなります。 たとえば、余分なアスタリスクは、他の日にすべての生産ジョブを実行できませんでした:
1 * * * * * /opt/nextdoor/some_job.sh
第三に、Cronで多くの運用オーバーヘッドを発生させました。 私たちは、異なる頻度(例えば、細かく、毎時、毎週)で、一日に数千回実行されている二百近くの生産ジョブを持っています。 ジョブの失敗は一般的です。 Oncallの人は、失敗したジョブを手動で一日に数回、時には真夜中の後に再起動しなければなりませんでした。 1)失敗したジョブのコマンドラインでページを取得する;2)スケジューラマシンにssh;3)コマンドラインをコピーして&を貼り付けて、失敗したジョブを再実行します。 これは確かにエンジニアリングの幸福のために良いではありません-はい、私たちは従業員の幸福を気にしません!
第四に、実行時に生産ジョブの可視性がほとんどありませんでした。 どのジョブが実行されているか、成功したかどうかを知る簡単な方法はありませんでした。
私たちはcron-replacementを構築することに決めました。 しかし、なぜ我々はオープンソースのソリューションを使用していないのですか? 私たちはちょうど適切なものを見つけることができませんでした。 私たちはpythonを話します。 私たちは、会社の既存のインフラストラクチャコンポーネントを活用したいと考えていました。 私たちは、それを構築し、それを理解し、それを所有したかったです。
スケーラビリティの問題に対処するために、各ジョブをタスクワーカーマシンのクラスタで実行できる非同期タスクにしました。 Taskworkerで実行されるジョブを、失敗したときに自動的に再試行するように簡単に構成できます。 私たちのoncallエンジニアは、この自動再試行機能が大好きです!
Cronを置き換えるために、優れたpythonモジュールApSchedulerを使用してジョブをスケジュールし、プログラムでジョブを管理することができました—REST Api、コマンドラインツール、人間に優しいweb UIを構築しました。
アーキテクチャ
次の図は、スケジューラシステムのアーキテクチャを示しています。

NextdoorスケジューラはPython/Tornadoで実装されています。 これは、3つのコンポーネントで構成され、単一のマシン上の単一のデーモンプロセス(スケジューラプロセス)として実行されます。
- スケジューラ(またはコアスケジューラ)。 これは、cronを置き換え、実行するジョブをスケジュールします。 ジョブが実行されるようにトリガーされると、スケジューラプロセスはジョブのメッセージをAmazon SQSに発行するだけです。 タスクワーカーマシンのクラスターは、Amazon SQSからメッセージを取得し、対応するジョブを実行します。 上記のように、コアスケジューラを実装するためにAPSchedulerを使用します。
- ジョブの追加、ジョブの一時停止/再開、ジョブの削除、ジョブの変更、ジョブの手動開始など、ジョブを管理するためのRESTインターフェイスを提供します。 Scheduler APIの上にコマンドラインツールを構築して、ジョブのグループを一度に一時停止するなど、操作を簡単にしました。
- これは、Scheduler APIと話している単一ページのアプリです。 バックボーンを使用しました。web UIを実装するためのjsとBootstrap。 人間のオペレータは、主にWeb UIを使用してNextdoor Schedulerと対話します。
すべてのジョブとジョブ実行の情報は、データストアに格納されます。 私たちは主にここでNextdoorでPostgresを使用しています。
Web UI
エンジニアは、昔のblackboxのようなCronを扱うのではなく、ジョブを管理する直感的な方法を提供するNextdoor SchedulerのWeb UIを愛しています。
求人ページ

このページでは、私たちが持っているジョブと次回の実行時期を見ることができます。 また、”カスタム実行”をクリックして手動でジョブを開始することもできます。
ジョブの編集

私たちは簡単にジョブを編集することができます,例えば,そのスケジュールを変更し、ワンボタンクリックでそれを一時停止! これは、昔のプレーンテキストのcrontabを変更するよりもはるかに優れています。

最後に、どのジョブが実行されているか、それらが成功するかどうかについての大きな可視性を持っています。
コードを書くのは簡単です。 生産は難しいです。 Nextdoor Schedulerの実装が完了するまでに、新しいシステムに移行する必要がある200近くの生産Cronジョブがありました。
Taskworkerプロジェクトから学んだことを適用して、Nextdoor Schedulerシステムを展開しました。 四つのステップ:
- 私たちは暗闇の中で生産にNextdoorスケジューラを立ち上げました—生産ジョブはまだ新しいシステムで実行されていませんでした。
- すべてのジョブの基本クラスに機能スイッチを追加しました。
- 私たちは、二週間にわたって各ジョブのための機能スイッチをゆっくりと慎重にオンにしました。
- Cronを実行していた古いbeefy schedulerマシンをシャットダウンしました。
Happy Ending
新しいNextdoorスケジューラを使用すると、分散タスクワーカーマシンで実行するジョブをオフロードするため、負荷を非常に低く保ちながら、以前(c3.8xlarge)よりもはるかに安価なスケジューラEC2インスタンス(c3.2xlarge)を実行することができます。
古いスケジューラマシン(上のグラフ)と新しいスケジューラマシン(下のグラフ)のCPU使用率の比較は次のとおりです:

私たちは18ヶ月以上スケジューラの仕事を使用してきました。 私たちはこれまでのところ幸せです。 この種の問題やその他の興味深いインフラストラクチャの課題に取り組むことに興味があるなら、私たちは雇用しています!