ワーカープロセスにタスクを割り当てるためにMySQLを使用するための正しい方法

StackOverflow https://stackoverflow.com/questions/664774

質問

私は、MySQLのInnoDBテーブル内のURLの膨大なリストを持って、そして処理するために、一連のURLのためのMySQLを照会ワーカープロセス。他のワーカープロセスが同じものを処理するために開始することにより、資源を無駄にしないように、URLはすぐに、処理されているとしてマークする必要があります。

現在、私が最初にいくつかのURLを取得するには、この操作を行います:

SELECT DISTINCT url FROM urls WHERE task_assigned is NULL ORDER BY id LIMIT 100

次に、コードに私が処理されるように、それをマークするために、これらのURLの各々を介してループを単純に

UPDATE urls SET task_assigned = NOW() WHERE url = ? COLLATE utf8_bin

私はこれがどのように愚かな、非効率完璧承知しています。さらに重要なことは、別のワーカープロセスが私の更新の途中でリストを取得しようとしないだろうという保証はありません。これを行うには、美しい方法は何ですか?私はそれトランザクションにする必要があり、どのように?

役に立ちましたか?

解決

のMySQLで利用できるようにする(MySQLの5マニュアルでチラッによって)以下が表示されます。私はそれが最善の方法だかどうかわからないんだけど、私はPostgreSQLの中で前に使用しているものです。

BEGIN TRANSACTION;
SELECT DISTINCT url FROM urls WHERE task_assigned is NULL ORDER BY id LIMIT 100 FOR UPDATE;
UPDATE urls SET task_assigned = NOW() WHERE url IN [list of URLs] COLLATE utf8_bin;
COMMIT;

実際のPostgreSQLに私はSELECTの場所を取るUPDATEのRETURNING句とのシングルのUPDATEステートメントを使用しますが、それは、PostgreSQL固有の拡張機能です。

あなたのアプローチと私は見る一つの潜在的な問題が重複したURLである:URLのhttp://www.example.com/があなたのテーブルに二回表示された場合は、IDが23と42と言う、それがSELECTによって、これら2つのIDのいずれかで返されますが、UPDATE、両方に影響を与えます行。その振る舞いは、アプリケーションで理にかなっているかどうかは知りません。それが起こるし、その後IN句(より高速であるべき)で、IDは、ないURLのリストを使用することができなかったので、私はおそらく、URLを上のUNIQUE制約のいくつかの種類をかけることになります。

他のヒント

たぶん、あなただけの最初のすべてのURLを選択し、非同期的にそれらを解析するためにスレッドを使用する必要がありますか?

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top