ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

Redis - 管道技术 pipeline

2021-10-01 01:00:08  阅读:144  来源: 互联网

标签:pipeline Redis redis pipe 命令 管道 执行 服务端


一、管道概念

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

标签:pipeline,Redis,redis,pipe,命令,管道,执行,服务端
来源: https://www.cnblogs.com/frankcui/p/15358577.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有