Redis Queue StreamとRedisマルチスレッドの詳細解説(2)

Redis キューのいくつかの実装の概要

リストベースのLPUSH+BRPOPの実装

これは非常に単純で、メッセージ消費の遅延はほぼゼロですが、アイドル状態の接続の問題に対処する必要があります。

そこでスレッドがブロックされている場合、Redis クライアントの接続はアイドル接続になります。アイドル状態が長すぎると、サーバーは通常、アイドル リソースの占有を減らすために積極的に接続を切断します。このとき、blpop とbrpop は例外をスローする可能性があるため、クライアント消費を記述するときは例外をキャッチするときに注意してください。例外をキャッチした場合は再試行する必要があります。

その他の欠点は次のとおりです。

コンシューマにとって ACK を確認するのは面倒であり、コンシューマがメッセージを消費した後に正常に処理できるかどうかを保証することは不可能です (ダウンタイムや処理例外など)。通常、メッセージ処理の確認を確実にするために Pending リストを維持する必要があります。パブリッシュ/サブスクライブ モードは使用できません。メッセージ パブリッシュ/サブスクライブ モデル。繰り返し消費することはできません。一度消費されると削除されます。グループ消費はサポートされません。

ソートセットに基づく実装

これは主に遅延キューの実装に使用されます。もちろん、整然とした通常のメッセージ キューも実装できますが、コンシューマはメッセージを取得するためにブロックすることはできず、ポーリングのみが可能で、メッセージの繰り返しは許可されません。

PUB/SUB、サブスクライブ/パブリッシュ モード

アドバンテージ:

一般的なブロードキャスト モードでは、メッセージを複数のコンシューマに公開できます。マルチチャネル サブスクリプションでは、コンシューマは同時に複数のチャネルにサブスクライブして、複数の種類のメッセージを受信できます。メッセージはすぐに送信され、コンシューマはメッセージを送信する必要はありません。コンシューマがメッセージを読むのを待つために、コンシューマはチャネルによって発行されたメッセージを自動的に受信します。

欠点:

メッセージが公開されると、受信できなくなります。つまり、公開時にクライアントがオンラインでない場合、メッセージは失われ、取得できなくなります。各コンシューマの受信時間が一貫していることは保証できません。コンシューマにメッセージのバックログがある場合は、クライアントの電源がオンになっていると、ある程度強制的に切断され、予期しないメッセージの損失が発生します。これは通常、メッセージの生成が消費の速度よりもはるかに速い場合に発生します。Pub/Sub モデルはメッセージ ストレージやメッセージ バックログ サービスには適していないものの、ブロードキャスト、インスタント メッセージング、インスタント メッセージの処理には優れていることがわかります。フィードバックサービス。

ストリームタイプに基づいた実装

基本的に、メッセージ ミドルウェアの初歩的な形式はすでに存在しており、運用プロセスでの使用を検討できます。もちろん、実際に運用に適用するには、やるべきことがまだたくさんあります。たとえば、メッセージの管理や監視などです。また、プロフェッショナルなメッセージ キューには、優れたサードパーティのソリューションやプラグインがすでに付属しているか、それらが組み込まれています。

メッセージキューの問題

上記の Stream の使用法から、Stream にはメッセージ キュー、プロデューサー API、コンシューマー API、メッセージ ブローカー、メッセージ確認メカニズムなどの基本要素がすでに備わっていることがわかります。そのため、メッセージ ミドルウェアの使用時に生じる問題も同様です。ここで起こります。

ストリーム メッセージが多すぎる場合はどうすればよいですか?

蓄積されたメッセージが多すぎると、ストリームのリンク リストが非常に長くなり、内容が爆発してしまいませんか? xdel コマンドはメッセージを削除せず、メッセージにマークを付けるだけです。

Redis は当然これを考慮して、固定長の Stream 関数を提供します。xadd 命令は固定長の maxlen を提供します。これにより、古いメッセージを削除し、最大長が指定された長さを超えないようにすることができます。

メッセージが ACK を忘れた場合はどうなりますか?

ストリームは、各コンシューマ構造で処理されているメッセージ ID リスト PEL を保存します。コンシューマがメッセージを受信して​​処理しても、ACK に応答しない場合、PEL リストは増加し続けます。コンシューマ グループが多数ある場合、PEL の占有メモリ拡大されます。したがって、メッセージはできるだけ早く消費して確認する必要があります。

PEL はメッセージ損失をどのように回避しますか?

クライアント コンシューマがストリーム メッセージを読み取り、Redis サーバーがそのメッセージをクライアントに応答すると、クライアントが突然切断され、メッセージが失われます。ただし、送信されたメッセージの ID は PEL に保存されています。クライアントは再接続後、PEL でメッセージ ID リストを再度受信できます。ただし、現時点では、xreadgroup の初期メッセージ ID をパラメータ > にすることはできませんが、任意の有効なメッセージ ID にする必要があります。通常、パラメータは 0 ~ 0 に設定されます。これは、すべての PEL メッセージと last_delivered_id 以降の新しいメッセージを読み取ることを意味します。

デッドレター問題

メッセージがコンシューマーによって処理できない場合、つまり XACK が送信できない場合、メッセージは各コンシューマーに繰り返し転送されたとしても、長期間保留リストに残ります。このとき、メッセージの配信カウンター (XPENDING を通じて照会できます) が累積され、その累積が事前に設定した特定のしきい値に達すると、悪いニュース (デッドレター、デッドレター、配信不能メッセージとも呼ばれます) と見なされます。判定条件があるため、悪いニュースに対処して削除することができます。メッセージを削除するには、XDEL 構文を使用します。このコマンドは保留中のメッセージを削除しないことに注意してください。そのため、「保留中」をチェックすると、メッセージはそのまま残ります。XDEL を実行すると、メッセージ XACK が処理されたことを示します。

ストリームの高可用性

Stream の高可用性はマスター/スレーブ レプリケーションに基づいており、他のデータ構造レプリケーション メカニズムと何ら変わりません。つまり、Stream は Sentinel および Cluster クラスター環境で高可用性をサポートできます。ただし、Redis のコマンド レプリケーションは非同期であるため、フェイルオーバーが発生すると、Redis はデータのごく一部を失う可能性があり、同じことが Redis の他のデータ構造にも当てはまります。

パーティション パーティション

Redis サーバーはネイティブにパーティショニングをサポートしていないため、パーティショニングを使用する場合は、複数のストリームを割り当て、クライアント側で特定の戦略を使用して異なるストリームにメッセージを生成する必要があります。

ストリーム概要

Stream の消費モデルは、Kafka の消費グループの概念を利用しており、Redis Pub/Sub がメッセージを永続化できないという欠点を補っています。ただし、Kafka とは異なり、Kafka のメッセージはパーティションに分割できますが、Stream は分割できません。分割する必要がある場合は、クライアント側で分割し、異なるストリーム名を指定し、メッセージに対してハッシュモジュロを実行して、どのストリームに詰め込むかを選択する必要があります。

一般的に中小規模のプロジェクトや企業であればRedisを業務に利用しており、業務量がそれほど大きくなくメッセージミドルウェア機能が必要な場合にはRedisのStream機能を検討することができます。ただし、同時実行性が高く、リソースが十分である場合は、RocketMQ、Kafka などのプロフェッショナルなメッセージ ミドルウェアを使用してビジネスをサポートすることをお勧めします。

おすすめ

転載: blog.csdn.net/yaya_jn/article/details/130224172