Skip to content

分散cronとスケジューリング

この記事は英語版から翻訳されました。最新版は英語版をご覧ください。

分散cronは、クラスタ全体で「時刻」を作業に変換します。単純に見えますが、時計ずれ、スケジューラ再起動、夏時間、長時間実行、複数リージョンの二重所有があると難しくなります。本番のスケジューラには、永続スケジュール、リース、missed-run policy、jitter、backpressure、重複tickの意味定義が必要です。

モデル

作業開始前にrun recordを永続化します。run recordは監査証跡であり、tick重複排除キーです。

Schedule と Run

オブジェクト変更可能性
Schedule毎日09:00 Asia/Tokyoユーザー/設定により変更可能
Runschedule A at 2026-06-15T00:00Zidentityは不変、statusは変更

run identityは (schedule_id, scheduled_time) にします。現在時刻の丸めだけを使うと重複や漏れの原因になります。

Tick Claim

sql
INSERT INTO scheduled_runs (schedule_id, scheduled_at, status, created_at)
VALUES (:schedule_id, :scheduled_at, 'created', now())
ON CONFLICT (schedule_id, scheduled_at) DO NOTHING;

DB制約で重複検出します。run作成後にスケジューラが落ちても、reconcilerが created-but-not-started run をenqueueできます。

時刻セマンティクス

要件設計
UTC intervalintervalと次のUTC fire timeを保存
ローカル業務時刻numeric offsetではなくIANA timezoneを保存
DST spring forwardskipまたはshiftを定義
DST fall back1回か2回か定義
月末clampまたはskipを定義
SLA windowlatest acceptable startを保存

時刻ポリシーは利用者に見える仕様にします。隠れたデフォルトは請求/コンプライアンス事故になります。

Missed Runs

ポリシー使う場合
Skip新鮮さが完全性より重要
Catch up allすべての期間が法的/金銭的に必要
Catch up latest only最新状態だけ意味がある
Bounded catch-up古い作業は一定期間だけ有用

backfillはlive tickと無制限に同じcapacityを共有させないでください。

Jitter

全テナントが0時に実行されると、自分で障害を作ります。決定的jitterを使います。

text
offset_seconds = hash(schedule_id) % jitter_window_seconds
actual_fire_time = nominal_fire_time + offset_seconds

Sharding

戦略強みリスク
schedule ID hash単純で均等hot tenantは残る
time bucketdue scanが効率的common timeがhotになる
tenant shard分離とquota制御tenantサイズが偏る
DB range scan + leases復旧が簡単DBがscheduler bottleneck

障害モード

障害症状対策
clock skewtickが早い/遅いNTP、DB/server time基準
scheduler split brainduplicate runsunique run keyと冪等start
catch-up storm障害復旧後にworkers飽和bounded catch-upと別queue
DST ambiguity二重請求/レポート漏れ明示timezone policy
long-running overlap同じjobが並行実行scheduleごとのconcurrency policy

運用メトリクス

  • schedule scan lag
  • dueだが未評価の最古schedule
  • run creation latency
  • duplicate run conflict数
  • missed run数
  • catch-up backlog
  • scheduler shard ownership churn

関連パターン

MITライセンスの下で公開。Babushkaiコミュニティが構築。