This is the third day of my participation in the November Gwen Challenge. Check out the details: the last Gwen Challenge 2021
Writing in the front
Redis is a fully open source, high-performance key-value database, which is being used in more and more business scenarios. The “publish/subscribe” messaging pattern may be well understood, but how it works and how it works is still unclear.
Today, WE plan to talk about Redis publishing and subscription in simple terms, as easy as possible, so that everyone can easily get started.
Publish/subscribe
About the publish/subscribe model
In software architecture, publish/subscribe is a message pattern in which the sender of a message (called a publisher) does not send the message directly to a specific recipient (called a subscriber), but rather broadcasts it through a message channel for consumption by subscribers who subscribe to the message topic.
Redis provides publishing and subscription functions, which can be used for message transmission. The publishing and subscription mechanism of Redis consists of three parts: Publisher, Subscriber and Channel. The biggest feature of the publish/subscriber pattern is its loose coupling.
Redis publishes subscription categories
-
Channel publishing subscription
-
Publish subscriptions to patterns
The realization principle and application are described in detail below.
Channel publishing subscription
Realize the principle of
Redis stores the subscription relationship of all channels in the pubsub_Channels dictionary of the server state. The key of the dictionary is a channel that is subscribed to, and the corresponding value is a linked list that records all the clients that subscribed to this channel.
struct redisServer{ //... Dict *pubsub_channels; / /... }Copy the code
An example pubsub_channels dictionary is as follows:
-
Client-1, client-2, and client-3 are currently subscribing to the article. Tech channel
-
Client -4 is subscribing to the article. Mysql channel
-
Client-5 and client-6 are currently subscribed to the “article. Redis” channel
Subscribe to the channel
Related commands:
The SUBSCRIBE channel [channel]...Copy the code
When a client executes a SUBSCRIBE command to SUBSCRIBE to a channel or channels, the client establishes a subscription relationship with the channel to which it is subscribed.
There are two ways to establish a subscription relationship:
1) The channel already has other subscribers
There is a linked list of subscribers in pubsub_Channels dictionary for this channel. You can add this client to the end of the linked list of subscribers.
2) This channel has no subscribers
The channel does not have a list of subscribers in the Pubsub_Channels dictionary. First, a key is created for the channel in the dictionary and the value of this key is set to an empty list, then the client is added to the list as the first element of the list.
Examples:
Client client-10086 Run the following command:
SUBSCRIBE "article.mysql" "article.java"
Copy the code
Pubsub_channels dictionary: SUBSCRIBE
Unsubscribe channel
Related commands:
UNSUBSCRIBE channel [channel]...Copy the code
When a client unsubscribes to a channel or channels, the server disassociates the client from the unsubscribing channel from pubsub_channels.
Unsubscribe execution process:
1) According to the name of the unsubscribed channel, find the linked list of subscribers corresponding to the channel in pubsub_Channels dictionary, and delete the unsubscribed client from the linked list of subscribers;
2) If the subscriber list of a channel becomes an empty linked list after deleting the unsubscribe client, then there are no subscribers left for this channel. The key corresponding to the channel will be deleted from the Pubsub_Channels dictionary.
Examples:
Client client-10086 Run the following command:
UNSUBSCRIBE "article.mysql" "article.java" "article.a"
Copy the code
Pubsub_channels dictionary: SUBSCRIBE
We notice that although “article. A “is included in the unsubscribe channel, it is ignored because “article. A” does not exist in pubsub_Channels dictionary.
Publish subscriptions to patterns
The difference between mode and channel, simple understanding mode is a combination of multiple channels.
Realize the principle of
Redis stores all Pattern subscriptions in the server state’s PubSub_Patterns list. Each node in the list contains a Pubsub Pattern structure whose Pattern attribute records the subscribed Pattern. The client property records the client in subscription mode.
struct redisServer{ //... Dict *pubsub_patterns; // Save all schema subscriptions. / /... }Copy the code
An example of a pubsub_Patterns chain:
-
Client -7 is subscribing to “book.*”
-
Client client-8 is subscribing to “column.*”
A subscription model
Related commands:
PSUBSCRIBE pattern [] the pattern...Copy the code
When a client executes the PSUBSCRIBE command to subscribe to one or more patterns, the server performs two operations for each subscribed pattern:
1) Create a pubsubPattern result, set the pattern attribute of the structure to the subscribed pattern, and set the client attribute to the subscribed client;
2) Add the pubsubPattern structure to the end of the pubsub_Patterns list.
Examples:
Client client-9 Run the following command:
PSUBSCRIBE "article.*"
Copy the code
Pubsub_patterns after executing the PSUBSCRIBE command:
Unsubscribe mode
Related commands:
PUNSUBSCRIBE pattern [] the pattern...Copy the code
When a client unsubscribes a pattern or patterns, the server looks up and deletes those pattern attributes from the PUBsub_Patterns list as the unsubscribing pattern, and the client attribute is the pubsubPattern structure of the client executing the unsubscribe command.
A simple understanding is: search for and delete the pubsubPattern with the same client and pattern.
Examples:
Client client-9 Run the following command:
PUNSUBSCRIBE "article.*"
Copy the code
Pubsub_patterns after executing the PUNSUBSCRIBE command:
Send a message
Related commands:
PUBLISH <channel> <message>
Copy the code
The message Message is sent to all subscribers of a channel channel, as well as to subscribers that match the pattern of the channel channel.
Sending messages Execution process:
1) Find the subscriber list of channel in the pubsub_Channels dictionary and send the message to all clients on the list;
2) Iterate through the pubsub_Patterns list to find patterns that match channel channels and send messages to clients that subscribe to these patterns.
Examples:
The current state of pubsub_channels dictionary is as follows:
The current state of the PUBSub_Patterns list is as follows:
In this case, a client runs the following command:
PUBLISH "article.redis" "hello"
Copy the code
Sending messages Execution process:
-
PUBLISH first sends the message “hello” to all subscribers of the “Articleredis” channel (client-5, client-6);
-
It then looks in the pubsub_Patterns list to see if any subscribed patterns match the “article.redis” channel, randomly finds the “article.*” pattern, and sends a message “hello” to client-9.
Publish and subscribe principle summary
The principle of publish and subscribe is summarized as follows:
-
The pubsub_channels dictionary stores the subscription relationships of all channels: the SUBSCRIBE command associates the client with the dictionary, while the UNSUBSCRIBE command unassociates the client with the unsubscribed channel.
-
The pubsub_Patterns list holds subscriptions for all patterns: the PSUBSCRIBE command records clients and subscribed patterns to the list, while the PUNSUBSCRIBE command removes clients and unsubscribed patterns from the list.
-
PUBLISH sends messages to all subscribers of a channel by accessing the Pubsub_Channels dictionary, and to all subscribers of a pattern matching a channel by accessing the pubsub_Patterns linked list.
Practical application case experience sharing
Background description
Let’s take the information subscription and distribution website as an example, and assume that the article structure is as follows:
Each chat is equivalent to a “channel”, and the classification of front-end, back-end, and test can be understood as a combination of a class of channels, which is called a “mode”.
Data profiling
If the user subscribes to chat (channel) and category (mode) :
-
User A has reserved channel chat-1
-
User B subscribes channel CHat-16 and mode “back end”
-
User C has subscribed to mode “front-end” and channel chat-101
The subscription relationship between channels and modes is shown below:
Redis records the data format of published subscription channels as follows:
Redis records the publish and subscribe mode in the following data format:
To perform operation
In this case, a client runs the following command:
PUBLISH "chat-1" "hello"
Copy the code
The execution process is as follows:
-
PUBLISH first sends the message “hello” to all subscribers of the “chat-1” channel, user A;
-
It then looks in the pubsub_Patterns list to see if any subscribed patterns match the “chat-1” channel, randomly finds a “front” pattern, and sends a message “hello” to user C.
Other message sending execution processes, subscriptions and message sending are the same as the above scenario, you can try to analyze their own.
Ability to apply
Redis has a wide range of application scenarios. Similar to weibo/wechat public account, Redis can also be used as a real-time message system (similar to chat/group chat ability support).
Using Redis publishing subscription can quickly achieve user subscription/attention relationship maintenance and subsequent message push ability, this article from the concept to the principle analysis, and then to specific case application explanation, is to take everyone familiar with the Redis publishing subscription picture, I hope to help you in the future work, thank you.
– END –
Author: The road to architecture Improvement, ten years of research and development road, Dachang architect, CSDN blog expert, focus on architecture technology precipitation learning and sharing, career and cognitive upgrade, adhere to share practical articles, looking forward to growing with you. Attention and private message I reply “01”, send you a programmer growth advanced gift package, welcome to hook up.
Thanks for reading!