你真的了解redis为什么要提供pipeline功能


Posted in Redis onJune 22, 2021

 Redis本身是一个cs模式的tcp server, client可以通过一个socket连续发起多个请求命令。 每个请求命令发出后client通常会阻塞并等待redis服务端处理,redis服务端处理完后将结果返回给client。

       redis的pipeline(管道)功能在命令行中没有,但redis是支持pipeline的,而且在各个语言版的client中都有相应的实现。 由于网络开销延迟,即算redis server端有很强的处理能力,也由于收到的client消息少,而造成吞吐量小。当client 使用pipelining 发送命令时,redis server必须部分请求放到队列中(使用内存)执行完毕后一次性发送结果;如果发送的命名很多的话,建议对返回的结果加标签,当然这也会增加使用的内存;

       Pipeline在某些场景下非常有用,比如有多个command需要被“及时的”提交,而且他们对相应结果没有互相依赖,而且对结果响应也无需立即获得,那么pipeline就可以充当这种“批处理”的工具;而且在一定程度上,可以较大的提升性能,性能提升的原因主要是TCP链接中较少了“交互往返”的时间。不过在编码时请注意,pipeline期间将“独占”链接,此期间将不能进行非“管道”类型的其他操作,直到pipeline关闭;如果你的pipeline的指令集很庞大,为了不干扰链接中的其他操作,你可以为pipeline操作新建Client链接,让pipeline和其他正常操作分离在2个client中。不过pipeline事实上所能容忍的操作个数,和socket-output缓冲区大小/返回结果的数据尺寸都有很大的关系;同时也意味着每个redis-server同时所能支撑的pipeline链接的个数,也是有限的,这将受限于server的物理内存或网络接口的缓冲能力。

下面给大家普及redis为什么要提供pipeline功能。

通常我们用redis做接口缓存后,查询接口的性能就能提升到ms级别;
但是redis是纯内存操作啊,总不至于要到ms吧,根据官方的 benchmark 单实例也是能抗 7w+ qps 也就是说单个redis 操作在redis-server上耗时大概是 0.014ms,那时间是消耗到哪里去了?

redis是 client-server 模型,client客户端将 command 通过tcp网络连接发送到 server服务端,服务端执行完 command 后将响应再通过 tcp 连接发送给client;

你真的了解redis为什么要提供pipeline功能

对于应用服务来说,我们所关注的性能其实是客户端时间,即前面的整个执行过程,虽然 redis-server 命令执行的非常快,但每次命令执行都需要在网络上走一遭,按照我们公司redis客户端中间件统计的rt,一次命令的执行平均是1ms 左右,那么网络耗时占比: 1-0.014 / 1 = 0.98(98%!!! ) 可见,大部分时间都耗在网络io上

所以,减少网络io次数就能大大提供 redis-client 所感知的耗时,提升应用服务性能,redis提供的 pipeline 功能,让我们可以提交一个命令后,不用等这个返回结果就可以继续执行下一个命令,也就是说,可以执行多个命令后,一次性获取所有结果; 这样就大大减少了在网络上的消耗

比如

Client: INCR X
Client: INCR X
Client: INCR X
Client: INCR X

Server: 1
Server: 2
Server: 3
Server: 4

除此之外,减少了网络读写次数的同时,也减少了 redis-server 内核态和用户态的上下文切换,进一步提高了性能

性能提升了多少?

redis官方声称pipeline可带来10倍的性能提升

你真的了解redis为什么要提供pipeline功能

测试机Intel(R) Xeon(R) CPU E5520 @ 2.27GHz, 用pipeline比没用pipeline性能提升了将近7倍

// 用pipeline
$ ./redis-benchmark -r 1000000 -n 2000000 -t get,set,lpush,lpop -P 16 -q
SET: 552028.75 requests per second
GET: 707463.75 requests per second
LPUSH: 767459.75 requests per second
LPOP: 770119.38 requests per second

// 没用pipeline
SET: 122556.53 requests per second
GET: 123601.76 requests per second
LPUSH: 136752.14 requests per second
LPOP: 132424.03 requests per second

注意,使用pipeline的时候,多个命令的响应是缓存在server端的,所以在 pipeline 里一批命令的数量不要过多,以免服务端内存压力过大

其实,减少网络io次数的处理技巧还是比较常见的,如

  • CSS Sprites,将很多小图标合并成一张图片
  • jdbc batch api批量提交sql

