Request/Response protocols and RTT
Redis是基于客户端-服务端和请求/响应协议的TCP服务器. 这就意味着一个请求需要通过以下几步来完成.
- 客户端发送一个查询请求到服务器, 对于服务器的响应, 客户端以阻塞的方式从socket中读取数据
- 服务器处理从客户端发送过来的命令, 以及返回响应给客户端
因此,例如一个四个命令序列是这样的
- Client: INCR X
- Server: 1
- Client: INCR X
- Server: 2
- Client: INCR X
- Server: 3
- Client: INCR X
- Server: 4
客户端和服务器通过网络来进行连接, 因此这个连接可能很快( 本地回环接口 ), 也可能很慢( 主机之间通过网络建立连接).
无论网络怎样, 都会有一个客户端和服务器往返的时间. 这个时间被成为RTT( Round Trip Time ).
这很容易看出当一个客户端需要连续发送多个请求时将会多么影响性能, 如果一个RTT时间是250毫秒( 在通过Internet很慢的链路的情况下 ), 即使服务器能够每秒处理100k的请求, 那么我们也只能够每秒处理最多4个请求. 如果是使用一个loopback接口, 那么RTT时间就会短很多, 但是这个时间还是很多, 如果需要连续处理很多的写操作的话.
幸运的是有一个方法可以改善这个用例.
Redis Pipelining
请求/响应服务器可以被实现, 使得它能够处理新的请求, 即使客户端还没有读取旧的响应. 通过这种方式, 有可能发送多个命令到服务器而不需要去等待回应, 而且在最后只通过一步读取全部的回复.这被称为pipelining, 一种在这几十年都运用广泛的技术.
redis在很早期就已经支持pipelining, 所以无论你使用哪个版本,都可以使用pipelining.
如果使用pipelining, 那么第一个例子中的操作顺序将是下面这样
- Client: INCR X
- Client: INCR X
- Client: INCR X
- Client: INCR X
- Server: 1
- Server: 2
- Server: 3
- Server: 4