Redis的进阶使用
在上一篇文章中我们详解 Redis的 key-value 键值对模型中 value 的细节点,重点在于理解 value 支持的五种数据结构,对于每种数据结构的基本用法(即常用命令),我们还要对每种数据结构的优劣势,以及常用业务场景要做到心中有数
作为缓存之王,Redis 绝对不可能只有这么一点儿功能,下面我们就来学习一下 Redis 的进阶使用
其实从 Redis 官网我们即可学习到所有的用法:http://redis.cn/documentation.html
一、管道(pipelining)
管道是什么概念呢?
如果客户端对 redis 服务进程发出一连串的命令,其实每发一次命令都要走一次数据的传输,执行完返回,返回结果之后才能线性执行第二个命令。这意味着通常情况下一个请求会遵循以下步骤:
- 客户端向服务端发送一个查询请求,并监听Socket返回,通常是以阻塞模式,等待服务端响应。
- 服务端处理命令,并将结果返回给客户端。
因此,例如下面是4个命令序列执行情况:
- Client: INCR X
- Server: 1
- Client: INCR X
- Server: 2
- Client: INCR X
- Server: 3
- Client: INCR X
- Server: 4
客户端和服务器通过 TCP 网络进行连接,无论网络延如何延时,数据包总是能从客户端到达服务器,并从服务器返回数据回复客户端。这个时间被称之为 RTT (Round Trip Time - 往返时间),毫无疑问这种单次发送一个命令会带来大量的往返时间消耗,影响系统性能
此时我们自然而然就想到了一种优化方法——buffer 缓冲区,一次能够传输一批命令,对应在 Redis 中的实现就是管道
一次请求/响应服务器能实现处理新的请求,即使旧的请求还未被响应。这样就可以将多个命令发送到服务器,而不用等待回复,最后在一个步骤中读取该答复,这就是管道(pipelining)
管道使用案例:
$ (printf "PING\r\nPING\r\nPING\r\n"; sleep 1) | nc localhost 6379
+PONG
+PONG
+PONG
这一次我们没有为每个命令都花费了RTT开销,而是只用了一个命令的开销时间。
非常明确的,用管道顺序操作的第一个例子如下:
- Client: INCR X
- Client: INCR X
- Client: INCR X
- Client: INCR X
- Server: 1
- Server: 2
- Server: 3
- Server: 4
注意:使用管道发送命令时,服务器将被迫回复一个队列答复,占用很多内存。所以,如果你需要发送大量的命令,最好是把他们按照合理数量分批次的处理,例如10K的命令,读回复,然后再发送另一个10k的命令,等等。这样速度几乎是相同的,但是在回复这10k命令队列需要非常大量的内存用来组织返回数据内容。