0

ジョブ スケジューラを構築しようとしています。時間ベースで 2 ~ 3 台の異なるマシンで実行するジョブのリストがあります。したがって、どのマシンでも任意のジョブを選択でき、next_execution_time < current_time. すべてのジョブをデータベース テーブルに格納しSELECT.... FOR UPDATE、SQL でクエリを使用して実行するジョブを選択しています。

しかし、このアプローチの問題は、machine1 がジョブを選択した場合、書き込みロックしかないため、他のマシンも実行のために同じジョブを選択しますが、ロックが解除されるのを待つため実行できないことです。解放またはロックのタイムアウトが発生します。他のマシンがこのジョブをスキップし、SQL ロックを使用して他のジョブを実行する方法はありますか。データベースに他の列を追加する必要はありませんか?

フローは次のようなものです:

select a job and lock it -> execute the job -> release the lock

これを開発するために ruby​​-on-rails を使用しています。レールにノーウェイトまたは set_lock_timeout = 0 がある場合。おそらく問題を解決できます。存在する場合...構文は何ですか?

4

1 に答える 1

0

実際には、mysql の現在のテーブルでこれを行う簡単な方法があります。次のタスクを選択するときにテーブルを一時的にロックする必要があります。テーブルに既に開始済み/完了済みのタスクにフラグを立てるための列があると仮定しています。それ以外の場合は、同じ列を日時とともに使用してジョブを開始し、既に完了済み/開始済みであることを示すフラグを立てることができます。

lock tables jobs write;

select * from jobs where start_time < current_time and status = 'pending' order by start_time;
-- be carefull here to check for SQL errors in your code and run unlock tables if an exception is thrown or something like that

update jobs set status = 'started' where id = the_one_you_selected_adobe;

unlock tables;

それだけです。複数の同時スレッド/プロセスは、同じタスクを実行する 2 つのスレッドを持たなくても、ジョブ テーブルを使用してタスクを実行できます。

于 2013-11-01T18:40:16.970 に答える