3

私はbeanstalkdのPerlクライアントを使用しています。同じ作業を2回エンキューしない簡単な方法が必要です。

基本的にK個の要素ができるまで待ってからグループ化する必要があるものが必要です。これを達成するために、私にはプロデューサーがいます:

insert item(s) into DB
insert a queue item into beanstalkd

そして消費者:

while ( 1 ) {
   beanstalkd.retrieve
   if ( DB items >= K )
       func_to_process_all_items
   kill job
}

これは、リクエスト/処理の数に比例しますが、次の場合です。

insert 1 item
... repeat many times ...
insert 1 item

これらすべての挿入がジョブが取得される前に発生したと仮定すると、これによりN個のキュー項目が追加され、次のようになります。

check DB, process N items
check DB, no items
... many times ...
check DB, no items

後のジョブリクエストを不必要に挿入/処理しないように、これを行うためのよりスマートな方法はありますか?

4

2 に答える 2

2

関連する要件がありました。特定のジョブを数分以内に1回だけ処理したかったのですが、プロデューサーは同じジョブの複数のインスタンスをキューに入れることができました。memcacheを使用してジョブ識別子を保存し、キーの有効期限をわずか数分に設定しました。

ワーカーがジョブ識別子をmemcacheに追加しようとすると、最初のIDのみが成功します。ジョブIDの追加に失敗すると、ワーカーはジョブを削除します。数分後、キーはmemcacheから期限切れになり、ジョブを再度処理できるようになります。

特にエレガントではありませんが、機能します。

于 2011-02-08T10:53:48.813 に答える
1

これはうまくいきますか?:

  1. 「buffer」と「live」の 2 つの Tube を作成します。プロデューサーは常に「バッファー」チューブにのみ追加します。
  2. 1 つは「バッファ」を監視し、もう 1 つは「ライブ」を監視し、ブロッキングreserve()コールを呼び出す 2 つのワーカーを作成します。
  3. 「バッファ」ワーカーがリザーブに戻るときはいつでも、アイテムが K 未満の場合、ジョブを埋めます。正確に K 個ある場合、すべての K 個のジョブを「キック」し、それらを「ライブ」チューブに転送します。
  4. 「ライブ」ウォッチャーが自動的に戻るようになりましたreserve()

埋もれた状態からジョブがバッファ キューに戻らないように注意する必要があります。これを行うフェイルセーフな方法は、それを削除してからライブに追加することです。

2 つの別々のキューは、より明確に分離するためだけのものです。K-1 になるまですべてのジョブを埋め、K 番目のジョブが到着したらすべてのジョブを有効にすることで、単一のキューで同じことを行うことができます。

于 2009-12-24T04:10:58.233 に答える