Redis 协议

Redis 的客户端和服务器端使用 TCP 直连,基本的协议都是一问一答(request and response) 形式的。但它发送的请求是遵循特定的应用层协议(Redis Serialization Protocal)的。

一个请求如下:

1
*3\r\n$3\r\nSET\r\n$5\r\nhello\r\nworld\r\n 

*3 代表 3 个参数(SET KEY VALUE)。 $3 代表紧随其后的参数长度为 3 字节。 每一段可见字符都必须以一个CLRF(\r\n)结尾。

而返回值也有格式:

状态回复,在 RESP 中第一个字节为“+”。 错误回复,在 RESP 中第一个字节为“-”。 多条字符串回复,在 RESP 中第一个字节为“”。 整数回复,在 RESP 中第一个字节为“:”。 字符串回复,在 RESP 中第一个字节为“$”。 多条字符串回复,在 RESP 中第一个字节为“”。

Jedis 客户端

使用的时候要注意配上 try-finally 块,小心连接泄漏。 也可以使用连接池,也要注意规划,连接池一样可以造成连接泄漏。

客户端管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 客户端列表,定位每个客户端的问题
client list
# 整体看待客户端信息
info clients

# 获取内存信息
info memory

# 杀死指定地址端口的客户端
client kill 127.0.0.1:3780

# 暂停客户端 1000 毫秒
client pause 1000

# 另一种镜像监控所有流量的方式,注意需要庞大的输出缓冲区,很可能耗尽内存。禁止在生产上使用。
monitor

redis 服务端为每个客户端分配一个输入缓冲区(默认大小为 1G,而且不受 maxmemory 的限制)。输入缓冲区满了以后,客户端可能会被关闭。

与客户端相关的几个参数:

  • tcp-keepalive 默认值为 0,即 Redis 不检查死连接。如果设置为 60,则 Redis 会定期清理死连接,防止僵尸连接占用资源。
  • tcp-backlog tcp 接受连接的总数的大小,默认值为 511。这个值也受 OS 的内核参数控制,可以修改/proc/sys/net/core/somaxconn。

监控内存过大的思路

消耗的内存如果接近了 maxmemory,则可以按照以下步骤来排查问题:

  1. 确认各个主从节点的 dbsize 是否一样。
  2. 使用info clients来输出内存消耗信息,确认输入输出缓冲区的大小。
  3. 使用redis-cli client list | grep -v "omem=0"查找消耗内存比较多的 client。
  4. 检查是否有慢查询-注意查询 slowlog,或者遇到 slowlog 的时候直接报警。