Redis Pipeline原理

原理

大多数同学一直以来对 Redis 管道有一个误解,
他们以为这是 Redis 服务器提供的一种特别的技术,
有了这种技术就可以加速 Redis 的存取效率。
但是实际上 Redis 管道 (Pipeline) 本身并不是 Redis 服务器直接提供的技术,
这个技术本质上是由客户端提供的,
跟服务器没有什么直接的关系。
下面我们对这块做一个深入探究。

Redis 的消息交互

当我们使用客户端对 Redis 进行一次操作时,
如下图所示,客户端将请求传送给服务器,
服务器处理完毕后,再将响应回复给客户端。
这要花费一个网络数据包来回的时间。

image.png

如果连续执行多条指令,
那就会花费多个网络数据包来回的时间。
如下图所示。

image.png

回到客户端代码层面,
客户端是经历了读-写-读-写四个操作才完整地执行了两条指令。

image.png

现在如果我们调整读写顺序,改成写—写-读-读,
这两个指令同样可以正常完成。


image.png

两个连续的写操作和两个连续的读操作总共只会花费一次网络来回,
就好比连续的 write 操作合并了,
连续的 read 操作也合并了一样。

image.png

这便是管道操作的本质,
服务器根本没有任何区别对待,
还是收到一条消息,
执行一条消息,
回复一条消息的正常的流程。
客户端通过对管道中的指令列表改变读写顺序就可以大幅节省 IO 时间。
管道中指令越多,效果越好。

这一段笔者看的有点云里雾里~~~
不过接着往后面看就明白了

管道压力测试

接下来我们实践一下管道的力量。

Redis 自带了一个压力测试工具 redis-benchmark,
使用这个工具就可以进行管道测试。

首先我们对一个普通的 set 指令进行压测,
QPS 大约 5w/s。
redis-benchmark -t set -q
SET: 51975.05 requests per second

我们加入管道选项-P参数,
它表示单个管道内并行的请求数量,
看下面P=2,QPS 达到了 9w/s。
redis-benchmark -t set -P 2 -q
SET: 91240.88 requests per second

再看看P=3,QPS 达到了 10w/s。
SET: 102354.15 requests per second

但如果再继续提升 P 参数,发现 QPS 已经上不去了。
这是为什么呢?

因为这里 CPU 处理能力已经达到了瓶颈,
Redis 的单线程 CPU 已经飙到了 100%,
所以无法再继续提升了。

深入理解管道本质

接下来我们深入分析一个请求交互的流程,
真实的情况是它很复杂,
因为要经过网络协议栈,
这个就得深入内核了。

image.png

上图就是一个完整的请求交互流程图。
我用文字来仔细描述一遍:

  1. 客户端进程调用write将消息写到操作系统内核为套接字分配的发送缓冲send buffer。
  2. 客户端操作系统内核将发送缓冲的内容发送到网卡,
    网卡硬件将数据通过「网际路由」送到服务器的网卡。
  3. 服务器操作系统内核将网卡的数据放到内核为套接字分配的接收缓冲recv buffer。
  4. 服务器进程调用read从接收缓冲中取出消息进行处理。
  5. 服务器进程调用write将响应消息写到内核为套接字分配的发送缓冲send buffer。
  6. 服务器操作系统内核将发送缓冲的内容发送到网卡,
    网卡硬件将数据通过「网际路由」送到客户端的网卡。
  7. 客户端操作系统内核将网卡的数据放到内核为套接字分配的接收缓冲recv buffer。
  8. 客户端进程调用read从接收缓冲中取出消息返回给上层业务逻辑进行处理。
  9. 结束。

其中步骤 5~8 和 1~4 是一样的,
只不过方向是反过来的,一个是请求,一个是响应。

我们开始以为 write 操作是要等到对方收到消息才会返回,
但实际上不是这样的。
write 操作只负责将数据写到本地操作系统内核的发送缓冲然后就返回了。
剩下的事交给操作系统内核异步将数据送到目标机器。
但是如果发送缓冲满了,
那么就需要等待缓冲空出空闲空间来,
这个就是写操作 IO 操作的真正耗时。

我们开始以为 read 操作是从目标机器拉取数据,
但实际上不是这样的。
read 操作只负责将数据从本地操作系统内核的接收缓冲中取出来就了事了。
但是如果缓冲是空的,
那么就需要等待数据到来,
这个就是读操作 IO 操作的真正耗时。

所以对于value = redis.get(key)这样一个简单的请求来说,
write操作几乎没有耗时,
直接写到发送缓冲就返回,
而read就会比较耗时了,
因为它要等待消息经过网络路由到目标机器处理后的响应消息,再回送到当前的内核读缓冲才可以返回。
这才是一个网络来回的真正开销。

而对于管道来说,
连续的write操作根本就没有耗时,
之后第一个read操作会等待一个网络的来回开销,
然后所有的响应消息就都已经回送到内核的读缓冲了,
后续的 read 操作直接就可以从缓冲拿到结果,
瞬间就返回了。

小结

这就是管道的本质了,它并不是服务器的什么特性,
而是客户端通过改变了读写的顺序带来的性能的巨大提升。

个人再总结一点就是:
写入Redis的时候,
一般情况我们写入一个数据,
要等到服务器返回给我们ok,
我们才写下一条数据,
这样自然就慢了,
但是pipeline则是:
写入数据只要写到本地缓存就ok,
就一直写,写到缓存满了才停,
当然数据也是持续不断的往Redis 服务器走,
来清空客户端的缓存,
这样当然就快了,
因为再也不用等服务器的返回了。

本文转载自 Redis 深度历险:核心原理与应用实践 - 老錢 - 掘金小册

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容

  • Redis-pipeline 注意事项 cluster并不支持pipeline操作,不知道有没有什么好的方法 本质...
    zhangsanzhu阅读 2,347评论 0 2
  • 内容依旧来自<redis深度历险> 核心原理 线程IO模型 单线程非阻塞IO redis是单线程模型。redis的...
    无一幸免阅读 575评论 0 8
  • 上图就是一个完整的请求交互流程图。我用文字来仔细描述一遍: 客户端进程调用write将消息写到操作系统内核为套接字...
    恏人_7d7c阅读 1,258评论 0 1
  • 作者:黄湘龙 花了三天时间,把REDIS 3.0.6英文版大部分都翻译过来了,还有部分没翻译完,等我慢慢更新本文章...
    楚骧阅读 1,689评论 0 0
  • 事务 参考文章 什么是事务 事务是有一组操作构成,要么全部正确执行,要么全部不执行 四大特性 ACID 原子性 A...
    小绵羊你毛不多阅读 219评论 0 0