我们希望在没有任何附加条件的场景下去使用队列批量执行一系列的命令,从而提高系统性能,这就是 Redis 的流水线(pipelined)技术。而现实中 Redis 执行读/写速度十分快,而系统的瓶颈往往是在网络通信中的延时,如图所示。

在实际的操作中,往往会发生这样的场景,当命令 1 在时刻 T1 发送到 Redis 服务器后,服务器就很快执行完了命令 1,而命令 2 在 T2 时刻却没有通过网络送达 Redis 服务器,这样就变成了 Redis 服务器在等待命令 2 的到来,当命令 2 送达,被执行后,而命令 3 又没有送达 Redis,Redis 又要继续等待,依此类推,这样 Redis 的等待时间就会很长,很多时候在空闲的状态,而问题出在网络的延迟中,造成了系统瓶颈。

为了解决这个问题,可以使用 Redis 的流水线,但是 Redis 的流水线是一种通信协议,没有办法通过客户端演示给大家,不过我们可以通过 Java API 或者使用 Spring 操作它,先使用 Java API 去测试一下它的性能,代码如下所示。

Jedis jedis = pool.getResource();
long start = System.currentTimeMillis();
// 开启流水线
Pipeline pipeline = jedis.pipelined();
// 这里测试10万条的读/写2个操作
for (int i = 0; i < 100000; i++) {int j = i + 1;pipeline.set("pipeline_key_" + j, "pipeline_value_" + j);pipeline.get("pipeline_key_" + j);
}
// pipeline.sync(); //这里只执行同步,但是不返回结果
// pipeline.syncAndReturnAll ();将返回执行过的命令返回的List列表结果
List result = pipeline.syncAndRetrunAll();
long end = System.currentTimeMillis();
// 计算耗时
System.err.println("耗时:" + (end - start) + "毫秒");

在电脑上测试这段代码,它的耗时在 550 毫秒到 700 毫秒之间,也就是不到 1 秒的时间就完成多达 10 万次读/写,可见其性能远超数据库。我的测试是 1 秒 2 万多次,可见使用流水线后其性能提高了数倍之多,效果十分明显。执行过的命令的返回值都会放入到一个 List 中。

注意:这里只是为了测试性能而已,当你要执行很多的命令并返回结果的时候,需要考虑 List 对象的大小,因为它会“吃掉”服务器上许多的内存空间,严重时会导致内存不足,引发 JVM 溢出异常,可以考虑使用迭代的方式去处理。

在 Spring 中,执行流水线和执行事务的方法如出一辙都比较简单,使用 RedisTemplate 提供的 executePipelined 方法即可。下面将上面代码的功能修改为 Spring 的形式供大家参考,代码如下所示。

public static void testPipeline() {Applicationcontext applicationcontext = new ClassPathXmlApplicationContext("applicationcontext.xml");RedisTemplate redisTemplate = applicationcontext.getBean(RedisTemplate.class);// 使用Java8的Lambda表达式SessionCallback callBack = (SessionCallback) (RedisOperations ops)-> {for (int i = 0; i<100000; i++)    {int j = i + 1;ops . boundValueOps ("pipeline_key_" + j ).set("piepeline_value_"+j);ops.boundValueOps("pipeline_key_" + j).get();}return null;};long start = System.currentTimeMillis();//执行Redis的流水线命令List resultList= redisTemplate.executePipelined(callBack);long end = System.currentTimeMillis();System.err.println(end-start);
}

我对这段代码进行了测试,其性能慢于不用 RedisTemplate 的,测试消耗的时间大约在 1 100 毫秒到 1 300 毫秒之间,也就是消耗的时间大约是其两倍,但也属于完全可以接受的性能范围,同样的在执行很多命令的时候,也需要考虑其对运行环境内存空间的开销。

