Publish and subscribe P52

Redis Publish and subscribe are realized (publish/subscribe) Pattern , also called pub/sub Pattern ( Similar to the observer pattern in design patterns ). Subscribers are responsible for subscribing to the channel , The sender is responsible for sending binary string messages to the channel . Whenever a message is sent to a given channel , All subscribers to the channel receive messages .

Publish and subscribe commands P52
command Format describe
SUBSCRIBE SUBSCRIBE channel [channel ...] Subscribe to one or more channels
UNSUBSCRIBE UNSUBSCRIBE [channel [channel ...]] Unsubscribe from one or more channels ; No channel specified , Unsubscribe from all channels
PUBLISH PUBLISH channel message Send a message to a specified channel , Returns the number of subscribers who received the message
PSUBSCRIBE PSUBSCRIBE pattern [pattern ...] Subscribe to one or more patterns , Channels that match the pattern will subscribe to
PUNSUBSCRIBE PUNSUBSCRIBE [pattern [pattern ...]] Unsubscribe from one or more modes ; No mode specified , Unsubscribe from all modes

The relevant demo code is as follows :

// Perform publish subscribe related operations ( Be careful :pubSubConn Medium Conn The object cannot be conn object , That is, two different connections have to be made )
func executePubSubOperation(pubSubConn redis.PubSubConn, conn redis.Conn) {
// Listen for channel messages and output
go func() {
for ; ; {
switch result := pubSubConn.Receive().(type) {
case redis.Message:
// byte turn string
resultMap := map[string]string {
"Channel": result.Channel,
"Pattern": result.Pattern,
"Data": string(result.Data),
}
handleResult(resultMap, nil)
case redis.Subscription:
handleResult(result, nil)
} }
}() // Subscribe to two channels ( because Subscribe There's no execution in Receive, So only error, Output when there are no errors nil)
// The subscriber receives the corresponding message subscription information , Output, respectively, -> {subscribe channel_1 1} and {subscribe channel_2 2}
handleResult(nil, pubSubConn.Subscribe("channel_1", "channel_2"))
// Subscribe to two modes , Respectively by _1 and g_2 For the end of the channel ( because PSubscribe There's no execution in Receive, So only error, Output when there are no errors nil)
// The subscriber receives the corresponding message subscription information , Output, respectively, -> {psubscribe *_1 3} and {psubscribe *g_2 4}
handleResult(nil, pubSubConn.PSubscribe("*_1", "*g_2")) time.Sleep(time.Second) // Release the news to the channel channel_1, Output -> 2, Two subscribers received a message
// Subscribers output -> map[Channel:channel_1 Data:channel1 Pattern:] and map[Channel:channel_1 Data:channel1 Pattern:*_1]
handleResult(conn.Do("PUBLISH", "channel_1", "channel1"))
// Release the news to the channel channel_2, Output -> 1, A subscriber receives a message
// Subscriber output -> map[Channel:channel_2 Data:channel1 Pattern:]
handleResult(conn.Do("PUBLISH", "channel_2", "channel1")) // Unsubscribe from two channels ( because Subscribe There's no execution in Receive, So only error, Output when there are no errors nil)
// The subscriber receives the corresponding message to unsubscribe , Output, respectively, -> {unsubscribe channel_1 3} and {unsubscribe channel_2 2}
handleResult(nil, pubSubConn.Unsubscribe("channel_1", "channel_2"))
// Unsubscribe from two channels ( because Subscribe There's no execution in Receive, So only error, Output when there are no errors nil)
// The subscriber receives the corresponding message to unsubscribe , Output, respectively, -> {punsubscribe *_1 1} and {punsubscribe *g_2 0}
handleResult(nil, pubSubConn.PUnsubscribe("*_1", "*g_2")) time.Sleep(time.Second)
}
risk P54
  • stability : Old edition Redis When the client reading the message is not fast enough , A constant backlog of information will make Redis The buffer is getting bigger and bigger , May lead to Redis It's slowing down , Even the immediate collapse , There are also reasons for Redis Could be killed by the operating system . new edition Redis It will automatically disconnect the inconformity client-output-buffer-limit pubsub Configure the client required by the option .
  • reliability : Any network system in the execution of the operation may encounter disconnection , The connection error caused by disconnection usually causes one end of the network connection to be reconnected . If the client is disconnected during the subscription operation , Then the client will lose all messages sent during disconnection .

