redis 大key问题学习

转自:https://zhuanlan.zhihu.com/p/473542122,https://www.cnblogs.com/cxy2020/p/13748658.html

 https://cloud.tencent.com/developer/article/1660821

1.大key

  • value是String类型时,size超过10KB。(一个字符串类型的value最大可以存储512MB的内容)
  • value是ZSET、Hash、List、Set等集合类型时,它的成员数量超过1w个。(一个列表类型的value最多可以存储2的32次方-1个元素)

主要是根据value的成员数量和字节数来确定。

2.影响

redis核心工作线程是单线程,串行执行,也导致分布式架构中内存数据和CPU的不平衡。

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

阻塞线程,并发量下降,导致客户端超时,服务端业务成功率下降

3.解决

 删除:大key并非热key就可以在DB中查询使用,则可以在Redis中删掉。

  • 当Redis版本大于4.0时,可使用UNLINK命令安全地删除大Key,该命令能够以非阻塞(异步,惰性删除,del是同步)的方式,逐步地清理传入的Key。
  • 当Redis版本小于4.0时,避免使用阻塞式命令KEYS,而是建议通过SCAN命令执行增量迭代扫描key,然后判断进行删除。

压缩和拆分:

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

在Redis中,要特别注意复杂度为O(n)的操作,这类操作一般时间较长,很容易阻塞Redis,在集群环境下极易发生故障切换。

4.存储原理

key和value都是存储在DictEntry中的。所以基本上来说,大key和大value带来的内存不均和网络IO压力都是一致的,只是key相较于value还多一个做hashcode和比较的过程(链表中进行遍历比较key),会有更多的内存相关开销。

 

posted @ 2023-03-06 08:58  lypbendlf  阅读(55)  评论(0编辑  收藏  举报