Redis pipeline以及批量优化

Request/Response protocol

Redis基于Request/Response 协议。通常情况下一次请求的步骤如下

1 客户端通过tcp 协议发送指令到服务端,等待redis服务端返回结果

2 redis服务端执行命令,返回响应到客户端。

54324357.png

客户端发送请求到接受到服务端返回的响应被称为一次RTT(Round Trip Time). 在不考虑redis 服务端处理耗时的情况下,数据传输的耗时是最要的开销。且redis client 必须等待上一次响应结果才能发送下一个指令,会长时间处于阻塞的状态。

为解决提升reids服务端的吞吐量,redis提供了如下几种解决方案。

批量指令

redis实现了HMGET/HMSET/MSET/MGET等一系列批量指令。区别与普通指令如GET, MGET可以一次性发送key数组,然后redis服务端一次性返回结果数组。


 SET key1 "Hello"

"OK"
SET key2 "World"
"OK"
MGET key1 key2 nonexisting
1) "Hello"
2) "World"
3) (nil)

很明显这种方式可以使用一次RTT处理完多个指令。这种方式的在性能上是最好的,缺点在于

1. 指令类型必须一致,批量指令依赖于Redis的实现,有些指令如setbit 没有批量实现的,就无法使用这种方案。

2. 不能混合指令发送,需要发送的指令必须在一次请求中确定。灵活性比pipeline差。

redis pipeline

pipelining 是Request/Reponse协议的一种实现方式。客户端连续发送请求,而不用等待上一次的response返回。最终通过一次读取之前所有的Response。Redis服务支持这种实现方式。

51661039.png

redis pipeline性能

我们通过redis-benchmark对比下普通cs模型和pipleline的性能。


src ./redis-benchmark -t get,set -q -n 100000

SET: 50761.42 requests per second

GET: 70671.38 requests per second

➜ src ./redis-benchmark -P 100 -t get,set -q -n 100000

SET: 483091.78 requests per second

GET: 826446.31 requests per second

从上面测试结果可以看出pipleline的性能远高于普通的请求方式。

redis pipeline高性能分析

1. pipeline的RTT交互次数,从而减少延迟,在网络延迟比较大的环境下。吞吐量提高会特别明显。

2. redis客户端/服务端减少了sys_call调用次数,减少了用户态到内核态的切换开销。

3. redis客户端发送无需等待上一次response请求结果,减少了阻塞时间。

It's not just a matter of RTT

Pipelining is not just a way in order to reduce the latency cost due to the round trip time, it actually improves by a huge amount the total operations you can perform per second in a given Redis server. This is the result of the fact that, without using pipelining, serving each command is very cheap from the point of view of accessing the data structures and producing the reply, but it is very costly from the point of view of doing the socket I/O. This involves calling the read() and write() syscall, that means going from user land to kernel land. The context switch is a huge speed penalty.

Redis-Bloomfilter 1.1.0优化

Redis-Bloomfilter在1.0.0版本时,操作redis是基于标准的request/response模式, 但是Bloomfilter 在精度和预计插入数量大的情况,需要做多次hash操作。这样一次bloomfilter操作需要进行几十次redis setbit/getbit。这种情况下会严重影响Bloomfilter的吞吐量。由于setbit/getbit 不支持批量操作,所以采用pipeline来优化redis的性能开销。具体可以参考https://github.com/ttting/redis-bloomfilter的实现方式。 另外增加对于基于redistemplate的支持。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 在之前的文章中,我们对redis批量处理指令mget进行了压测并分析了性能瓶颈,显然通过mget批量执行指令可以节...
    近路阅读 39,658评论 4 18
  • 前言 Redis是基于TCP连接进行通信Redis是使用客户端 - 服务器模型的TCP服务器,称为请求/响应协议。...
    香山上的麻雀阅读 1,032评论 0 1
  • Redis是一种基于客户端-服务端(C/S)模型以及请求/响应协议(Request/Response protoc...
    handsomemao666阅读 177评论 0 3
  • 看了看redis的文档,觉得有些东西写的挺好的,就挑觉得有意义的记录一下。 pipelining—流水线 Redi...
    arloor阅读 475评论 0 0
  • 又开始看安妮宝贝的文章。 这篇《想起来的爱情》这样写道: 觉得爱情是两个人彼此做个伴。不要束缚,不要缠绕,不要占有...
    空笺阅读 387评论 5 2