redis原理 4:雷厉风行 —— 管道

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

Redis 的消息交互

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

img
img

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

img
img

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

img
img

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

img
img

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

img
img

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

管道压力测试

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

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

首先我们对一个普通的 set 指令进行压测,QPS 大约 5w/s。

sql复制代码> redis-benchmark -t set -q
SET51975.05 requests per second

我们加入管道选项-P参数,它表示单个管道内并行的请求数量,看下面P=2,QPS 达到了 9w/s。

sql复制代码> redis-benchmark -t set -P 2 -q
SET91240.88 requests per second

再看看P=3,QPS 达到了 10w/s。

sql
复制代码SET102354.15 requests per second

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

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

深入理解管道本质

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

img
img

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

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

其中步骤 58 和 14 是一样的,只不过方向是反过来的,一个是请求,一个是响应。

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

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

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

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

小结

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

本文由 mdnice 多平台发布

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/52676.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【JS代码调试技巧】你必须知道的Javascript技巧汇总

注:最后有面试挑战,看看自己掌握了吗 文章目录 使用控制台检查变量值控制台使用 type of 检查变量的类型捕获拼错的变量名和函数名捕获使用赋值运算符而不是相等运算符捕捉函数调用后缺少的左括号和右括号 🌸I could be bounded in a nutshel…

如果网站用了CDN,我怎么找到它的真实IP?

0x01 验证是否存在CDN 方法1: 很简单,使用各种多地 ping 的服务,查看对应 IP 地址是否唯一,如果不唯一多半是使用了CDN, 多地 Ping 网站有: http://ping.chinaz.com/ http://ping.aizhan.com/ http://ce.…

JS解析JSON

在 JavaScript 中解析 JSON 数据 在 JavaScript 中,您可以使用 JSON.parse() 方法来解析 JSON 数据,示例代码如下: var json {"course": {"name": "JavaScript","author": "http://c.bianch…

探索CSS计数器:优雅管理网页元素的计数与序号

113. 探索CSS计数器:优雅管理网页元素的计数与序号 在前端开发中,我们经常需要对网页元素进行计数与序号,如有序列表、表格行号、步骤指示等。为了优雅地管理这些计数与序号,CSS提供了一种强大的功能:CSS计数器&#…

Stable diffusion 三大基础脚本 提示词矩阵,载入提示词,XYZ图表讲解

目录 0.本章讲解 1.提示词矩阵(prompt matrix) 1.2.提示词矩阵功能选项 1.2.1.把可变部分放在提示词文本的开头 1.2.2.为每张图片使用不同随机种子 1.2.3.选择提示词 1.2.4.选择分割符 1.2.5.宫格图边框(像素) 2.从文本框或文件载入提示词(Pro…

JVM基础篇-本地方法栈与堆

JVM基础篇-本地方法栈与堆 本地方法栈 什么是本地方法? 本地方法即那些不是由java层面实现的方法,而是由c/c实现交给java层面进行调用,这些方法在java中使用native关键字标识 public native int hashCode()本地方法栈的作用? 为本地方法提供内存空…

【数理知识】协方差,随机变量的的协方差,随机变量分别是单个数字和向量时的协方差

序号内容1【数理知识】自由度 degree of freedom 及自由度的计算方法2【数理知识】刚体 rigid body 及刚体的运动3【数理知识】刚体基本运动,平动,转动4【数理知识】向量数乘,内积,外积,matlab代码实现5【数理知识】协…

C 语言的 scanf() 函数

文章目录 概述转换说明intfloatdouble字符串 修饰符 modifier格式字符串中的空白格式字符串中的普通字符* 修饰符 概述 作用: Read formatted data from the standard input stream. 函数原型: int scanf( const char *format [,argument]… ); Parameters: format: Format …

Packet Tracer - 实施基本连接

Packet Tracer - 实施基本连接 地址分配表 设备 接口 IP 地址 子网掩码 S1 VLAN 1 192.168.1.253 255.255.255.0 S2 VLAN 1 192.168.1.254 255.255.255.0 PC1 网卡 192.168.1.1 255.255.255.0 PC2 网卡 192.168.1.2 255.255.255.0 拓扑图 目标 第 1 部分…

【数据结构与算法——TypeScript】算法的复杂度分析、 数组和链表的对比

【数据结构与算法——TypeScript】 算法的复杂度分析 什么是算法复杂度(现实案例)? ❤️‍🔥 前面已经解释了什么是算法? 其实就是解决问题的一系列步骤操作、逻辑。 ✅ 对于同一个问题,我们往往有很多种解决思路和方法&#x…

Adaptive autosar 都有哪些模块?各有什么功能?

Adaptive autosar是一种用于高性能计算ECU的软件平台,它支持自适应应用程序的开发和运行。它由两部分组成:基础(Foundation)和服务(Service)。基础包括了操作系统接口、执行管理、网络管理、识别访问管理、加密、更新和配置管理等功能。服务包括了通信管理、RESTful、时间…

OPENCV C++(四)形态学操作+连通域统计

形态学操作 先得到一个卷积核 Mat kernel getStructuringElement(MORPH_RECT,Size(5,5)); 第一个是形状 第二个是卷积核大小 依次为腐蚀 膨胀 开运算 闭运算 Mat erodemat,dilatemat,openmat,closemat;morphologyEx(result1, erodemat, MORPH_ERODE, kernel);morphologyEx…