これについてこれ以上見つけることができなかったことに驚いていますが、残念ながら、まだ答えを見つけることができません。最近 AWS に移行し、シンプルなウェブサイトをより堅牢で信頼性の高いシステムに移行しました。現在私を困惑させているのは、分散システムで cron ジョブを管理することです。その cron ジョブは、環境内のすべてのインスタンスにプッシュされます。
ユースケースは次のとおりです。
バックグラウンド
設定
従来の LAMP スタックを実行しています。おそらく最初の問題ですが、それが私たちが得たものです。
DB テーブル
table1
- id int(11)
- start date
- interval int(11) (number of seconds)
table2
- id int(11)
- table1_id int(11)
- sent datetime
ゴール
目標は、スクリプトが毎日 1 回実行され、次のことを確認することです。
- 現在の日付は過ぎています
table1.start
table1.start
< 現在の日付table1.interval
> 0- 今日はちょうど間隔全体です (間隔が 7 日 [秒単位] で 6 日目の場合は失敗します)
- 今日であり、以前のチェックと一致する
table2
ようなエントリはありません。table2.sent
table2.table1_id
これらのすべてのチェックに合格した場合、間隔のある table1 ごとに table2 にエントリを挿入します。これは、table2 のデータに基づいて電子メールを送信することも意味します。
問題
基本的に、前述のブロックで表される 2 つのクエリがあります。問題は、分散システムでは、各インスタンスが同時に (または互いに数ミリ秒以内に) cron を実行することです。table2
「トランザクション」の概念がないため、他のインスタンスが最初のクエリを実行する前に挿入する機会が得られない場合、各インスタンスは電子メールを送信します。
ソリューション???
私はこれについてかなりの量の調査を行いましたが、私が思いついた唯一の潜在的な解決策は以下に詳述されています:
Cron インスタンス
cron ジョブの実行を担当する単一の独立したインスタンスをセットアップします。これは (私が見る限り) 確実に機能しますが、それほど高価ではなく、せいぜい 1 日に 1 回しか実行する必要がないジョブにとっては、非常にコストがかかります。
PHP スケジューラ
スケジューラとして機能する PHP スクリプトを定期的に実行するように cron を設定します。これは、限られた時間とお金の中で最も簡単な方法であることが調査で示唆された後、私たちがたどり着いたルートでした. 私が遭遇した問題は、これにより同時実行性の問題が、ジョブの消費からジョブのスケジューリングに移行したように見えるということでした。cron を実行している各インスタンスから複数のジョブが同時にスケジュールされないように、いつジョブをスケジュールしますか?
この方法も非常に「不器用」(私の友人の好きな言葉を借りる)のようで、私も同意せざるを得ません。
取引
私はこれをかなり調査しましたが、並行性は常にデータベース上のアトミック トランザクションで解決されていましたが、私が知る限り、これを LAMP で実現するのは簡単ではありません。しかし、私は間違っているかもしれません。そうであることが証明されれば幸いです。
ついに
誰かが私がこれを理解するのを手伝ってくれるなら、私はそれを大いに感謝します. おそらく私のグーグル スキルはさびてきているのでしょうが、この (おそらく単純な) タスクに苦しんでいるのは私だけだとは思えません。