你真的了解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 相关文章推荐
Redis安装启动及常见数据类型
Apr 14 Redis
基于Redis位图实现用户签到功能
May 08 Redis
比较几种Redis集群方案
Jun 21 Redis
使用redis实现延迟通知功能(Redis过期键通知)
Sep 04 Redis
Redis 持久化 RDB 与 AOF的执行过程
Nov 07 Redis
CentOS8.4安装Redis6.2.6的详细过程
Nov 20 Redis
Springboot/Springcloud项目集成redis进行存取的过程解析
Dec 04 Redis
详解Redis的三种常用的缓存读写策略步骤
May 06 Redis
解决 redis 无法远程连接
May 15 Redis
Redis keys命令的具体使用
Jun 05 Redis
浅谈Redis缓冲区机制
Jun 05 Redis
Redis实现主从复制方式(Master&Slave)
Jun 21 Redis
Redis缓存-序列化对象存储乱码问题的解决
比较几种Redis集群方案
解析Redis Cluster原理
解析高可用Redis服务架构分析与搭建方案
Redis基于Bitmap实现用户签到功能
redis实现的四种常见限流策略
Redis 哨兵集群的实现
You might like
咖啡知识 咖啡养豆要养多久 排气又是什么
2021/03/06 新手入门
PHP_Flame(Version:Progress)的原代码
2006/10/09 PHP
无JS,完全php面向过程数据分页实现代码
2012/08/27 PHP
一个简单的php路由类
2016/05/29 PHP
实例讲解PHP表单验证功能
2019/02/15 PHP
thinkphp5 模型实例化获得数据对象的教程
2019/10/18 PHP
用Juery网页选项卡实现代码
2011/06/13 Javascript
jquery.artwl.thickbox.js  一个非常简单好用的jQuery弹出层插件
2012/03/01 Javascript
js控制表单不能输入空格的小例子
2013/11/20 Javascript
js 鼠标移动显示图片的简单实例
2013/12/25 Javascript
检查输入的是否是数字使用keyCode配合onkeypress事件
2014/01/23 Javascript
Js 正则表达式知识汇总
2014/12/02 Javascript
jQuery创建DOM元素实例解析
2015/01/19 Javascript
jquery实现的Accordion折叠面板效果代码
2015/09/02 Javascript
AngularJs 弹出模态框(model)
2016/04/07 Javascript
Echarts基本用法_动力节点Java学院整理
2017/08/11 Javascript
React Native 环境搭建的教程
2017/08/19 Javascript
详解js几个绕不开的事件兼容写法
2017/08/30 Javascript
微信小程序倒计时功能实现代码
2017/11/09 Javascript
JS中双击和单击事件冲突的解决方法
2018/04/09 Javascript
对mac下nodejs 更新到最新版本的最新方法(推荐)
2018/05/17 NodeJs
配置一个vue3.0项目的完整步骤
2019/04/26 Javascript
微信小程序Echarts覆盖正常组件问题解决
2019/07/13 Javascript
vue 里面的 $forceUpdate() 强制实例重新渲染操作
2020/09/21 Javascript
[00:34]DOTA2上海特级锦标赛 VG战队宣传片
2016/03/04 DOTA
python导入时小括号大作用
2017/01/10 Python
Python GUI库PyQt5样式QSS子控件介绍
2020/02/25 Python
利用Python自动化操作AutoCAD的实现
2020/04/01 Python
python中JWT用户认证的实现
2020/05/18 Python
什么是Python中的匿名函数
2020/06/02 Python
深入分析python 排序
2020/08/24 Python
东方电视购物:东方CJ
2016/10/12 全球购物
VICHY薇姿俄罗斯官方网上商店:法国护肤品牌,火山温泉水
2019/11/22 全球购物
大学生活自我评价
2014/04/09 职场文书
学校2014重阳节活动策划方案
2014/09/16 职场文书
教你利用Nginx 服务搭建子域环境提升二维地图加载性能的步骤
2021/09/25 Servers