本文大部分内容引自《Redis深度历险:核心原理和应用实践》,感谢作者!!!
Redis管道
Redis管道(Pipeline)是由Redis客户端提供的技术,和Redis服务器没有直接的关系;管道适合操作先后顺序对结果无影响的连续指令,连续读或连续写
Redis的普通消息交互
客户端和服务器之间每次交互都是经历了“写-读-写-读”四个阶段,这种模式每次完成交互需要花费一个网络数据包来回的时间
管道的本质
1、如果改成“写-写-读-读”的操作顺序就好比连续的write操作合并了,连续的read操作也合并了
2、在管道中,服务器对收到的请求还是做出相应的处理;但是客户端通过对管道中的指令列表改变读写顺序就可以大幅度节省IO时间。管道中的指令越多,效果越好
3、使用redis-benchmark可以进行管道测试
深入理解管道本质
1、管道的使用是一个请求交互的流程,要经过网络协议栈,深入内核
2、客户端进程调用write将消息写到操作系统内核为套接字分配的发送缓冲send buffer
3、客户端操作系统内核将发送缓冲的内容发送到网卡,网卡硬件将数据通过“网际路由”发送到服务器的网卡
4、服务器操作系统内核将网卡的数据放到内核为套接字分配的接收缓冲recv buffer
5、服务器进程调用read从接收缓冲中取出消息进行处理
6、服务器进程调用write将响应消息写到内核为套接字分配的发送缓冲send buffer
7、服务器操作系统内核将发送缓冲的内容发送到网卡,网卡硬件将数据通过“网际路由”发送到客户端的网卡
8、客户端操作系统内核将网卡的数据放到内核为套接字分配的接收缓冲recv buffer
9、客户端进程调用read从接收缓冲中取出消息返回给上层业务逻辑进行处理
10、结束
细节讲解
1、write操作只负责将数据写到本地操作系统内核的发送缓冲然后就返回了,剩下的事交给操作系统内核异步将数据送到目标机器;但是如果发送缓冲满了,那么就需要等待缓冲空出空闲空间来,这个就是写操作IO操作的真正耗时
2、read操作只负责将数据从本地操作系统内核的接收缓冲中取出来就了事了;但是如果缓冲是空的,那么就需要等待数据到来,这个就是读操作IO操作的真正耗时
3、对于value = redis.get(key)这样一个简单的请求来说,write操作几乎没有耗时,直接写到发送缓冲就返回;而read就会比较耗时了,因为它要等待消息经过网络路由到目标机器处理后的响应消息,再回送到当前的内核读缓冲才可以返回,这才是一个网络来回的真正开销
4、而对于管道来说,连续的write操作根本就没有耗时;之后第一个read操作会等待一个网络的来回开销,然后所有的响应消息就都已经回送到内核的读缓冲了,后续的read操作直接就可以从缓冲拿到结果,瞬间就返回了