流水线技术(pipeline)在Redis中的应用

Redis客户端通过TCP连接或者类似的面向流的连接来和服务器端进行通讯

通常情况下:客户端发送命令到服务器端,并等待服务器端的返回;服务器端接收到命令,并完成响应操作,发送处理结果数据给客户端;这样就完成了完成了一次请求/响应

在我们使用Redis时,客户端一般一次只发送一个命令,举个例来说:

客户端服务器端set key valueOKget keyvalue客户端服务器端

这样的模式适用于很多的业务场景。比如说我们在获取数据时一般是阻塞的,自然需要等待服务器端返回数据才能进行下一步操作。又比如说有多个客户端或者说有多个线程的情况下,这一边所存的数据很有可能在下一刻便会被另一边用到,所以命令能越快发送就越好

当然凡事都有特例,在一些特殊的业务中,我们可能需要存储大量的数据,使用到许多的命令。在这种情况下,客户端再一条命令一条命令的发送就显得不太经济了,如果批量发送命令会不会提高效率,减省时间?

客户端服务器端set key1 value1set key2 value2......OKOK......客户端服务器端

很容易发现如果一次性发送多条命令,大量减少了IO操作。要知道IO系统调用,无论是read还是write,都是比较费时的操作,每一次IO系统调用,在操作系统内都需要涉及用户态和内核态的切换。原本n条命令在客户端需要n*2次IO系统调用(read&write),现在如果是使用流水线技术,将多条命令一次性发送,就只需要2次IO系统调用

如果向更深层次分析,如果客户端向服务器端,一次只发送一条命令,那么可以吧一条命令看作一个数据包,它在网络中的传输如下:

流水线技术(pipeline)在Redis中的应用

从图中我们可以看出,客户端发送数据包到服务器端返回数据包给客户端,其中所消耗的时间称为往返时间(Round Trip Time-RTT),往返时间的长短取决于网络线路畅通与否,但即使是使用回环网卡,和高效的CUP处理速度相比,仍然是一个很长的时间。当我们使用流水线技术时,就会发现大大的减少了RTT,这才是流水线技术提升性能的最主要原因

流水线技术(pipeline)在Redis中的应用

同时我们也会发现流水线技术对于缓存的花费是很大的,在客户端,需要将多条命令先缓存起来,存储了一定数量以后才一起发送给服务器端。在服务器端,这需要将克虎发来的多条命令缓存起来,一条命令一条命令的处理,同时还需存储处理后的结果,最后将多条结果返回给客户端。所以在编写代码时需要同时考虑内存开销和时间开销,使批量发送的命令数量在合理的范围内

问题1:在Redis中流水线(pipeline)和事务(Transaction)的区别?

  • 就实现上来说:实现事务只需要服务器端的支持,开启事物之后,服务器端会存储客户端的命令,最后一次性执行;实现pipline则需要客户端和服务器端共同的支持,客户端一次性发送多个命令,服务端一次性响应多个命令

  • 就功能上来说:事务是一个单独的隔离操作,并且具有原子性;pipeline则是为了减少RTT以及IO操作,提升性能