两万字 redis.conf 7.0 配置和原理全解,生产王者必备( 十 )


4、SortedSets(有序集合)
在 Redis 7.0 版本之前,有序集合底层的数据结构有 ziplist 和 skipist,之后使用 listpack 代替了 ziplist 。
7.0 版本之前,当集合元素个数小于 zset-max-ziplist-entries配置,同时且每个元素的值大小都小于zset-max-ziplist-value配置(默认 64 字节,推荐调大到 128)时,我将使用 ziplist 数据结构存储数据,有效减少内存使用 。与此类似,7.0 版本之后我将使用 listpack 存储 。
## 7.0 之前的配置zset-max-ziplist-entries 128zset-max-ziplist-value 64## 7.0 之后的配置zset-max-listpack-entries 128zset-max-listpack-value 645、HyperLogLog
HyperLogLog 是一种高级数据结构,统计基数的利器 。HyperLogLog 的存储结构分为密集存储结构和稀疏存储结构两种,默认为稀疏存储结构,而我们常说的占用 12K 内存的则是密集存储结构,稀疏结构占用的内存会更小 。
hll-sparse-max-bytes
默认配置是 hll-sparse-max-bytes 3000,单位是 Byte,这个配置用于决定存储数据使用稀疏数据结构(sparse)还是稠密数据结构(dense) 。
如果 HyperLogLog 存储内容大小大于 hll-sparse-max-bytes 配置的值将会转换成稠密的数据结构(dense) 。
推荐的值是 0~3000,这样PFADD命令的并不会慢多少,还能节省空间 。如果内存空间相对 cpu 资源更缺乏,可以将这个值提升到 10000 。
6、Streams(流)
Stream 是 Redis 5.0 版本新增的数据类型 。Redis Streams 是一些由基数树(Radix Tree)连接在一起的节点经过 delta 压缩后构成的,这些节点与 Stream 中的消息条目(Stream Entry)并非一一对应,而是每个节点中都存储着若干 Stream 条目,因此这些节点也被称为宏节点或大节点 。
stream-node-max-bytes 4096
单位为 Byte,默认值 4096,用于设定每个宏节点占用的内存上限为 4096,0 表示无限制 。
stream-node-max-entries 100
用于设定每个宏节点存储元素个数 。默认值 100,0 表示无限制 。当一个宏节点存储的 Stream 条目到达上限,新添加的条目会存储到新的宏节点中 。
7、rehash
我采用的是渐进式 rehash,这是一个惰性策略,不会一次性把所有数据迁移完,而是分散到每次请求中,这样做的目的是防止数据太多要迁移阻塞主线程 。
在渐进式 rehash 的同时,推荐你使用 activerehashing yes开启定时辅助执行 rehash,默认情况下每一秒执行 10 次 rehash 加快迁移速度,尽可能释放内存 。
关闭该功能的话,如果这些 key 不再活跃不被被访问到,rehash 操作可能不再有机会完成,会导致散列表占用更多内存 。
8、客户端输出缓冲区限制
这三个配置是用来强制断开客户端连接的,当客户端没有及时把缓冲区的数据读取完毕,我会认为这个客户端可能完蛋了(一个常见的原因是 Pub/Sub 客户端处理发布者的消息不够快),于是断开连接 。
一共分为三种不同类型的客户端,分别设置不同的限制 。

  • normal(普通),普通客户端,包括 MONITOR 客户端 。
  • replica(副本客户端),slave 节点的客户端 。
  • pubsub(发布订阅客户端),至少订阅了一个 pubsub 频道或者模式的客户端 。

client-output-buffer-limit的语法如下 。
client-output-buffer-limit <class> <hard limit> <soft limit> <soft seconds><class> 表示不同类型的客户端,当客户端的缓冲区内容大小达到 <hard limit>后我就立马断开与这个客户端的连接,或者达到 <soft limit> 并持续了 <soft seconds>秒后断开 。
默认情况下,普通客户端不会限制,只有后异步的客户端才可能发送发送请求的速度比读取响应速度快的问题 。比如 pubsub 和 replica 客户端会有默认的限制 。
soft limit 或者 hard limit 设置为 0,表示不启用此限制 。默认配置如下 。
client-output-buffer-limit normal 0 0 0client-output-buffer-limit replica 256mb 64mb 60client-output-buffer-limit pubsub 32mb 8mb 609、client-query-buffer-limit
每个客户端都有一个 query buffer(查询缓冲区或输入缓冲区),用于保存客户端发送命令,Redis Server 从 query buffer 获取命令并执行 。
如果程序的 Key 设计不合理,客户端使用大量的 query buffer,导致 Redis 很容易达到 maxmeory 限制 。最好限制在一个固定的大小来避免占用过大内存的问题 。
如果你需要发送巨大的 multi/exec 请求的时候,那可以适当修改这个值以满足你的特殊需求 。
默认配置为 client-query-buffer-limit 1gb 。


推荐阅读