参考:

https://redis.io/topics/pipelining

https://redis.io/topics/benchmarks

以上就是redis为什么要提供pipeline功能的详细内容,更多关于redis pipeline的资料请关注三水点靠木其它相关文章!

Redis 相关文章推荐
在K8s上部署Redis集群的方法步骤
Apr 27 Redis
Redis高级数据类型Hyperloglog、Bitmap的使用
May 24 Redis
k8s部署redis cluster集群的实现
Jun 24 Redis
聊一聊Redis与MySQL双写一致性如何保证
Jun 26 Redis
使用Redis实现实时排行榜功能
Jul 02 Redis
Redis高并发防止秒杀超卖实战源码解决方案
Nov 01 Redis
redis数据结构之压缩列表
Mar 21 Redis
一文搞懂Redis中String数据类型
Apr 03 Redis
Redis如何实现验证码发送 以及限制每日发送次数
Apr 18 Redis
Redis特殊数据类型Geospatial地理空间
Jun 01 Redis
Redis基本数据类型String常用操作命令
Jun 01 Redis
Redis实现主从复制方式(Master&Slave)
Jun 21 Redis
Redis缓存-序列化对象存储乱码问题的解决
比较几种Redis集群方案
解析Redis Cluster原理
解析高可用Redis服务架构分析与搭建方案
Redis基于Bitmap实现用户签到功能
redis实现的四种常见限流策略
Redis 哨兵集群的实现
You might like
PHP+DBM的同学录程序(1)
2006/10/09 PHP
PHP页面间参数传递的四种方法详解
2013/06/09 PHP
PHP内核探索:变量概述
2014/01/30 PHP
Laravel 5.5 的自定义验证对象/类示例代码详解
2017/08/29 PHP
PHP7使用ODBC连接SQL Server2008 R2数据库示例【基于thinkPHP5.1框架】
2019/05/06 PHP
PJ Blog修改-禁止复制的代码和方法
2006/10/25 Javascript
jQuery 操作option的实现代码
2011/03/03 Javascript
用jQuery中的ajax分页实现代码
2011/09/20 Javascript
网页加载时页面显示进度条加载完成之后显示网页内容
2012/12/23 Javascript
js confirm()方法的使用方法实例
2013/07/13 Javascript
js中arguments,caller,callee,apply的用法小结
2014/01/28 Javascript
实例分析javascript中的call()和apply()方法
2014/11/28 Javascript
jQuery显示和隐藏 常用的状态判断方法
2015/01/29 Javascript
JS实现的左侧竖向滑动菜单效果代码
2015/10/19 Javascript
AngularJS ng-blur 指令详解及简单实例
2016/07/30 Javascript
用iframe实现不刷新整个页面上传图片的实例
2016/11/18 Javascript
javascript简单进制转换实现方法
2016/11/24 Javascript
Layui表格监听行单双击事件讲解
2019/11/14 Javascript
JS数组方法push()、pop()用法实例分析
2020/01/18 Javascript
vue动态设置页面title的方法实例
2020/08/23 Javascript
[02:26]2016国际邀请赛8月3日开战 中国军团出征西雅图
2016/08/02 DOTA
[46:32]Fnatic vs OG 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
python通过post提交数据的方法
2015/05/06 Python
Python global全局变量函数详解
2018/09/18 Python
在Python中合并字典模块ChainMap的隐藏坑【推荐】
2019/06/27 Python
关于pycharm中pip版本10.0无法使用的解决办法
2019/10/10 Python
python nohup 实现远程运行不宕机操作
2020/04/16 Python
HTML5之SVG 2D入门9—蒙板及mask元素介绍与应用
2013/01/30 HTML / CSS
德国古洛迷亚百货官网:GALERIA Kaufhof
2017/06/20 全球购物
联想新西兰官方网站:Lenovo New Zealand
2018/10/30 全球购物
linux面试题参考答案(10)
2013/11/04 面试题
高中三年学习生活的自我评价
2013/10/10 职场文书
三八红旗集体先进事迹材料
2014/05/22 职场文书
2014年督导工作总结
2014/11/19 职场文书
2015年纪念“卢沟桥事变”78周年活动方案
2015/05/06 职场文书
公司与个人合作协议书
2016/03/19 职场文书