申し訳ありませんが、通常の応答には、大量のテキスト/理論が必要です。あなたの良い質問は、あなたがすでに良い答えを書いているからです:)
まず、用語を定義する必要があります。アンダースコア/ロダッシュに関する「デバウンス」は、David Corbacho の記事の説明で学習する必要があります。
Debounce : 「複数のイベントを 1 つにまとめる」と考えてください。あなたが家に帰り、エレベーターに乗り込み、ドアが閉まっていると想像してみてください...そして突然、あなたの隣人がホールに現れ、エレベーターに飛び乗ろうとします。丁寧に!そして彼のためにドアを開けてください:あなたはエレベーターの出発をデバウンスしています. 同じ状況が第三者と再び発生する可能性があることを考慮してください...おそらく出発が数分遅れます。
スロットル: バルブと考えてください。実行の流れを調整します。特定の時間内に関数を呼び出すことができる最大回数を決定できます。エレベーターの例えで言えば、10 秒間人を入れるほど丁寧ですが、その遅延が過ぎたら、行かなければなりません。
debounce
最初の要素がリストにプッシュされるので、あなたは尋ねています:
そのため、エレベーターとの類推によって。エレベーターが最初の人に来てから10分後にエレベーターが上がるはずです. エレベーターに何人が詰め込まれたかは関係ありません。
分散フォールト トレラント システムの場合、これは一連の要件と見なす必要があります。
- 新しいリストの処理は、最初の要素の挿入 (つまり、リストの作成) 後、X 時間以内に開始する必要があります。
- ワーカーのクラッシュによって何も壊れてはなりません。
- デッドロックフリー。
- 最初の要件は、ワーカーの数 (1 か N かに関係なく) を満たす必要があります。
つまり、(分散方法で)知っておく必要があります-ワーカーのグループを待つ必要があるか、リスト処理を開始できます。「分散」と「フォールトトレラント」というフレーズを発するとすぐに。これらの概念は常に友達とつながります。
- 原子性 (例: ブロッキングによる)
- 予約
実際には
実際には、システムをもう少し複雑にする必要があるのではないかと心配しています (おそらく、書いていないだけで、すでに持っているかもしれません)。
あなたの方法:
- SET NX PX を介したミューテックスによる悲観的ロック。
NX
一度に 1 つのプロセスだけが作業を行うこと (原子性) が保証されます。は、このPX
プロセスで何かが発生した場合に、Redis によってロックが解放されることを保証します (デッド ロックに関するフォールト トレラントの一部)。
- すべてのワーカーは (リスト キーごとに) 1 つのミューテックスをキャッチしようとするため、1 つだけが満足して、X 時間後にリストを処理します。このプロセスにより、mutex の TTL を更新できます (当初の予定よりも時間が必要な場合)。プロセスがクラッシュした場合、ミューテックスは TTL 後にロック解除され、他のワーカーによって取得されます。
私のおすすめ
RPOPLPUSHを中心に構築された Redisのフォールト トレラントな信頼できるキュー処理:
- 処理から特別なリストへの RPOPLPUSH アイテム (リストごとのワーカーごと)。
- 処理項目
- 特別なリストからアイテムを削除
要件 したがって、ワーカーがクラッシュした場合、特別なリストからメイン リストに壊れたメッセージをいつでも返すことができます。また、Redis は RPOPLPUSH/RPOP の原子性を保証します。つまり、しばらく待つのは問題のある作業員グループだけです。
そして、2つのオプション。最初 - 多くのクライアントと少ないワーカーがワーカー側でロックを使用している場合。そのため、ワーカーでミューテックスをロックしてみてください。成功した場合は、処理を開始してください。
およびその逆。LPUSH/RPUSH を実行するたびに SET NX PX を使用します (多くのワーカーといくつかのプッシュ クライアントがある場合に、「ポップする前に N 時間待機する」ソリューションを使用するため)。したがって、プッシュは次のとおりです。
SET myListLock 1 PX 10000 NX
LPUSH myList value
そして、各ワーカーは myListLock が存在するかどうかを確認するだけで、処理ミューテックスを設定してドレインを開始する前に、少なくともキー TTL を待機する必要があります。