2012-03-19 10 views
1

処理するジョブを格納するmysqlテーブルがあります。主に生データのテキストフィールドは処理するのにそれぞれ約1分かかります。メッセージキューの代わりにmysql行レベルの読み取りロック

私は2台のサーバーがそのテーブルからデータを取り出して削除しています。

私は現在amazon SQSを使用している2台のサーバ間のジョブ割り当てを管理します。私はSQSで処理が必要なすべての行IDSを保存し、ワーカー・サーバーは新しい行を処理するためにSQSをポーリングします。

システムは現在動作していますが、SQSは、私がやっていることを達成するために過度に感じる複雑さとコストの層を追加します。

私はSQSなしで同じことを実装しようとしていますが、ある行で作業しているワーカーがその行を選択できるように、行をロックする方法があるかどうか疑問に思っていました。またはそれを行うための良い方法がある場合。

答えて

1

簡単な回避策:ジョブテーブルにもう1つの列、is_taken_by INTを追加します。

select job_id from jobs where is_taken_by is null limit 1 for update; 
update jobs set is_taken_by = worker_pid where id = job_id; 

SELECT ... FOR UPDATEsets exclusive locks on rows it reads

は、その後、あなたの労働者に、あなたはこのような何かを行います。このようにして、他の従業員が同じ仕事をすることができないようにします。

注:これらの2行を明示的なトランザクションで実行する必要があります。自動コミットが無効になっている場合、SELECT FOR UPDATEを使用して、更新のための行の

ロックにのみ適用され(いずれかのSTART TRANSACTIONまたは自動コミットが有効になっている場合は0に自動コミットを設定することで、トランザクションを開始することで、仕様に一致する行がロックされていません。

+0

行を追加する際の問題は、作業者が途中で失敗した場合、その行が処理された状態でテーブルにスタックされていることです...詳細については、「更新」を参照してください。それは行をロックし、どれくらいの期間、問題を解決するかもしれません – applechief

+0

別の列を追加してください: 'locked_at DATETIME'そして、長い時間前にロックされた行のロックを解除するために定期的なcronジョブを実行してください。 –