Sort P54

SORT Commands can be used on lists 、 Set and ordered set sort , Can be SORT Command is seen as making SQL Medium order by Clause . P55

command Format describe
SORT SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC|DESC] [ALPHA] [STORE destination] According to the given options , Returns or saves the given list 、 aggregate 、 Ordered set key The ordered elements in

Can realize the function : P55

  • Sort elements in ascending or descending order ( Use [ASC|DESC], The default is ascending )
  • Sort elements as numbers or strings ( Use [ALPHA] Sort as a string , The default is number )
  • Use values other than the sorted elements as weights to sort , Even from the list of inputs 、 aggregate 、 Values are taken from places other than the ordered set ( Use [BY pattern] You can sort by a specified value ; You can use nonexistent keys as parameter options to skip sorting without directly returning results )
  • Use a value other than the sorted element as the return result ( Use [GET pattern [GET pattern ...]] The corresponding value can be returned according to the sorting result )
  • Save sorting results ( Use [STORE destination] You can specify that the results be saved to the specified key, The number of saved elements is returned )
  • Limit return results ( Use [LIMIT offset count] You can specify the number of elements to skip and the number of elements to return )

The relevant demo code is as follows :

// perform SORT command 
func executeSortOperation(conn redis.Conn) {
// Delete the original value
handleResult(redis.Int(conn.Do("DEL", "id", "age", "name", "destination")))
// initialization
handleResult(redis.Int(conn.Do("RPUSH", "id", 1, 4, 3, 2, 5)))
handleResult(redis.String(conn.Do("SET", "age_1", 15)))
handleResult(redis.String(conn.Do("SET", "age_2", 14)))
handleResult(redis.String(conn.Do("SET", "age_3", 11)))
handleResult(redis.String(conn.Do("SET", "age_4", 12)))
handleResult(redis.String(conn.Do("SET", "age_5", 10)))
handleResult(redis.String(conn.Do("SET", "name_1", "tom")))
handleResult(redis.String(conn.Do("SET", "name_2", "jerry")))
handleResult(redis.String(conn.Do("SET", "name_3", "bob")))
handleResult(redis.String(conn.Do("SET", "name_4", "mary")))
handleResult(redis.String(conn.Do("SET", "name_5", "jack"))) // according to id null , Skip the first element , Get the next two elements , Output -> [4 3]
handleResult(redis.Ints(conn.Do("SORT", "id", "LIMIT", "1", "2", "DESC")))
// according to age_{id} Ascending sort , according to id age_{id} name_{id} Return results in sequence , Output -> [5 10 jack 3 11 bob 4 12 mary 2 14 jerry 1 15 tom]
handleResult(redis.Strings(conn.Do("SORT", "id", "BY", "age_*", "GET", "#", "GET", "age_*", "GET", "name_*", "ALPHA")))
// according to name_{id} Dictionary order descending order , according to id age_{id} name_{id} Return results in sequence , Store in destination in
// Output -> 15
handleResult(redis.Int(conn.Do("SORT", "id", "BY", "name_*", "GET", "#", "GET", "age_*", "GET", "name_*", "ALPHA", "DESC", "STORE", "destination")))
// Output list result , Output -> [1 15 tom 4 12 mary 2 14 jerry 5 10 jack 3 11 bob]
handleResult(redis.Strings(conn.Do("LRANGE", "destination", 0, -1)))
}

Basic Redis Business

Redis Yes 5 A command allows the user to perform operations on multiple keys without being interrupted , They are : WATCHMULTIEXECUNWATCH and DISCART . Basic Redis Business only uses MULTI and EXEC that will do , Transactions that use multiple commands will be described later . P56

Redis The basic transaction allows a client to execute multiple commands without being interrupted by other clients . When a transaction is completed , Redis Will handle commands from other clients . P56

If a certain ( Or something ) key Is in WATCH Under the watch of orders , And the transaction block has and this ( Or these ) key Related commands , that EXEC The order is only in this ( Or these ) key It is executed and effective without being changed by other orders , Otherwise, the transaction is interrupted (abort).

