redis的流操作能够降低客户端与redis的交互次数,即降低多次的socket通信的开销,如果遇到需要连续的读取redis的数据或者写入redis数据,且前后的redis操作没有依赖关系,那么可以使用流操作来降低客户端与redis服务的通信开销。
先看以下几段代码,分别是非事务流操作(管道操作)、非流操作(普通redis操作)、事务流操作。
以下代码的逻辑:循环1000次往redis中存放数据,且每循环一次执行10个redis的 set 操作命令。
/**
* 管道操作,非事务流操作
*/
@GetMapping("/pipe")
public void testPipe() {
long start = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {//每一个循环中操作redis 10次
List<Object> objects = redisTemplate.executePipelined(new RedisCallback<Long>() {
@Override
public Long doInRedis(RedisConnection connection) throws DataAccessException {
connection.openPipeline();//开启管道
for (int j = 0; j < 10; j++) {
connection.set(("pipeLine" + j).getBytes(), String.valueOf(1).getBytes());
}
connection.closePipeline();//关闭管道
return null;
}
});
}
long delta = System.currentTimeMillis() - start;
System.out.println("delta-pipe: " + delta);
}
/**
* 普通的redis操作
*/
@GetMapping("/nonpipe")
public void testNonpipe() {
long start = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {//每一个循环中操作redis 10次
for (int j = 10; j < 20; j++) {
redisTemplate.opsForValue().set("pipeLine" + j, 1 + "");
}
}
long delta = System.currentTimeMillis() - start;
System.out.println("delta-nonpipe: " + delta);
}
/**
* 开启事务操作,事务也属于流操作的一种
*/
@GetMapping("/multi")
public void testMulti() {
redisTemplate.setEnableTransactionSupport(true);
long start = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {//每一个循环中操作redis 10次
redisTemplate.multi();//开启事务
for (int j = 10; j < 20; j++) {
redisTemplate.opsForValue().set("pipeLine" + j, 1 + "");
}
redisTemplate.exec();//执行
}
long delta = System.currentTimeMillis() - start;
System.out.println(" delta-multi: " + delta);
}
以下为三种操作的消耗时间的两次打印结果,为了确保结果的准确性,执行了两次:
第一次:
delta-pipe:1428
delta-nonpipe: 6268
delta-multi: 2218
第二次:
delta-pipe: 1290
delta-nonpipe :6827
delta-multi: 2839
操作方式 | 平均消耗时间/ms | 执行命令次数 |
delta-pipe(非事务流操作) | 1359 | 1000*10 |
delta-multi(事务流操作) | 2528 | 1000*10 |
delta-nonpipe(普通操作) | 6547 | 1000*10 |
从结果中分析(以我本地的网络宽带条件测试结果,大约往虚拟机上传速度为20m/s左右),当执行redis的命令比较多时,redis的流操作比普通的redis操作性能要高很多,非事务的流操作的性能消耗大约是事务性的流操作性能消耗的 1/2,事务性的流操作的性能消耗大约是普通操作的 1/2-1/3 。所以在合适的场景中使用redis的流式操作能提高应用程序的性能。