加餐(六)| Redis的使用规范小建议

极客时间 | 《Redis核心技术与实战》学习笔记目录

原文

键值对使用规范

规范一:key 的命名规范

把业务名作为前缀,然后用冒号分隔,再加上具体的业务数据名。这样一来,我们可以通过 key 的前缀区分不同的业务数据,就不用在多个数据库间来回切换了。

  • 一个 Redis 实例默认可以支持 16 个数据库,我们可以把不同的业务数据分散保存到不同的数据库中。
  • 但是,在使用不同数据库时,客户端需要使用 SELECT 命令进行数据库切换,相当于增加了一个额外的操作。

我们在设置 key 的名称时,要注意控制 key 的长度

  • 当 key 字符串的长度增加时,SDS 中的元数据也会占用更多内存空间
  • 为了减少 key 占用的内存空间,建议:对于业务名或业务数据名,可以使用相应的英文单词的首字母表示,(比如 user 用 u 表示,message 用 m),或者是用缩写表示(例如 unique visitor 使用 uv)

规范二:避免使用 bigkey

  • 情况一:键值对的值大小本身就很大,例如 value 为 1MB 的 String 类型数据。为了避免 String 类型的 bigkey,在业务层,我们要尽量把 String 类型的数据大小控制在 10KB 以下
  • 情况二:键值对的值是集合类型,集合元素个数非常多,例如包含 100 万个元素的 Hash 集合类型数据。为了避免集合类型的 bigkey,建议尽量把集合类型的元素个数控制在 1 万以下

规范三:使用高效序列化方法和压缩方法

规范四:使用整数对象共享池

数据保存规范

规范一:使用 Redis 保存热数据

规范二:不同的业务数据分实例存储

规范三:在数据保存时,要设置过期时间

规范四:控制 Redis 实例的容量

Redis 单实例的内存大小都不要太大,建议设置在 2~6GB 。这样一来,无论是 RDB 快照,还是主从集群进行数据同步,都能很快完成,不会阻塞正常请求的处理。

命令使用规范

规范一:线上禁用部分命令

  • KEYS,按照键值对的 key 内容进行匹配,返回符合匹配条件的键值对,该命令需要对 Redis 的全局哈希表进行全表扫描,严重阻塞 Redis 主线程;
  • FLUSHALL,删除 Redis 实例上的所有数据,如果数据量很大,会严重阻塞 Redis 主线程;
  • FLUSHDB,删除当前数据库中的数据,如果数据量很大,同样会阻塞 Redis 主线程。

具体的做法是,管理员用 rename-command 命令在配置文件中对这些命令进行重命名,让客户端无法使用这些命令

规范二:慎用 MONITOR 命令

规范三:慎用全量操作命令

对于集合类型的数据来说,如果想要获得集合中的所有元素,一般不建议使用全量操作的命令(例如 Hash 类型的 HGETALL、Set 类型的 SMEMBERS)。这些操作会对 Hash 和 Set 类型的底层数据结构进行全量扫描,如果集合类型数据较多的话,就会阻塞 Redis 主线程。

建议

  • 使用 SSCAN、HSCAN 命令分批返回集合中的数据,减少对主线程的阻塞
  • 化整为零,把一个大的 Hash 集合拆分成多个小的 Hash 集合。这个操作对应到业务层,就是对业务数据进行拆分,按照时间、地域、用户 ID 等属性把一个大集合的业务数据拆分成多个小集合数据。例如,当你统计用户的访问情况时,就可以按照天的粒度,把每天的数据作为一个 Hash 集合
  • 如果集合类型保存的是业务数据的多个属性,而每次查询时,也需要返回这些属性,那么,你可以使用 String 类型,将这些属性序列化后保存,每次直接返回 String 数据就行,不用再对集合类型做全量扫描了

小结

规范类别规范内容
强制禁用 KEYS、FLUSHALL、FLUSHDB 命令
推荐使用业务名做 key 的前缀,并使用缩写形式
控制 key 的长度
使用高效序列化方法和压缩方法
使用整数对象共享池
不同业务数据保存到不同实例
数据保存时设置过期时间
慎用 MONITOR 命令
慎用全量操作命令
建议控制 String 类型数据的大小不超过 10KB
控制集合类型的元素个数不超过 1 万个
使用 Redis 保存热数据
把 Redis 实例的容量控制在 2~6 GB

精选留言

Kaito

业务层面主要面向的业务开发人员:

  1. key 的长度尽量短,节省内存空间
  2. 避免 bigkey,防止阻塞主线程
  3. 4.0+版本建议开启 lazy-free
  4. 把 Redis 当作缓存使用,设置过期时间
  5. 不使用复杂度过高的命令,例如SORT、SINTER、SINTERSTORE、ZUNIONSTORE、ZINTERSTORE
  6. 查询数据尽量不一次性查询全量,写入大量数据建议分多批写入
  7. 批量操作建议 MGET/MSET 替代 GET/SET,HMGET/HMSET 替代 HGET/HSET
  8. 禁止使用 KEYS/FLUSHALL/FLUSHDB 命令
  9. 避免集中过期 key
  10. 根据业务场景选择合适的淘汰策略
  11. 使用连接池操作 Redis,并设置合理的参数,避免短连接
  12. 只使用 db0,减少 SELECT 命令的消耗
  13. 读请求量很大时,建议读写分离,写请求量很大,建议使用切片集群

运维层面主要面向的是 DBA 运维人员:

  1. 按业务线部署实例,避免多个业务线混合部署,出问题影响其他业务
  2. 保证机器有足够的 CPU、内存、带宽、磁盘资源
  3. 建议部署主从集群,并分布在不同机器上,slave 设置为 readonly
  4. 主从节点所部署的机器各自独立,尽量避免交叉部署,对从节点做维护时,不会影响到主节点
  5. 推荐部署哨兵集群实现故障自动切换,哨兵节点分布在不同机器上
  6. 提前做好容量规划,防止主从全量同步时,实例使用内存突增导致内存不足
  7. 做好机器 CPU、内存、带宽、磁盘监控,资源不足时及时报警,任意资源不足都会影响 Redis 性能
  8. 实例设置最大连接数,防止过多客户端连接导致实例负载过高,影响性能
  9. 单个实例内存建议控制在 10G 以下,大实例在主从全量同步、备份时有阻塞风险
  10. 设置合理的 slowlog 阈值,并对其进行监控,slowlog 过多需及时报警
  11. 设置合理的 repl-backlog,降低主从全量同步的概率
  12. 设置合理的 slave client-output-buffer-limit,避免主从复制中断情况发生
  13. 推荐在从节点上备份,不影响主节点性能
  14. 不开启 AOF 或开启 AOF 配置为每秒刷盘,避免磁盘 IO 拖慢 Redis 性能
  15. 调整 maxmemory 时,注意主从节点的调整顺序,顺序错误会导致主从数据不一致
  16. 对实例部署监控,采集 INFO 信息时采用长连接,避免频繁的短连接
  17. 做好实例运行时监控,重点关注 expired_keys、evicted_keys、latest_fork_usec,这些指标短时突增可能会有阻塞风险
  18. 扫描线上实例时,记得设置休眠时间,避免过高 OPS 产生性能抖动
comments powered by Disqus