Redis actual combat - 05. Brief introduction of redis's other commands

Man Fu Zhu Ji 2021-01-24 11:14:33
redis actual combat brief introduction


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

版权声明
本文为[Man Fu Zhu Ji]所创,转载请带上原文链接,感谢
https://javamana.com/2021/01/20210124111336498i.html

  1. 【计算机网络 12(1),尚学堂马士兵Java视频教程
  2. 【程序猿历程,史上最全的Java面试题集锦在这里
  3. 【程序猿历程(1),Javaweb视频教程百度云
  4. Notes on MySQL 45 lectures (1-7)
  5. [computer network 12 (1), Shang Xuetang Ma soldier java video tutorial
  6. The most complete collection of Java interview questions in history is here
  7. [process of program ape (1), JavaWeb video tutorial, baidu cloud
  8. Notes on MySQL 45 lectures (1-7)
  9. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  10. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  11. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  12. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  13. 【递归,Java传智播客笔记
  14. [recursion, Java intelligence podcast notes
  15. [adhere to painting for 386 days] the beginning of spring of 24 solar terms
  16. K8S系列第八篇(Service、EndPoints以及高可用kubeadm部署)
  17. K8s Series Part 8 (service, endpoints and high availability kubeadm deployment)
  18. 【重识 HTML (3),350道Java面试真题分享
  19. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  20. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  21. [re recognize HTML (3) and share 350 real Java interview questions
  22. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  23. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  24. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  25. RPC 1: how to develop RPC framework from scratch
  26. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  27. RPC 1: how to develop RPC framework from scratch
  28. 一次性捋清楚吧,对乱糟糟的,Spring事务扩展机制
  29. 一文彻底弄懂如何选择抽象类还是接口,连续四年百度Java岗必问面试题
  30. Redis常用命令
  31. 一双拖鞋引发的血案,狂神说Java系列笔记
  32. 一、mysql基础安装
  33. 一位程序员的独白:尽管我一生坎坷,Java框架面试基础
  34. Clear it all at once. For the messy, spring transaction extension mechanism
  35. A thorough understanding of how to choose abstract classes or interfaces, baidu Java post must ask interview questions for four consecutive years
  36. Redis common commands
  37. A pair of slippers triggered the murder, crazy God said java series notes
  38. 1、 MySQL basic installation
  39. Monologue of a programmer: despite my ups and downs in my life, Java framework is the foundation of interview
  40. 【大厂面试】三面三问Spring循环依赖,请一定要把这篇看完(建议收藏)
  41. 一线互联网企业中,springboot入门项目
  42. 一篇文带你入门SSM框架Spring开发,帮你快速拿Offer
  43. 【面试资料】Java全集、微服务、大数据、数据结构与算法、机器学习知识最全总结,283页pdf
  44. 【leetcode刷题】24.数组中重复的数字——Java版
  45. 【leetcode刷题】23.对称二叉树——Java版
  46. 【leetcode刷题】22.二叉树的中序遍历——Java版
  47. 【leetcode刷题】21.三数之和——Java版
  48. 【leetcode刷题】20.最长回文子串——Java版
  49. 【leetcode刷题】19.回文链表——Java版
  50. 【leetcode刷题】18.反转链表——Java版
  51. 【leetcode刷题】17.相交链表——Java&python版
  52. 【leetcode刷题】16.环形链表——Java版
  53. 【leetcode刷题】15.汉明距离——Java版
  54. 【leetcode刷题】14.找到所有数组中消失的数字——Java版
  55. 【leetcode刷题】13.比特位计数——Java版
  56. oracle控制用户权限命令
  57. 三年Java开发,继阿里,鲁班二期Java架构师
  58. Oracle必须要启动的服务
  59. 万字长文!深入剖析HashMap,Java基础笔试题大全带答案
  60. 一问Kafka就心慌?我却凭着这份,图灵学院vip课程百度云