Redis流水线性能提高相关推荐

  1. java redis 流水线,Redis系列(1) —— 流水线

    写在前面 去年下半年,出于学习Redis的目的,在看完<Redis in Action>一书后,开始尝试翻译Redis官方文档.尽管Redis中文官方网站有了译本,但是看别人翻译好的和自己 ...

  2. Redis学习-性能与优化(五)

    实际开发的场景中,尤其是涉及到高并发的应用,关系型数据库常常无法满足业务需求,这时候从问题出发,尝试用redis这个基于内存的数据库,通常会因为它带来的几十倍甚至上百倍的性能使得问题迎刃而解.虽然满足 ...

  3. 压测、压力测试分析、UV、PV、通用性能提高、并发

    一:压力测试报错 1.1 java.net.SocketException: Socket closed 参考:JMeter压测"java.net.SocketException: Sock ...

  4. Redis MGET性能衰减分析

    MGET是redis中较为常用的命令,用来批量获取给定key对应的value.因为redis使用基于RESP (REdis Serialization Protocol)协议的rpc接口,而redis ...

  5. redis geo 性能分析及对问题的思考

    redis geo 性能分析及对问题的思考 文章目录 redis geo 性能分析及对问题的思考 对 redis 进行压力测试 对 redis 进行满载压力分析 georadiusGeneric me ...

  6. Redis 的性能幻想与残酷现实(转)

    2011 年,当初选择 Redis 作为主要的内存数据存储,主要吸引我的是它提供多样的基础数据结构可以很方便的实现业务需求.另一方面又比较担心它的性能是否足以支撑,毕竟当时 Redis 还属于比较新的 ...

  7. 英特尔用ViT做密集预测效果超越卷积,性能提高28%,mIoU直达SOTA|在线可玩

    丰色 发自 凹非寺 量子位 报道 | 公众号 QbitAI 用全卷积网络做密集预测 (dense prediction),优点很多. 但现在,你可以试试Vision Transformer了-- 英特 ...

  8. MySpaces性能提高的过程(转)

    50万用户 2 WebServer  1 DataBase Server   当用户达到50万的时候 改用3个DBServer ,1个负责接收用户提交,然后复制到其他2个DB内,另外2个复制用户请求数 ...

  9. redis java 性能_Redis 性能优化

    一.Linux 操作系统 [1]ulimit 与 TCP backlog:1).修改 ulimit:通过 ulimit 修改 open files 参数,redis 建议把 open files 至少 ...

最新文章

  1. 读博无门就业碰壁,孤独当了7个月“民科”后,我的论文中了顶会
  2. python中module_Python中的模块(Module)
  3. stoi() 函数----将一个string类型转换为int型
  4. 初识OneNote 2016
  5. mac下用scp命令实现本地文件与服务器Linux文件之间的相互传输
  6. P359 usestock2.cpp
  7. 双缓冲 android,Android 的 SurfaceView 双缓冲应用
  8. 模板:多项式乘法(FFTNTT)
  9. Windows Terminal Preview 1909 发布
  10. Spring Boot(3) Web开发(1)静态资源处理
  11. 广义注意力- saliency map 关注图、gaze、Att
  12. 开发比软件测试好吗,前端开发比软件测试发展好吗?
  13. 《和平精英》迎来史上最严封号:模拟器过检测、手机外设全部凉凉?
  14. [工具]Snipaste 屏幕截图软件超级利器 - 花3年精心打造的极致截图贴图/编辑/标注工具
  15. 艾司博讯:拼多多批量发货怎么做?
  16. 中国石油大学《中国当代散文》共享课程考试
  17. Btspread Search Assistant的开发过程
  18. keepdims=True
  19. Android UI SVGA使用
  20. 设置指纹识别模块分析

热门文章

  1. java 接口文件夹_Java NIO.2 使用Path接口来监听文件、文件夹变化
  2. 计算机x线影像ppt,计算机X线摄影ppt课件
  3. php new static,PHP中new self()和new static()的区别用法
  4. mysql 5.7 flashback_Flashback for MySQL 5.7
  5. 修改了模板文件tpl如何立即生效_Views视图与模板
  6. win7本地连接不见了的修复方法
  7. 搜狐视频怎么清除应用缓存
  8. 23种经典设计模式都有哪些,如何分类?Java设计模式相关面试
  9. oracle数据库中索引会失效的几种情况
  10. mongodb 数组查询 php,关于PHP,查询mongodb里的数组的问题