私はこれについてもっと見つけられなかったことに驚いていますが、悲しいかな、私はまだ答えを見つけることができません。私たちは最近、AWSに変換し、シンプルなウェブサイトをより堅牢で信頼性の高いシステムに移行しました。現在、私が困惑しているのは、そのcronジョブが環境内のすべてのインスタンスにプッシュされるときに、分散システム上でcronジョブを管理することです。ここでAWSの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
ゴール
目標は、スクリプトは毎日一回実行すると、以下のチェックすることです:
- 現在の日付が過去であるが
table1.start
table1.start
<現在の日付table1.interval
> 0- 今日は離れて正確に全区間である(その間隔は[秒で] 7日だったし、それが6日目である場合に失敗します)
table2.sent
が今日あるようなtable2
にエントリがありません前のチェックと一致するのはtable2.table1_id
です。
これらのチェックがすべて合格した場合、間隔を持つテーブル1ごとにtable2にエントリを挿入します。これはまた、表2のデータに基づいて電子メールを送信することを意味します。
問題基本的に
、我々は前述のブロックによって表される2つのクエリを、持っています。問題は、分散システムでは、各インスタンスが同時に(または互いにミリ秒以内に)cronを実行するということです。 「トランザクション」という概念はないので、他の人が最初のクエリを実行する前にtable2
に挿入する機会がないと、各インスタンスは電子メールを送信します。
解決策???
私はこの研究のかなりの量を行っているが、私は出ている唯一の潜在的な解決策を以下に詳述する:
cronのインスタンス
がランニングを担当し、単一の、独立したインスタンスを設定しますcronジョブ。これは確かに(私が見る限り)仕事ですが、ひどく高価ではなく、たいてい1日に1回だけ実行する必要がある仕事には、非常にコストがかかります。
PHPスケジューラ
セットcronが定期的にスケジューラとして動作するPHPスクリプトを実行します。これは、我々の研究が限られた時間とお金のために最も簡単であると示唆した後に我々が下降していたルートであった。私が遭遇した問題は、並行処理の問題をジョブの消費からジョブのスケジューリングに変えるように思えたことでした。 cronを実行している各インスタンスから複数のジョブが同時にスケジュールされないようにジョブをスケジュールするのはいつですか?
この方法も(私の友人の好きな言葉を借りるために)非常に "クルージュ"と思われ、私は同意する必要があります。
取引
私はこのかなり研究してきたがは、並行処理は常にデータベース上のアトミックトランザクションを解決した、これまでのところ、私は言うことができるように、これはLAMPを達成することは容易ではありません。しかし、おそらく私は間違っています。私はそう証明されてとても幸せです。
最後に
誰も私はこの1つを把握することができますのであれば、私はそれを大幅に感謝。おそらく、私のグーグルのスキルは錆びていますが、私はこの(おそらく単純な)仕事に苦しんでいる唯一の人だとは想像できません。
これを実際に建設的な答えに変えるのに十分な経験はありませんが、AmazonのSWFを見てきましたか?すでにAWSに乗っているので、cronの代わりに信頼できるものです。 –
恐ろしいと思われるかもしれませんが、[Zookeeper](http://zookeeper.apache.org/)を見てください。軽量で堅牢な使い方が簡単で、分散したタスクをできるだけシンプルに調整/同期化する作業を行います。 – Viccari
Kohanaを使用していることも注目に値するかもしれません。トランザクションがアトミックで直列になっていることを確認するために、DBクエリで行うことができるロックのレベルがあるかどうか疑問に思っています。 – Ryan