command Format describe
MULTI MULTI Mark the beginning of a transaction block , Always returns OK
EXEC EXEC Execute commands within all transaction blocks , Returns the execution result of the command in order . When the operation is interrupted , return nil

The relevant demo code is as follows :

// Execute the transaction command 
func executeTransactionOperation(conn redis.Conn) {
// Delete the original value
handleResult(redis.Int(conn.Do("DEL", "counter")))
// Open transaction ( It's pipelined , Reduce communication overhead )
handleResult(nil, conn.Send("MULTI"))
// Self incrementing operations are performed in transactions ( It's pipelined , Reduce communication overhead )
handleResult(nil, conn.Send("INCR", "counter"))
handleResult(nil, conn.Send("INCR", "counter"))
handleResult(nil, conn.Send("INCR", "counter"))
// Carry out orders , Perform the auto increment operation in turn , Return the operation results respectively , Output -> [1 2 3]
handleResult(redis.Ints(conn.Do("EXEC")))
}
Exercises : Remove competitive conditions P58

Simple practice - Article voting in VoteArticle There is no transaction control in the function , There will be concurrency problems . This function contains a competition condition and a result of the competition condition bug . Competing conditions for functions can cause memory leaks , And the bug It may lead to incorrect voting results . Can you find a way to fix them ?

Tips : If you find it hard to understand why race conditions lead to memory leaks , Then we can analyze Simple practice - Article voting Medium PostArticle At the same time , Read it. 6.2.5 section .

  • I still can't understand why there is such a situation , Force a guess at the following possibilities ( Although it's not caused by competitive conditions ):

    • PostArticle Function , After adding authors to the voting user collection , Set an expiration date for it . If there is no relevant operation due to some original exception before the expiration time is set , So this set will always be in memory , It doesn't expire , This causes memory leaks .
    • VoteArticle Function , If the voting user is added to the voting user collection , I haven't had time to set up the relevant information of the article , Then this user can't vote any more , And the voting information of the article is wrong .
  • I don't quite understand what the competition is , We can only deal with the above problems . Only one more set can be added with a transaction to mark whether the transaction is executed successfully , The processing flow is as follows :

    1. First add users and articles to this collection as values
    2. Add users to the voting set
    3. Then start the transaction , Send the command to update the information and delete the related information in that collection in turn , And implement
    4. Finally, there is one worker Scan this collection , Take out the values and analyze the users and articles , Check whether the user is in the collection , If in a set , Then execute again step 3, Finally, delete the value
Exercises : Improve performance P58

Simple practice - Article voting in ListArticles Function to get the entire page of the article , Need to be in Redis There will be at most 26 This is a round trip , It's very inefficient , Can you think of a way to ListArticles The number of round trips to the function is reduced to 2 And then ?

Tips : Use assembly line

  • When getting the list of articles , First get the corresponding id list ( most 25 individual ), Recycle to get every id The corresponding article , So at most 26 This is a round trip
  • Because you have to get id list , And then get each id The corresponding article , So we can only separate the two pieces , So at least 2 This is a round trip . The general flow is as follows :
    1. First get id list
    2. Use assembly line , In turn, each id The command for the article is sent to the buffer , Finally, communicate with the server and execute the command (Go You can use the above transaction demo code to operate )
    3. Finally, analyze the results in order

Expiration time P58

Only a few commands can atomically set the expiration time for a key , And for the list 、 aggregate 、 For containers like hash tables and ordered sets , The key expiration command can only set the expiration time for the entire key , There is no way to set the expiration time for a single element in the key ( You can use an ordered collection of stored timestamps to achieve expiration times for individual elements ; You can also change a single element in a container into a string in the form of a prefix ). P58

Used to process expiration time Redis command P59
command Format describe
PERSIST PERSIST key The expiration time of the remove key
TTL TTL key See how many seconds the key is away from the expiration time
EXPIRE EXPIRE key seconds Let the key expire after the specified number of seconds
EXPIREAT EXPIREAT key timestamp Let the key in the specified UNIX Second level timestamp expired
PTTL PTTL key See how many milliseconds the key has to go before it expires
PEXPIRE PEXPIRE key milliseconds Let the key expire after the specified number of milliseconds
PEXPIREAT PEXPIREAT key milliseconds-timestamp Let the key in the specified UNIX Millisecond timestamps expired

