タグ付けされた質問 「producer-consumer」

3
Redisでメッセージキューを実装する方法は?
キューイングにRedisを使用する理由 私は、Redisがキューイングシステムを実装するための良い候補になることができるという印象を受けています。これまで、MySQLデータベースをポーリングまたはRabbitMQで使用してきました。RabbitMQには多くの問題があります。クライアントライブラリは非常に貧弱でバグが多いため、修正に開発者の時間をかけすぎないように、サーバー管理コンソールにいくつかの問題があります。少なくとも、ミリ秒で把握したり、パフォーマンスを真剣に推進したりすることはないので、システムがキューをインテリジェントにサポートするアーキテクチャを備えている限り、おそらく良好な状態にあります。 さて、それが背景です。基本的に、非常に古典的でシンプルなキューモデルがあります。仕事を生成する複数のプロデューサーと、仕事を消費する複数のコンシューマーがあり、プロデューサーとコンシューマーの両方がインテリジェントにスケーリングできる必要があります。すべてのサブスクライバーに作業を消費さPUBSUBせたくないので、ナイーブが機能しないことがわかります。1人のサブスクライバーに作業を受け取りたいだけです。最初のパスでは、インテリジェントデザインのように見えます。BRPOPLPUSH BRPOPLPUSHを使用できますか? 基本的な設計でBRPOPLPUSHは、1つの作業キューと進行状況キューがあります。コンシューマーが作業を受け取ると、アイテムをアトミックに進行キューにプッシュし、作業を完了するとそれが完了LREMします。これにより、クライアントが死んだ場合の作業のブラックホール化が防止され、監視が非常に楽になります。たとえば、大量のタスクがあるかどうかを通知するだけでなく、消費者がタスクを実行するのに長時間かかる問題があるかどうかを確認できます。 それは保証します 仕事はちょうど1人の消費者に届けられる 作業は進行キューで終了するため、消費者がブラックホールに陥ることはありません 欠点 私が見つけた最高のデザインはPUBSUB、Redisのキューイングに関するほとんどのブログ投稿が焦点を当てているものであるように思われるため、実際には使用していません。だから、私は明白な何かを見逃しているように感じます。PUBSUBタスクを2回消費せずに使用する唯一の方法は、作業が到着したという通知をプッシュするだけで、消費者はそれをブロックしないようにできRPOPLPUSHます。 一度に複数のワークアイテムを要求することはできません。これはパフォーマンスの問題のようです。私たちの状況にとっては大きなものではありませんが、この操作は高スループットまたはこの状況のた​​めに設計されたものではないことを明確に示しています 要するに、私は愚かな何かを見逃していますか? node.jsタグも追加します。これは、私が主に扱っている言語だからです。Nodeは、シングルスレッドでノンブロッキングな性質を考えると、実装のいくつかの単純化を提供するかもしれませんが、さらに、node-redisライブラリとソリューションを使用しています。

1
Consumer / ProducerとObserver / Observableの違い
私は、次の3つの部分で構成されるアプリケーションの設計に取り組んでいます。 特定のイベントの発生(ファイルの作成、外部リクエストなど)を監視する単一のスレッド これらのイベントを処理することでこれらのイベントに応答するN個のワーカースレッド(各ワーカーは単一のイベントを処理して消費し、処理に時間がかかる場合があります) これらのスレッドを管理し、エラー処理を行うコントローラー(スレッドの再起動、結果のログ記録) これは非常に基本的で実装するのは難しくありませんが、それを行うための「正しい」方法は何だろうと思っています(この具体的なケースではJavaですが、より高い抽象化の答えもありがたいです)。2つの戦略が思い浮かびます。 Observer / Observable:監視スレッドはコントローラーによって監視されます。イベントが発生した場合、コントローラーに通知され、再利用可能なキャッシュスレッドプールから新しいタスクを空きスレッドに割り当てることができます(または、すべてのスレッドが現在ビジーである場合、FIFOキューでタスクを待機してキャッシュします)。ワーカースレッドはCallableを実装し、結果(またはブール値)で成功を返すか、エラーを返します。その場合、コントローラーは何をすべきかを決定します(発生したエラーの性質に応じて)。 プロデューサー/コンシューマー:監視スレッドはコントローラーとBlockingQueueを共有し(イベントキュー)、コントローラーはすべてのワーカーと2つを共有します(タスクキューと結果キュー)。イベントの場合、監視スレッドはタスクオブジェクトをイベントキューに入れます。コントローラーは、イベントキューから新しいタスクを取得し、それらをレビューして、タスクキューに入れます。各ワーカーは新しいタスクを待機し、タスクキュー(先着順、キュー自体で管理)からそれらを取得/消費し、結果またはエラーを結果キューに戻します。最後に、コントローラーは結果キューから結果を取得し、エラーが発生した場合に対応する手順を実行できます。 両方のアプローチの最終結果は似ていますが、それぞれわずかな違いがあります。 オブザーバーを使用すると、スレッドの制御は直接行われ、各タスクは特定の新しく生成されたワーカーに割り当てられます。スレッド作成のオーバーヘッドは高くなる可能性がありますが、キャッシュされたスレッドプールのおかげではありません。一方、Observerパターンは、複数ではなく単一のObserverに縮小されます。これは、厳密に設計されたものではありません。 キュー戦略は拡張が容易なようです。たとえば、1つではなく複数のプロデューサーを追加するのは簡単で、変更を必要としません。欠点は、作業をまったく行わない場合でも、すべてのスレッドが無期限に実行され、エラー/結果の処理が最初のソリューションほど洗練されていないことです。 この状況で最もふさわしいアプローチは何ですか?その理由は?ほとんどの例は、Observerケースの新しい値で多くのウィンドウを更新したり、複数のコンシューマーとプロデューサーで処理したりするなど、明確なケースのみを扱っているため、この質問に対する答えをオンラインで見つけるのは難しいと感じました。どんな入力でも大歓迎です。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.