ジョブを実行するためにフェッチされるテーブルに多くのエントリがあります。これは、複数のサーバーにスケーリングされます。
サーバーが一連の行をフェッチして独自のジョブ キューに追加するときは、他のサーバーがフェッチしないように「ロック」する必要があります。更新が実行されると、タイムスタンプが増加し、「ロック解除」されます。
私は現在、ジョブサーバーのIDでデフォルトでnullに設定されているテーブルの「ジョブサーバー」と呼ばれるフィールドを更新することでこれを行っています。
ジョブ サーバーは、フィールドが null の行のみを選択します。
すべての行が処理されると、タイムスタンプが更新され、最後にジョブ フィールドが再び null に設定されます。
だから私はこれを同期する必要があります:
$jobs = mysql_query("
SELECT itemId
FROM items
WHERE
jobserver IS NULL
AND
DATE_ADD(updated_at, INTERVAL 1 DAY) < NOW()
LIMIT 100
");
mysql_query("UPDATE items SET jobserver = 'current_job_server' WHERE itemId IN (".join(',',mysql_fetch_assoc($jobs)).")");
// do the update process in foreach loop
// update updated_at for each item and set jobserver to null
すべてのサーバーは上記を無限ループで実行します。フィールドが返されない場合、すべてが 2 日付 (最後の更新が 24 時間以内) であり、10 分後に送信されます。
私は現在 MyIsam を持っていますが、私の場合は innodb よりもパフォーマンスがはるかに優れていたので、そのまま使用したいと思っていますが、innodb には ACID トランザクションがあると聞きました。
そのため、選択と更新を1つとして実行できました。しかし、それはどのように見えて機能するのでしょうか?
問題は、他のプロセスが読み取り/書き込みを行う必要があり、ロックできないため、テーブルなどをロックする余裕がないことです。
また、共有セマフォなどのより高いレベルのソリューションにもオープンです。問題は、同期が複数のサーバーにまたがる必要があることです。
アプローチは一般的に正気ですか?あなたはそれを違うようにしますか?
ジョブ selectino を同期して、2 つのサーバーが同じ行を更新しないようにするにはどうすればよいですか?