The relevant demo code is as follows :

// Specify the expiration time related commands 
func executeExpirationOperation(conn redis.Conn) {
// Delete the original value
handleResult(redis.Int(conn.Do("DEL", "string")))
// Set the value of the string to value, Output -> OK,string Turn into -> value
handleResult(redis.String(conn.Do("SET", "string", "value")))
// see string The expiration time of , Output -> -1, No expiration date
handleResult(redis.Int(conn.Do("TTL", "string")))
// Set up string stay 3 Seconds after expired , Output -> 1
handleResult(redis.Int(conn.Do("EXPIRE", "string", 3)))
time.Sleep(time.Second)
// see string The expiration time of , Output -> 2
handleResult(redis.Int(conn.Do("TTL", "string")))
// remove string The expiration time of , Output -> 1
handleResult(redis.Int(conn.Do("PERSIST", "string")))
// see string The expiration time of , Output -> -1, No expiration date
handleResult(redis.Int(conn.Do("TTL", "string"))) // Set up string At the current time 2500 Expired in milliseconds , Output -> 1
handleResult(redis.Int(conn.Do("PEXPIREAT", "string", time.Now().UnixNano() / 1e6 + 2500)))
time.Sleep(time.Second)
// see string The expiration time of , Output -> 1499, It means that there is still 1499 Milliseconds expired
handleResult(redis.Int(conn.Do("PTTL", "string")))
time.Sleep(2 * time.Second)
// see string The expiration time of , Output -> -2, Indicates that it has expired
handleResult(redis.Int(conn.Do("PTTL", "string")))
}
Exercises : Use EXPIRE Command instead of timestamp ordered collection P59

stay Simple practice - Web application A sort by timestamp is used in 、 An ordered collection for clearing session information , Through this ordered set , The program can clean up the session , Analyze the products that users have browsed and the products in their shopping carts . however , If we decide not to analyze the goods , Then you can use it Redis Provides an expiration time operation to automatically clean up expired session information , Instead of using the cleanup function . that , Can you modify Simple practice - Web application As defined in UpdateToken Functions and UpdateCartItem function , Let them use the expiration time operation to delete session information , Instead of using ordered sets to record and clear session information ?

  • UpdateToken function : Token in userId Is not stored in the hash table , Instead, a single element in the container is changed into a string in the form of a prefix ( As mentioned above ), And set expiration time , And remove the most recent operation time ordered set , In this way, the token will be automatically deleted after expiration , There's no need to clean up functions .
  • UpdateCartItem function : Because at that time Redis Use as a database , The shopping cart should not disappear with the failure of login status , So shopping carts and userId hook , There is no such problem . But if you want the shopping cart to automatically expire , It needs to be in UpdateToken Function at the same time set the expiration time of the shopping cart .

This article was first published on the official account : Man Fu Zhu Ji ( Click to view the original ) Open source in GitHub :reading-notes/redis-in-action

