table of Contents
1. Introduction to Pipelin Mode
2. The transaction is abnormal
Three, redis publish and subscribe
1. Redis publish and subscribe common commands
3. Comparison of scan and keys
In the introduction chapter of redis , I have introduced you to the basic operating instructions of redis. Today, I will introduce you to the advanced operations of redis, and how do we use commands that are not packaged in toolkits such as jedis and redisTemplate? I believe you will have a deeper understanding of the overall redis after reading this article.
1. Introduction to Pipelin Mode
1. The usual usage of redis
In most cases, we will operate redis through the request-response mechanism. The steps to use this mode are
- Get jedis instance
- Send redis command
- Since redis is single-threaded, the command will not be executed until the last command is processed.
The entire interaction process is as follows
2. Pipeline mode
However, using the Pipeline mode, the client can send multiple commands at once without waiting for the server to return. This greatly reduces the network round-trip time and improves system performance.
The pipeline is a combination of multiple commands. Using PIPELINE can solve the problem of network overhead. The principle is also very simple. The process is as follows. After multiple commands are packaged, they are submitted to Redis at one time, and network communication is only once.
3. Performance comparison
The internet |
delay |
非Pipeline |
Pipeline |
Native |
1300 |
1414 |
114 |
Intranet server |
1222ms |
1532ms |
310ms |
Remote computer room |
90910ms |
92 000ms |
1090ms |
It can be seen that the delay of redis mainly occurs in the number of IOs requested by the network , so when we use redis, we try to reduce the number of network IOs as much as possible, and encapsulate multiple instructions into one command for execution through pipeline.
Two, Redis things
The simple transaction of redis is to put a group of commands that need to be executed together between the two commands multi and exec, where multi represents the beginning of the transaction, and exec represents the end of the transaction
1. Transaction order
multi: transaction start
exec: commit transaction
watch: transaction monitoring
The WATCH command can monitor one or more keys. Once one of the keys is modified (or deleted), subsequent transactions will not be executed. The monitoring continues until
discard: stop the transaction
Execute the command before executing exec, the commit transaction will fail, and the executed command will be rolled back
127.0.0.1:6379> multi //开始事务
OK
127.0.0.1:6379> sadd tt 1 //业务操作
QUEUED
127.0.0.1:6379> DISCARD //停止事务
OK
127.0.0.1:6379> exec //提交事务
(error) ERR EXEC without MULTI //报不存在事务异常
127.0.0.1:6379> get tt //获取不到对象
(nil)
127.0.0.1:6379>
2. The transaction is abnormal
Redis supports transactions, but it is a weak transaction, and some exceptions in the middle may cause the transaction to fail.
1. The command is wrong, the syntax is incorrect, and the transaction cannot be ended normally
127.0.0.1:6379> multi //开始事务
OK
127.0.0.1:6379> set aa 123 //业务操作
QUEUED
127.0.0.1:6379> sett bb 124 //命令错误
(error) ERR unknown command 'sett'
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors. //提交事务异常
127.0.0.1:6379> get aa //查询不到数据
(nil)
127.0.0.1:6379>
2. The operation is wrong, the syntax is correct, but the type is wrong, the transaction can be ended normally
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set t 1 //业务操作1
QUEUED
127.0.0.1:6379> sadd t 1 //业务操作2
QUEUED
127.0.0.1:6379> set t 2 //业务操作3
QUEUED
127.0.0.1:6379> exec
1) OK
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value //类型异常
3) OK
127.0.0.1:6379> get t //可以获取到t
"2"
127.0.0.1:6379>
Three, redis publish and subscribe
Redis provides a "publish, subscribe" message mechanism, in which message subscribers and publishers do not communicate directly, the publisher publishes messages to a specified channel, and each client subscribing to the channel can receive the message
1. Redis publish and subscribe common commands
command | meaning |
publish channel | release the news |
subscribe channel | Subscribe to news |
pubsub numsub channel | View the number of subscriptions |
unsubscribe channel | unsubscribe |
psubscribe ch* | Subscribe and unsubscribe by mode |
2. Performance test
See my other blog post : redis publish and subscribe performance test
3. Application scenarios
Redis mainly provides publishing messages, subscribing to channels, unsubscribing and subscribing and unsubscribing according to the model, and many professional message queues (kafka rabbitmq). Redis publish and subscribe is very low, for example, message procedures and backtracking cannot be achieved, but it is simple. If you can meet the application scenario, you can also use this
- Subscription account, official account, Weibo follower, email subscription system, etc.
- Even if the communication system
- Group chat tribe system (WeChat group)
Fourth, the key migration
You may not use a lot of key migration, because redis master-slave synchronization is generally used. But when we do statistical analysis of data, we may use it, such as user tags. In order to avoid the redis avalanche caused by the batch deletion of keys, it is generally through a redis used for calculation and a redis used by the final business, and the key values in the redis used in the calculation are updated one by one to the business redis through migration. , To minimize the impact on the business.
1、move
The move instruction migrates the data in one redis library to another library.
move key db //reids有16个库, 编号为0-15
set name DK; move name 5 //迁移到第6个库
elect 5 ;//数据库切换到第6个库,
get name 可以取到james1
If the key already exists in the target database, nothing will happen. This mode is not recommended to be used in a production environment, it can be played in the same reids
2、dump
The Redis DUMP command is used to serialize the key and return the serialized value. Used to import into other services
It is generally exported through the dump command and imported using the restore command.
1, on server A
set name james;
dump name; // 得到"\x00\x05james\b\x001\x82;f\"DhJ"
2, on the B server
restore name 0 "\x00\x05james\b\x001\x82;f\"DhJ" //0代表没有过期时间
get name //返回james
3、migrate
Migrate is used to migrate data between Redis instances. In fact, the migrate command combines the three commands dump, restore, and del to simplify the operation process.
The migrate command is atomic, and the function of migrating multiple keys has been supported since Redis 3.0.6. The data transmission of the migrate command is directly completed on the source Redis and the target Redis. After the target Redis completes the restore, it will send OK to the source Redis.
migrate |
192.168.42.112 |
6379 |
name |
0 |
1000 |
copy |
replace |
instruction |
Destination IP to be migrated |
port |
Migrate key value |
Target library |
overtime time |
Don't delete the original key after migration |
The migration is successful regardless of whether the target library does not have a test key |
For example: Migrate the name key value on 111 to redis on 112
192.168.42.111:6379> migrate 192.168.42.112 6379 name 0 1000 copy
Five, custom command package
When we use jedis or jdbctemplate, when we want to execute the key migration instruction, we find that the relevant instructions are not encapsulated for us at all. What should we do at this time? In addition to the way the framework helps us to encapsulate, we can also encapsulate commands by reflection. The main steps are as follows
- Establish Connection link, use Connection to connect to Redis
- Get the sendCommand method in Connection through reflection (protected Connection sendCommand(Command cmd, String... args)).
- Call the sendCommand method of the connection, the second parameter is the command to be executed (such as set, get, client, etc.), and the third parameter is the parameter of the command. You can see that the ProtocolCommand enumeration object contains all the instructions of redis, that is, all the instructions can be obtained through this object. And package execution
- Execute the invoke method and encapsulate the parameters according to the redis instructions
- Get Redis command execution result
package com.james.cache.jedis;
import redis.clients.jedis.Connection;
import redis.clients.jedis.Protocol;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @Auther: DK
* @Date: 2020/10/11 23:17
* @Description:
*/
public class RedisKeyMove {
public static void main(String[] args) throws IOException {
//1.使用Connection连接Redis
try (Connection connection = new Connection("10.1.253.188", 6379)) {
// 2. 通过反射获取Connection中的sendCommand方法(protected Connection sendCommand(Command cmd, String... args))。
Method method = Connection.class.getDeclaredMethod("sendCommand", Protocol.Command.class, String[].class);
method.setAccessible(true); // 设置可以访问private和protected方法
// 3. 调用connection的sendCommand方法,第二个参数为执行的命令(比如set,get,client等),第三个参数为命令的参数。
// 3.1 该命令最终对应redis中为: set test-key test-value
method.invoke(connection, Protocol.Command.MIGRATE,
new String[] {"10.1.253.69", "6379", "name", "0", "1000", "copy"});
// 4.获取Redis的命令执行结果
System.out.println(connection.getBulkReply());
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
Six, key full traversal
1、keys
instruction | meaning |
keys * | Return all keys, *match any character and multiple characters |
keys *y | Keys ending in |
keys n*e | Start with n and end with e, return name |
keys n?me | ? The question mark means that only one character is matched Return name, global match |
keys n?m* | Return name |
keys [j,l]* | Returns all keys starting with jl keys [j]ames matches james in full |
Considering that it is single-threaded, using the change command will block the thread. It is not recommended to use it in a production environment, as many keys may block.
2. Progressive traversal scan
1. Initialize the data
mset n1 1 n2 2 n3 3 n4 4 n5 5 n6 6 n7 7 n8 8 n9 9 n10 10 n11 11 n12 12 n13 13
2. Traverse the match
scan 0 match n* count 5 匹配以n开头的键,最大是取5条,第一次scan 0开始
For the second time, 20 keys starting with n are fetched from the cursor 4096, which is equivalent to fetching page by page. When the final return to 0 is returned, the keys are fetched.
3. Comparison of scan and keys
- Distributed through the cursor, the thread will not be blocked;
- Provide limit parameter, you can control the maximum number of results returned each time, limit is not accurate, the returned results can be more or less;
- Like keys, Scan also provides pattern matching functions;
- The server does not need to save state for the cursor, the only state of the cursor is the cursor integer that scan returns to the client;
- The results returned by scan may be repeated, and the client needs to be repeated;
- If there is data modification during scan traversal, it is uncertain whether the changed data can be traversed;
- The result of a single return is empty does not mean that the traversal is over, but depends on whether the returned cursor value is zero;
4. Other traversal commands
The SCAN command is used to iterate the database keys in the current database.
The SSCAN command is used to iterate the elements in the collection key.
The HSCAN command is used to iterate the key-value pairs in the hash key.
The ZSCAN command is used to iterate the elements in an ordered set (including element members and element scores).
The usage is the same as scan