前言
在我们的开发过程中,经常会使用 Redis 作为分布式缓存组件。Redis 缓存数据非常轻量,但是如果我们设计技术方案和使用过程中不加以注意,一定程度上会对 Redis 性能造成影响。一般来说,我们往 Redis 里的某个 key 存储的数据越多,查询 key 对应的 value 时的速度就会越慢。
什么是大 Key
大 Key 并不是指 Key 很大,而是指 Key 对应的 Value 值太大。所谓的 Redis 大 key 指的是 key 的 value 占用的存储空间较大或 hash/set/zset/list 等数据结构中元素的数量过多,官方定义的标准为:
- string 数据结构的value大于 10kb
- hash/set/zset/list 等数据结构中元素个数大于 5000 个
- hash/set/zset/list 等数据结构中单个 key 的整体 value 大于 10 MB
大 Key 可能造成的影响
我们都知道,由于 Redis 网络请求模块和数据处理模块是单线程的,当访问大 Key 时,可能会比较长的时间才能够返回数据,请求阻塞的时间较长会一定程度地影响到其他请求,往往表现为请求超时。 因此,大 Key 会造成超时阻塞和网络拥塞等问题。
如何解决大 Key 问题
1. 拆分大 Key
原理其实很简单,我们对于数据量大的表,一般会采用分库分表的方式解决。同理,对于大 Key 问题,我们同样也可以用拆分 Key 的方式来解决。大 key 的拆分需要结合具体业务场景,将大 key 逐步拆分成为小 key。
一般的方法是:
- 对于 string 数据结构可以尝试将对象分拆成几个 key-value 进行存储,读取的时候在业务代码中遍历拆分后的 Key 获取即可。如果该 string 对象仅需要读写部分数据,可以考虑将其存储在 hash 数据结构中,通过 hget 和 hset 来读写部;
- 对于 hash/set/zset/list 中存储过多的元素可以对存储元素按一定规则进行分类和拆解。
2. 压缩 value
上面的方法是对 Key 进行拆分,这种方法是对 value 值进行压缩。在写入 Redis 时,把我们比较大的value值进行压缩;然后在读取时,通过特定的解压算法再来进行解压。压缩算法可以自己根据业务要求选取。