ホームページ >データベース >Redis >Redis パブリッシュ/サブスクライブ モデルの分析例

Redis パブリッシュ/サブスクライブ モデルの分析例

WBOY
WBOY転載
2023-05-27 21:29:321708ブラウズ

Redis パブリッシュ/サブスクライブ アプリケーション

パブリッシュとサブスクライブ (pub/sub) は、メッセージ通信モデルです。主な目的は、メッセージ パブリッシャーとメッセージ サブスクライバーの間の結合を分離することです。この点は同様です。デザインパターンのObserverパターンに。 pub/sub は、パブリッシャーとサブスクライバーの直接的なコードレベルの結合を解決するだけでなく、物理的なデプロイメントにおける 2 つの結合も解決します。パブリッシュ/サブスクライブ サーバーとして、redis はサブスクライバーとパブリッシャー間のメッセージ ルーティング機能を果たします。サブスクライバーは、subscribe および psubscribe コマンドを使用して、関心のあるメッセージ タイプの Redis サーバーにサブスクライブできます。Redis は、メッセージ タイプをチャネルと呼びます。パブリッシャーが、publish コマンドを通じて特定の種類のメッセージを Redis サーバーに送信するとき。このメッセージ タイプを購読するすべてのクライアントは、このメッセージを受信します。ここでのメッセージ配信は多対多です。クライアントは複数のチャネルにサブスクライブし、複数のチャネルにメッセージを送信できます。

基本的なコマンドから始めましょう:

PSUBSCRIBE pattern [pattern ...]              #订阅一个或多个符合给定模式的频道;PUBSUB subcommand [argument [argument ...]]   #查看订阅与发布系统状态;PUBLISH channel message                       #将信息发送到指定的频道;PUNSUBSCRIBE [pattern [pattern ...]]          #退订所有给定模式的频道;SUBSCRIBE channel [channel ...]               #订阅给定的一个或多个频道的信息;UNSUBSCRIBE [channel [channel ...]]           #指退订给定的频道;

Redis マニュアルからわかるように、実際には、「パブリッシュとサブスクライブ」モードには 6 つのコマンドしかありません。 one.

SUBSCRIBE

特定のチャネルからの情報を購読します。

SUBSCRIBE channel [channel ...]

上記の公式説明から判断すると、ゲームプレイは現実のラジオを聴くのと少し似ています。ラジオを聴きたい場合はどうすればよいでしょうか?それは FM でなければなりません。正しいチャンネルでのみ、良い番組を聴くことができます。したがって、購読するには、まずチャンネルに購読する必要があります。以下に例を示します。2 つのクライアントを開いて、それぞれ msg チャンネルに購読します。たとえば、

root@localhost:~ # redis-cli -p 6379127.0.0.1:6379> SUBSCRIBE msg
Reading messages... (press Ctrl-C to quit)
1) "subscribe"2) "msg"3) (integer) 1

root@localhost:~ # redis-cli -p 6379127.0.0.1:6379> SUBSCRIBE msg
Reading messages... (press Ctrl-C to quit)
1) "subscribe"2) "msg"3) (integer) 1

SUBSCRIBE は複数のチャネルにサブスクライブすることもできるため、受信する情報は複数のチャネルから得られる可能性があります。

PUBLISH

これまで、この 2 人の購読者が msg チャンネルを監視していましたが、次に msg チャンネルからニュースが発信されれば、必ず購読されます。 . 受け取りましたので、まず Redis マニュアルでこのコマンドの使用方法を見てみましょう。

指定されたチャネルチャネルに情報メッセージを送信します。

PUBLISH channel message

次のデモ:

Redis パブリッシュ/サブスクライブ モデルの分析例

パブリッシュがメッセージを msg チャネルに送信した後、そのメッセージはサブスクライブによって監視され、個別に出力されます。はい、これまでのところ、最も基本的なパブリッシュ/サブスクライブ モデルは次のようになります。非常に単純ではないでしょうか?実は? ? ?非常にシンプルですが、キーをファジー一致させることができるかどうかというニーズが依然として存在することがあります。たとえば、プレフィックス china が付いているすべてのチャンネルを購読する必要がありますが、これが可能であれば、非常に素晴らしいことになります。 。 。私が答えるとしたら、強力な Redis が間違いなくそれを実行でき、PSUBSCRIBE コマンドが提供されるということでしょう。

PSUBSCRIBE

