redis 大key问题

做事一定要考虑别人的感受,千万不能让他们太开心了。

 

所谓的大 key 问题是某个 key 的 value 比较大,所以本质上是大 value 问题(value 往往不受程序控制,因此可能导致 value 很大)

说明:

  • value 是 String 类型时,size 超过 10KB
  • value 是 ZSET、Hash、List、Set 等集合类型时,它的成员数量超过 1w 个

 

大key是如何产生的?

  • 一直往 value 塞数据,没有删除机制,迟早要爆炸
  • 数据没有合理做分片,将大 key 变成小 key

 

大key问题带来什么影响?

  • 执行大 key 命令的客户端本身,耗时明显增加,甚至超时
  • 执行大 key 相关读取或者删除操作时,会严重占用带宽和 CPU,影响其他客户端
  • 大 key 本身的存储带来分布式系统中分片数据不平衡,CPU 使用率也不平衡
  • 大 key 有时候也是热 key,读取操作频繁,影响面会很大
  • 执行大 key 删除时,在低版本 redis 中可能阻塞线程

 

如何找到大key?

  • bigkeys 命令
  • redis-rdb-tools
  • 集成化可视化工具

 

如何解决大key问题?

根据大 key 的实际用途可以分为两种情况:可删除和不可删除。

 

可删除方法

当 Redis 版本大于 4.0 时,可使用 UNLINK 命令安全地删除大 Key,该命令能够以非阻塞的方式,逐步地清理传入的 Key。
“ Redis UNLINK 命令类似与 DEL 命令,表示删除指定的 key,如果指定 key 不存在,命令则忽略。
UNLINK 命令不同与 DEL 命令在于它是异步执行的,因此它不会阻塞。
UNLINK 命令是非阻塞删除,非阻塞删除简言之,就是将删除操作放到另外一个线程去处理。

 

当 Redis 版本小于 4.0 时,避免使用阻塞式命令 KEYS,而是建议通过 SCAN 命令执行增量迭代扫描 key,然后判断进行删除。
“ Redis Scan 命令用于迭代数据库中的数据库键。
SCAN 命令是一个基于游标的迭代器,每次被调用之后, 都会向用户返回一个新的游标, 用户在下次迭代时需要使用这个新游标作为 SCAN 命令的游标参数, 以此来延续之前的迭代过程。

 

不可删除情况压缩和拆分key

  1. 当 vaule 是 string 时,比较难拆分,则使用序列化、压缩算法将 key 的大小控制在合理范围内,但是序列化和反序列化都会带来更多时间上的消耗。
  2. 当 value 是 string,压缩之后仍然是大 key,则需要进行拆分,一个大 key 分为不同的部分,记录每个部分的 key,使用 multiget 等操作实现事务读取。
  3. 当 value 是 list/set 等集合类型时,根据预估的数据规模来进行分片,不同的元素计算后分到不同的片。

 

posted @ 2023-04-17 10:03  方达达  阅读(19)  评论(0编辑  收藏  举报