一、管道概念
1.1 为什么要有redis管道?
redis本身处理速度很快,但是如果你连续调用10条redis命令,它们要有10个网络来回,这速度就会降下来了,那么有没有办法把这10条命令一起发送到服务端呢?有,它就是redis管道
1.2 redis管道的本质是什么?
redis管道的本质是将要发往redis服务端执行的命令在客户端缓存起来,比如说缓存100条,然后你可以将这100条命令一起发送到redis服务端,从而将100个网络来回降低到1个来回,大大降低了网络开销,提升了性能。
1.3 redis管道优点是什么?
优点:
- 多个指令之间没有依赖关系,一个命令出问题,不影响其他命令;
- 可以使用 pipeline 一次性执行多个指令,减少 IO,缩减时间。
特点:
- redis的管道,是客户端实现的技术,服务端稍微配合一下即可(读取批量命令执行,每条命令执行完后进行缓存,全部执行完后再一次性返回)。
- 优点是大大减少了网络请求次数,提高了性能
- 注意:由于执行结果是批量返回的,所以管道中的命令不宜太多,否则redis服务端的缓存压力将会变大,进而影响性能。
- 注意:管道中的命令适合彼此没有关联的命令,如果一个命令的执行依赖上次执行的结果,那就不要用管道了。
二、Redis管道 vs Redis事务
从下方的流程图,可以看出区别:
1.命令在哪里缓存:
- 事务里面的命令是在服务端缓存,当发出exec命令的时候,服务端就会判断并执行事务命令。
- 管道里面的命令是在客户端缓存,当客户端结束管道后一次发送到服务端,服务端读取后按照先后顺序先后执行。
- 但不管是事务还是管道,服务端都需要缓存单个命令的执行结果,等全部执行完后再返回给客户端
2.命令中出现语法错误,是否影响其他命令:
- 事务里的命令如果有语法错误(比如:getset name,注意不是执行错误),会导致事务被丢弃,里面的命令都不会执行
- 而管道里的命令如果出现语法错误,依然不影响其他的命令执行
3.命令执行过程:
- 事务和管道里的命令执行过程中都不能被其他的命令插入(事务的肯定不会打断,管道的暂时认为不会打断吧)
- 事务的命令指向前需要判断watch指定的值是否改变,如果改变了就不执行,而管道不会判断
事务流程图:
管道流程图:
三、代码示例:使用pipeline
下面就来对比一下使用管道和不使用管道的速度差异。
public class JedisDemo { private static int COMMAND_NUM = 1000; private static String REDIS_HOST = "Redis服务器IP"; public static void main(String[] args) { Jedis jedis = new Jedis(REDIS_HOST, 6379); withoutPipeline(jedis); withPipeline(jedis); } private static void withoutPipeline(Jedis jedis) { Long start = System.currentTimeMillis(); for (int i = 0; i < COMMAND_NUM; i++) { jedis.set("no_pipe_" + String.valueOf(i), String.valueOf(i), SetParams.setParams().ex(60)); } long end = System.currentTimeMillis(); long cost = end - start; System.out.println("withoutPipeline cost : " + cost + " ms"); } private static void withPipeline(Jedis jedis) { Pipeline pipe = jedis.pipelined(); long start_pipe = System.currentTimeMillis(); for (int i = 0; i < COMMAND_NUM; i++) { pipe.set("pipe_" + String.valueOf(i), String.valueOf(i), SetParams.setParams().ex(60)); } pipe.sync(); // 获取所有的response long end_pipe = System.currentTimeMillis(); long cost_pipe = end_pipe - start_pipe; System.out.println("withPipeline cost : " + cost_pipe + " ms"); } }
结果也符合我们的预期:
withoutPipeline cost : 11791 ms
withPipeline cost : 55 ms
参考文献
版权声明:本文为CSDN博主「jackletter」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u010476739/article/details/105252038