指定されたパターンに一致する 1 つ以上のチャネルをサブスクライブします。各パターンは、一致する文字として を使用します。たとえば、it は一致します。で終わるすべてのチャネル it で始まるチャネル (it.news、it.blog、it.tweets など)、news.* は news. で始まるすべてのチャネル (news.it、news.global.today など) に一致します。等々。

PSUBSCRIBE pattern [pattern ...]

上記の説明を見て、これは単なる通常のマッチングではないかと思われるかもしれません。 。 。次に、接頭辞「中国」が付いたすべてのチャンネルを購読します。接頭辞「P」は「パターン」の略ですよね。 。

Redis パブリッシュ/サブスクライブ モデルの分析例

PSUBSCRIBE は、さまざまなパターンに一致する複数のパラメーターを受け取ることができます。小さな例を読んだ後は、pub/sub 関数を感覚的に理解できるはずです。接続が submit または psubscribe サブスクリプション チャネルを通過すると、サブスクリプション モードになることに注意してください。このモードでは、追加のチャネルにサブスクライブするか、unsubscribe または punsubscribe コマンドでサブスクリプション モードを終了すること以外、他のコマンドは送信できません。さらに、psubscribe コマンドを使用して複数のワイルドカード チャネルに登録すると、メッセージが複数のチャネル パターンに一致する場合、同じメッセージが複数回受信されます。

Redis の pub/sub 実装に必要なコードは 150 行だけですが、その機能は十分に完成していない可能性があります。セキュリティ、認証、信頼性の面でのサポートはあまりありません。

Redis パブリッシュ/サブスクライブ メカニズム

クライアントが PUBLISH コマンドを通じてサブスクライバーに情報を送信するとき、クライアントをパブリッシャーと呼びます。

クライアントが SUBSCRIBE または PSUBSCRIBE コマンドを使用して情報を受信するとき、そのクライアントをサブスクライバーと呼びます。

パブリッシャーとサブスクライバーの関係を切り離すために、Redis は 2 つの間の仲介者としてチャネルを使用します - パブリッシャーは情報をチャネルに直接公開し、チャネルは適切なサブスクライバーに情報を送信する責任があります。パブリッシャーとサブスクライバーの間には相互関係がなく、お互いの存在を知りません:

Redis パブリッシュ/サブスクライブ モデルの分析例

知道了发布和订阅的机制之后,接下来就可以开始研究具体的实现了,我们从Redis的订阅命令开始说起。

SUBSCRIBE命令的实现

前面说到,Redis将所有接受和发送信息的任务交给channel来进行,而所有channel的信息就储存在redisServer这个结构中:

struct redisServer {
  // 省略 ...
  dict *pubsub_channels; // Map channels to list of subscribed clients
  // 省略 ...
};

pubsub_channels是一个字典,字典的键就是一个个channel,而字典的值则是一个链表,链表中保存了所有订阅这个channel的客户端。

举个例子,如果在一个 redisServer 实例中,有一个叫做 news 的频道,这个频道同时被client_123 和 client_456 两个客户端订阅,那么这个 redisServer 结构看起来应该是这样子: Redis パブリッシュ/サブスクライブ モデルの分析例

可以看出,实现SUBSCRIBE命令的关键,就是将客户端添加到给定channel的订阅链表中。

PSUBSCRIBE命令的实现

除了直接订阅给定channel外,还可以使用PSUBSCRIBE订阅一个模式(pattern),订阅一个模式等同于订阅所有匹配这个模式的channel 。

和redisServer.pubsub_channels属性类似,redisServer.pubsub_patterns属性用于保存所有被订阅的模式,和pubsub_channels不同的是, pubsub_patterns是一个链表(而不是字典):

struct redisServer {
  // 省略 ...
  list *pubsub_patterns; // A list of pubsub_patterns
  // 省略 ...
};

pubsub_patterns 的每一个节点都是一个 pubsubPattern 结构的实例,它保存了被订阅的模式,以及订阅这个模式的客户客户端:

typedef struct pubsubPattern {
  redisClient *client;
  robj *pattern;
} pubsubPattern;

举个例子,假设在一个 redisServer 实例中,有一个叫做 news.* 的模式同时被客户端client_789 和 client_999 订阅,那么这个 redisServer 结构看起来应该是这样子: Redis パブリッシュ/サブスクライブ モデルの分析例

现在可以知道,实现PSUBSCRIBE命令的关键,就是将客户端和订阅的模式添加到redisServer.pubsub_patterns当中。

以上がRedis パブリッシュ/サブスクライブ モデルの分析例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。