Redis大Value

大 key 和大 value 的危害,如何处理

Redis 的大 key 有什么危害?
一个 key 的 value 较大时的情况,比如:

  • 内存不均:单 value 较大时,可能会导致节点之间的内存使用不均匀,间接地影响 key 的部分和负载不均匀;
  • 阻塞请求:redis 为单线程,单 value 较大读写需要较长的处理时间,会阻塞后续的请求处理;
  • 阻塞网络:单 value 较大时会占用服务器网卡较多带宽,可能会影响该服务器上的其他 Redis 实例或者应用。

虽说答的是挺好的,但是我又随之产生了另一个疑惑,如果 redis 的 key 较长时,会产生什么样的影响呢?查了很多文章,说的都不是特别清楚。所以我决心探究一下这个问题。

我们需要知道 Redis 是如何存储 key 和 value 的:
根结构为 RedisServer,其中包含 RedisDB(数据库)。
而 RedisDB 实际上是使用 Dict(字典)结构对 Redis 中的 kv 进行存储的。这里的 key 即字符串,value 可以是 string/hash/list/set/zset 这五种对象之一。
image.png

Dict 字典结构中,存储数据的主题为 DictHt,即哈希表。而哈希表本质上是一个 DictEntry(哈希表节点)的数组,并且使用链表法解决哈希冲突问题(关于哈希冲突的解决方法可以参考大佬的文章 解决哈希冲突的常用方法分析)。
所以在这里实际存储时,key 和 value 都是存储在 DictEntry 中的。
所以基本上来说,大 key 和大 value 带来的内存不均和网络 IO 压力都是一致的,只是 key 相较于 value 还多一个做 hashcode 和比较的过程(链表中进行遍历比较 key),会有更多的内存相关开销。
结论:

  1. 大 key 和大 value 的危害是一致的:内存不均、阻塞请求、阻塞网络。
  2. key 由于比 value 需要做更多的操作如 hashcode、链表中比较等操作,所以会比 value 更多一些内存相关开销。

如何处理?
Redis 大 key
Redis 使用过程中经常会有各种大 key 的情况, 比如:

  1. 单个简单的 key 存储的 value 很大
  2. hash, set,zset,list 中存储过多的元素(以万为单位)

由于 redis 是单线程运行的,如果一次操作的 value 很大会对整个 redis 的响应时间造成负面影响,所以,业务上能拆则拆,下面举几个典型的分拆方案。

业务场景:
即通过 hash 的方式来存储每一天用户订单次数。那么 key = order_20200102, field = order_id, value = 10。那么如果一天有百万千万甚至上亿订单的时候,key 后面的值是很多,存储空间也很大,造成所谓的大 key。

大 key 的风险: 1.读写大 key 会导致超时严重,甚至阻塞服务。 2.如果删除大 key,DEL 命令可能阻塞 Redis 进程数十秒,使得其他请求阻塞,对应用程序和 Redis 集群可用性造成严重的影响。

redis 使用会出现大 key 的场景: 1.单个简单 key 的存储的 value 过大;
2.hash、set、zset、list 中存储过多的元素。

解决问题: 1.单个简单 key 的存储的 value 过大的解决方案:
将大 key 拆分成对个 key-value,使用 multiGet 方法获得值,这样的拆分主要是为了减少单台操作的压力,而是将压力平摊到集群各个实例中,降低单台机器的 IO 操作。
2.hash、set、zset、list 中存储过多的元素的解决方案:

  1. 类似于第一种场景,使用第一种方案拆分;
  2. 以 hash 为例,将原先的 hget、hset 方法改成(加入固定一个 hash 桶的数量为 10000),先计算 field 的 hash 值模取 10000,确定该 field 在哪一个 key 上。
    将大 key 进行分割,为了均匀分割,可以对 field 进行 hash 并通过质数 N 取余,将余数加到 key 上面,我们取质数 N 为 997。
    那么新的 key 则可以设置为:
    newKey = order_20200102_String.valueOf( Math.abs(order_id.hashcode() % 997) )
    field = order_id
    value = 10
    hset (newKey, field, value) ;
    hget(newKey, field)
https://alicharles.oss-cn-hangzhou.aliyuncs.com/static/images/mp_qrcode.jpg
文章目录