In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-29 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Database >
Share
Shulou(Shulou.com)05/31 Report--
This article mainly introduces the advanced features of redis, which can be used for reference. I hope you can learn a lot after reading this article. Let's take a look at it.
Redis (Remote Dictionary Server), the remote dictionary service, is an open source API that is written in ANSI C language, supports the network, can be memory-based and persistent, and provides multiple languages.
1.redis publish and subscribe model
In addition to providing a message queuing mode like list's, Redis also provides a set of commands to implement the publish / subscribe mode. For example, Weibo, official account and so on can be realized from this.
1.2 subscribe to channels
The publisher needs to send the message to a place where subscribers can subscribe to the message, which is the channel. Subscribers can subscribe to one or more channels, and all subscribers who subscribe to this channel will receive this message.
Open two clients for testing
Client 1 subscribes to channel1127.0.0.1:6379 > subscribe channel1Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "channel1" 3) (integer) 1 client 2 publishes a message 127.0.0.1 publish channel1 test 6379 > publish channel1 test (integer) 1 client 1 subscribes message 127.0.0.1 channel1 6379 > subscribe channel1Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "channel1" 3) (integer) 11) "message" 2) "channel1" 3) "test"
1.2 subscribe by rules
Support? And * placeholders. ? Represents one character, and * represents 0 or more characters.
Start four redis-cli, one as the publisher of the message and the other three as subscribers.
Subscriber 1: subscribe to sports related
Psubscribe * sport
Subscriber 2: subscribe to news related
Psubscribe news*
Subscriber 3: subscribe to weather-related
Psubscribe new weather*
Published by:
Publish news-sport Kobepublish news-music jaychoupublish news-weather rain
At this point, subscriber 1 will receive Kobe, subscriber 2 will receive all messages, and subscriber 3 will receive rain.
2.redis transaction
2.1 Why do you use transactions
We all know that a single command of redis is atomic, but if you need multiple commands as an indivisible sequence of operations, you need to use transactions.
For example, when we use setnx to implement distributed locks, we usually set first, and then set expire to key to prevent the lock from being released when an exception occurs in del. After business processing, we want to perform these three operations as a set of commands in del.
Redis transactions have two characteristics:
Execute in the order in which you entered the queue
Will not be affected by other client requests
Redis's transaction design has four commands: multi (start transaction), exec (execute transaction), dicard (cancel transaction), watch (monitor)
2.2 usage of transactions
Transfer scenario An and B each have 100 yuan, A to B transfer 10 yuan, A minus 10 yuan, B plus 10 yuan
127.0.0.1 set 100OK127.0.0.1:6379 > set B 100OK127.0.0.1:6379 > multiOK127.0.0.1:6379 > decrby A 10QUEUED127.0.0.1:6379 > incrby B 10QUEUED127.0.0.1:6379 > exec1) (integer) 902) (integer) 110127.0.1 integer 6379 > get A "90" 127.0.1v 6379 > get B "110"
Start the transaction with the multi command. Transactions cannot be nested, and multiple multi commands have the same effect
After opening a transaction using multi, the client sends multiple commands to the server, which are not executed immediately, but are placed in a queue, and the commands in the queue are executed only after the exec command is invoked.
We can use discard to clear the transaction queue.
127.0.0.1 1QUEUED127.0.0.1:6379 > multiOK127.0.0.1:6379 > set K1 1QUEUED127.0.0.1:6379 > set K2 2QUEUED127.0.0.1:6379 > discardOK127.0.0.1:6379 > get K1 (nil) 127.0.0.1 1QUEUED127.0.0.1:6379 6379 > get K2 (nil)
Will it be rolled back when there is a problem when we execute the transaction?
An error occurred before exec (such as instruction syntax error)
127.0.1 clear127.0.0.1:6379 > multiOK127.0.0.1:6379 > set name testQUEUED127.0.0.1:6379 > hset user lisi (error) ERR wrong number of arguments for 'hset' command127.0.0.1:6379 > exec (error) EXECABORT Transaction discarded because of previous errors.127.0.0.1:6379 > get name (nil)
An error occurs after exec (using commands of different data types for the same key)
127.0.1 bQUEUED127.0.0.1:6379 6379 > multiOK127.0.0.1:6379 > set K1 1QUEUED127.0.0.1:6379 > hset K1 a bQUEUED127.0.0.1:6379 > exec1) OK2) (error) WRONGTYPE Operation against a key holding the wrong kind of value127.0.0.1:6379 > get K1 "1"
From the above, we know that when an error occurs before the exec, all operations will be rolled back; if an error occurs after the exec, only the wrong command will not be executed.
Why didn't redis roll back if there was an error in a transaction?
We can see from the above operation that redis rolls back only when the instruction syntax is wrong, and the instruction operation error is caused by the developer bug. For example, if you do + 1 on an int type and then accidentally + 2, or on a string type + 1, rollback is not applicable.
2.3 watch instruction
It can provide CAS optimistic locking for Redis transactions, that is, when multiple threads update a variable, the old value is compared to the memory address, and if equal, it is updated to the new value.
We can use watch to monitor one or more key, and if at least one monitored key is modified before exec execution after the transaction is started, the entire transaction will be canceled.
First, client 1 executes watch to monitor the key of money, and starts the transaction to add 100th to money.
127.0.1 multiOK127.0.0.1:6379 6379 > set money 1000OK127.0.0.1:6379 > watch moneyOK127.0.0.1:6379 > multiOK127.0.0.1:6379 > incrby money 100QUEUED
Reduce money by 100 at client 2 before the end of the transaction
127.0.0.1 decrby money 6379 > 100 (integer) 900
At this time, when client 1 ends the transaction, the value of money is not increased, but decreased, indicating that the modification of the transaction is invalid.
127.0.0.1 get money 6379 > exec (nil) 127.0.0.1 VR 6379 > get money "900"
3. Lua script
Lua scripting is a lightweight scripting language written in C, somewhat similar to stored procedures. Why use lua scripts?
Sending multiple commands at a time reduces network overhead. Redis executes the script as a whole, ensuring atomicity (transactions can be replaced in this way) script reuse, making it easy for multiple clients to complete the same logic.
3.1 use
We can use the following command to invoke the lua script
Eval script numkeys [key1 key2 key3....] [arg1 arg2 arg3....]
Eval executes lua script
Script represents the content of the lua script
Number of numkeys key
[key1 key2 key3....] The key name parameters, which represent the Redis keys (key) used in the script, can be accessed in the form of 1 as the base address through the global variable KEYS array in Lua (KEYS [1], KEYS [2], and so on).
[arg1 arg2 arg3....] Global variables, which can be accessed in Lua through an array of global variables ARGV, in a form similar to KEYS variables (ARGV [1], ARGV [2], and so on)
Let's take a simple example.
127.0.0.1 ARGV 6379 > eval "return {KEYS [1], ARGV [1], KEYS [2], ARGV [2]}" 2 key1 key2 val1 val11) "key1" 2) "val1" 3) "key2" 4) "val1" 127.0.0.1 eval "return {KEYS [1], KEYS [2], ARGV [1], ARGV [2]}" 2 key1 key2 val1 val11) "key1" 2) "key2" 3) "val1" 4) "val1"
How do you call redis commands in lua scripts?
We can use redis.call (command, key [param1, param2...]) Carry out operation
Commond redis commands, such as set,get and other key keys to be operated [param1, param2...] Parameters represented to key
127.0.1 eval redis.call ('mset',KEYS [1], ARGV [1], KEYS [2], ARGV [2]) "2 name age lisi 18 (nil) 127.0.0.1 mset',KEYS 6379 > mget name age1)" lisi "2) 18
The above command is equivalent to mset name lisi age 18, and the number of key is 2. The last two values are key, followed by args.
It is not convenient to write a lua script directly in redis-cli. Usually we put the script in a file and then execute this file.
We create a new test.lua script in a directory, fill in the following and execute it.
Root@VM-0-5-centos src] # mkdir testlua [root @ VM-0-5-centos src] # cd testlua/ [root @ VM-0-5-centos testlua] # lltotal 0 [root@VM-0-5-centos testlua] # touch test.lua [root @ VM-0-5-centos testlua] # vim test.luaredis.call ('set',KEYS [1], ARGV [1]) return redis.call (' get' KEYS [1]) [root@VM-0-5-centos testlua] # redis-cli-- eval test.lua 1 myname, Armin "Armin"
It is worth noting that spaces (myname, Armin) need to be added between key and arg.
3.2 caching lua scripts
The reason why the lua script needs to be cached is that the entire script is passed to the redis server each time it is called, which results in a large network overhead. To solve this problem, Redis provides evalsha commands that allow developers to execute scripts through a SHA1 summary of the contents of the script.
So how to generate this SHA1 and load the script content into the cache? use the script load command to calculate the SHA1 summary of the script and record the script into the cache. When executing evalsha, redis will go to the script cache to find the corresponding script content according to the summary provided, and execute it if it is found, otherwise an error prompt will be returned: "NOSCRIPT No matching script. Please use EVAL"
127.0.0.1 Hey boy' 6379 > script load "return 'Hey boy'"3760855b303510c83f0be2e8acfb0be64113ae6e" 127.0.0.1 evalsha 3760855b303510c83f0be2e8acfb0be64113ae6e 0 "Hey boy" 127.0.0.1 Hey boy' 6379 > script exists 3760855b303510c83f0be2e8acfb0be64113ae6e / / determine whether there is 1) (integer)
Redis also provides timeout for the execution of lua scripts. The default timeout is 5s. After 5s, redis will accept other commands but return a "BUSY" error.
You can modify the specified parameters in redis.conf
Lua-time-limit 5000
Redis provides a script kill command to terminate the running script
127.0.0.1 BUSY Redis is busy running a script 6379 > set name lisi (error). You can only call SCRIPT KILL or SHUTDOWN NOSAVE.127.0.0.1:6379 > script killOK127.0.0.1:6379 > set name lisiOK
If the data is modified, you cannot use script kill to terminate the script because it violates atomicity. At this point, redis can only be forcibly terminated through shutdown nosave.
The difference between shutdown nosave and shutdown is that shutdown nosave does not persist, which means that database changes that occurred after the last snapshot will be lost.
Thank you for reading this article carefully. I hope the article "what are the advanced features of redis" shared by the editor will be helpful to you. At the same time, I also hope you will support us and pay attention to the industry information channel. More related knowledge is waiting for you to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.