初识 Redis pipelining

使用Redis pipelining可以加速Redis查询

1. 请求/响应协议和RTT

Redis是一个使用client-server模型和请求/响应协议的TCP服务器。

过程如下:

  1. client 发送一个请求给server,通常以阻塞的方式从套接字中读取server的响应。
  2. server 处理命令并将响应发送回client
Client: INCR X
Server: 1
Client: INCR X
Server: 2
Client: INCR X
Server: 3
Client: INCR X
Server: 4

clientserver 通过网络连接。 这样的连接可能非常快(环回接口),也可能非常慢(通过 Internet 建立的连接在两台主机之间有很多跃点)。 无论网络等待时间是多少,数据包都会有一段时间从 client 传到 server ,然后再从 server 传回 client

这段时间称为RTT(往返时间)。 当 client 需要连续执行多个请求时(例如,将多个元素添加到同一列表中,或使用许多键填充数据库),很容易看到这会对性能产生怎样的影响。 例如,如果RTT 时间为250毫秒(在 Internet 上的链接非常慢的情况下),即使 server 有每秒处理10万个请求的能力,我们每秒也最多只可以处理4个请求。

如果使用的接口是环回接口(loopback interface),则 RTT 会短得多(例如,我的主机显示 ping 到127.0.0.1时为0.044毫秒),但是如果连续执行多次写操作,RTT 则会大得多。

幸运的是,有一种方法可以改善此用例。

3. Redis Pipelining

可以实现请求/响应服务器,以便 即是 client 尚未读取旧响应,它也可以处理新请求。 这样,可以将多个命令发送到服务器,而根本不用等待答复,最后来读取答复。

这就是pipelining,在近数十年来已经广泛使用的技术。 例如,许多POP3协议已支持此功能,从而极大地加快了从服务器下载新电子邮件的过程。

Redis从很早就开始支持管道传输,因此无论您运行的是哪个版本,都可以在Redis中使用管道传输。

按如下过程,只需一次RTT即可:

  • Client: INCR X
  • Client: INCR X
  • Client: INCR X
  • Client: INCR X
  • Server: 1
  • Server: 2
  • Server: 3
  • Server: 4

需要注意的是,当 clientpipelining发送命令时,server必须将回复也放入内存队列中。因此,如果使用 pipelining, 最好一次性批量发送大量(例如 10K)的命令。所以管道中命令的数量应该有一个合理的值,不能无限多

3. 不只是RTT问题

pipelining 不仅减少 RTT 的延迟成本,它实际上还可以极大地提高给定 Redis 服务器每秒可执行的总操作数。 在不使用 pipelining 时,执行命令得到回复这个过程很快,但是整个Redis的服务效率被 socket I/O 限制了。

使用 pipelining 时,通常使用1次 read() 系统调用读取许多命令,再使用1次 write() 系统调用传递多个答复。 因此,每秒执行的总查询数最初随着 pipelines 地增长而几乎呈线性增加,最终趋于某一个值。

4. Pipelining VS Scripting

使用 Redis LUA 脚本(在Redis 2.6或更高版本中可用),使用Redis LUA脚本 来完成某些 pipelining 的工作更加高效。 LUA脚本 的一大优势在于,它能够以最小的延迟读取和写入数据,从而使读取,计算,写入等操作非常快(在某些情况下,pipelining无济于事,例如 client 需要在执行写命令之前得到服务器的回复)。

有时,应用程序可能还希望在管道中发送EVALEVALSHA命令。Redis 通过SCRIPT LOAD命令实现此功能(它可以保证调用EVALSHA不会失败)。

5. 扩展

前面我们提到,为了解决网络开销带来的延迟问题,可以把客户端和服务器放到一台物理机上。但是有时用benchmark进行压测的时候发现这仍然很慢。

这时客户端和服务端实际是在一台物理机上的,所有的操作都在内存中进行,没有网络延迟,按理来说这样的操作应该是非常快的。为什么会出现上面的情况的呢?

实际上,这是由内核调度导致的。比如说,benchmark运行时,读取了服务器返回的结果,然后写了一个新的命令。这个命令就在回环接口的send buffer中了,如果要执行这个命令,内核需要唤醒Redis服务器进程。所以在某些情况下,本地接口也会出现类似于网络延迟的延迟。其实是内核特别繁忙,一直没有调度到Redis服务器进程。

6. 参看文献

Redis 官方文档 pipelining
速度不够,管道来凑——Redis管道技术

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值