Redis actual combat —— 05. Redis More related articles about other commands

  1. Redis The actual combat Redis + Jedis

    use Memcached, There are requirements for cache object size , A single object cannot be greater than 1MB, And does not support complex data types , for example SET etc. . Based on these limitations , It is necessary to consider Redis! Related links : Redis actual combat Redis The actual combat Redi ...

  2. Redis The actual combat Redis + Jedis[ turn ]

    http://blog.csdn.net/it_man/article/details/9730605 2013-08-03 11:01 1786 Human reading   Comment on (0)  Collection   report   Catalog (?)[-] ...

  3. Distributed cache technology redis Learning Series ( 5、 ... and )——redis actual combat (redis And spring Integrate , Distributed lock implementation )

    This article is about redis Learn the fifth part of the series , Click on the link below to go back to the series <redis Introduction and linux The installation of the > < Explain in detail redis data structure ( Memory model ) And common commands > <redi ...

  4. Distributed cache technology redis series ( 5、 ... and )——redis actual combat (redis And spring Integrate , Distributed lock implementation )

    This article is about redis Learn the fifth part of the series , Click on the link below to go back to the series <redis Introduction and linux The installation of the > < Explain in detail redis data structure ( Memory model ) And common commands > <redi ...

  5. Redis Practical summary -Redis High availability

    In previous blogs <Redis Practical summary - To configure . Persistence . Copy > Give a kind of Redis Master slave replication mechanism , Simply implemented Redis High availability . then , If Master Server down , Will lead to the whole Redis paralysis , In this way ...

  6. Redis The actual combat Redis command

    Read the directory 1. String command 2. List command 3. Assemble orders 4. Hash command 5. To assemble orders in order 6. Publish and subscribe commands 7. A profound Redis Can store keys and 5 Mapping between different types of data structures , this 5 It's a data node ...

  7. Linux+Redis Practical course _day01_ Common commands 【 a key 】

    3. Common commands [ a key ] Linux Parameters in the command , It's generally disordered . Except under special circumstances 3.1. Disk management commands ls command : List contents Parameters : -a Query all files and folders . Contains hidden -l Query detailed list     ls ...

  8. Redis actual combat ( One )Redis Introduction and environment installation (Windows)

    mention Redis, Everyone must have heard of , And should be more or less used in the project , Maybe you think Redis It's easy to use , But if someone asks you the following questions ( Like a colleague or an interviewer ), Can you answer me ? What is? Redis? R ...

  9. Redis actual combat

    About a year ago , Company colleagues began to use Redis, I don't know. It's configuration , It's still about the version , At that time Redis Often after a period of use , The connection is full and does not release . In my impression ,Redis 2.4.8 The following version is due to the synchronization problem of master-slave library , will ...

  10. Redis The actual battle of Conquest Redis + Jedis + Spring ( One )

    Redis + Jedis + Spring ( One )—— To configure & Normal operation (GET SET DEL) Then we need a quick survey based on Spring Under the framework of Redis operation . Related links : Redis actual combat Re ...

Random recommendation

  1. CentOS7 install mongoDB database

    CentOS7 install mongoDB database Time :2015-03-03 16:45 source :blog.csdn.net author : The puppet of attack report Click on :8795 Time mongoDB It's better developed at present NOSQL data ...

  2. Docker / CI / CD

    CI Weekly #6 | We can talk Docker / CI / CD practical experience   CI Weekly around 『 Improve the efficiency of software engineering 』 Share a series of technical content , Including continuous integration at home and abroad . Continuous delivery , Continuous deployment . Automatically ...

  3. understand hadoop

    <Hadoop Basic course > First knowledge Hadoop Blog classification : Journal entry   Hadoop It's always been a technology I want to learn , It happens that the project team is going to build an e-mall recently , I started to study Hadoop, Although the final identification Hadoop Not for me ...

  4. C# The recursive solution of the eight queens problem ——N Queen

    Baidu testing department 2015 year 10 One of the interview questions in this month —— Eight queens . Here is an introduction to the eight queens problem . The following is the realization of eight queens with recursive thinking -N Queen . The code is as follows : using System;using System.Collections. ...

  5. Qt And QHeaderView Custom sort ( Get the right QModelIndex)

    sketch In the previous sections, I've shared about the ability to customize sorting , It seems that our previous content can solve the sorting problem well , however , This will lead to some problems that are hard to find ... such as : obtain QModelIndex Index error . below , Let's start with a whole line ...

  6. Ubuntu12.04 + virtual machine VMware 9 + Secure CRT + EditPlus Local C++ Development environment construction

    1.1   Software preparation virtual machine VMware 9 Ubuntu 12.04 Secure CRT EditPlus 1.2   install VMware 9 And Ubuntu 12.04 These two software installations , Step by step , This is it ...

  7. hdu1569find the safest road(floyd The maximum safety value of deformation is calculated )

    find the safest road Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  8. jenkins pipline Send E-mail

    Recommend a good website https://www.w3cschool.cn/jenkins/jenkins-e7bo28ol.html obtain git User information // Get checkout output value ...

  9. Luogu .3834.[ Templates ] Persistent line tree ( Chairman tree Static interval No k Small )

    Topic link // After discretization, the range 1~cnt Don't be wrong #include<cstdio> #include<cctype> #include<algorithm> //#def ...

  10. Robot Operating System (ROS) Learning notes 3--- Keyboard control

    Set up the environment :XMWare  Ubuntu14.04  ROS(indigo) Reprinted from ancient Yueju   Reprint connection :http://www.guyuehome.com/253 One . Create control packages catkin_creat ...