redis 数据倾斜

什么是数据倾斜

Redis 数据倾斜指的是在 Redis 集群中,某些节点的负载过高,而其他节点负载较轻的情况。负载包括数据量的负载和访问量的负载,譬如实例上的数据分布不均衡,某个实例上的数据特别多。在或者某个实例上的数据是热点数据,被访问得非常频繁。这些都是数据倾斜的问题,严重会影响到 Redis 性能和稳定性。

数据量倾斜原因和解决方法

Hash Tag

Hash Tag 是 Redis 中的一个客户端特性,用于在使用哈希键时对键名进行分组,Hash Tag是一个由花括号包围的字符串,例如:{tag}key。在 Redis 中,如果一个键名包含Hash Tag,Redis会将 Hash Tag 中的字符串作为分组标识,在计算 key 的 CRC16 值时只对分组标识进行计算,将其余部分作为键名。这样,具有相同 Hash Tag 的键会被分配到同一个哈希槽中,从而避免了键名哈希不均匀的问题。

譬如 user:profile:{3231} 和 user:order:{3231} 的 Hash Tag 一样,都是 3231,客户端只会对 3231 进行 CRC16 取模计算计算哈希槽,所以他们都会在一个哈希槽中。

Hash Tag 主要是用在 Redis Cluster 和 Codis 中,支持事务操作和范围查询,Hash Tag 把要执行事务操作或是范围查询的数据映射到同一个实例上,这样就能很轻松地实现事务或范围查询了。

如果是由 Hash Tag 导致的数据倾斜可能就需要在业务层面做些调整。或者使用自定义哈希函数来替代默认的 CRC16 算法。

bigkey

如果某台实例上有许多bigkey。譬如值很大的 string 类型,或者大量集合元素。也会导致实例的内存消耗增加。而且 bigkey 的操作一般都会造成实例 IO 线程阻塞,如果 bigkey 的访问量比较大,就会影响到这个实例上的其它请求被处理的速度。

对于 bigkey 可以在业务层对 key 进行拆分,尽量不要把打过多的数据放在一个 key 中,如果是集合类型,可以通过把数据分组保存在不同的实例上,譬如一个集合存了100w用户Id,可以把这个 key 通过 id 把100w 数据分10分,譬如大于1小于100000的在 user:1:set,大于100000小于200000在user:2:set。可以避免访问bifkey带来的访问压力。

对于 string 类型建议大小为几 KB 到几十 KB 之间,最好不要超过300 KB,对于集合类型的需要根据场景来看,如果是比较复杂的元素建议譬如 Hash 来保存用户的信息这种,建议不要超过5000个,如果是单存保存的一些简单的信息,譬如只记录用户的Id,建议在50w内。

Slot 分配不均衡

没有均衡地分配 Slot,就会有大量的数据被分配到同一个 Slot 中,而同一个 Slot 只会在一个实例上分布,这就会导致,大量数据被集中到一个实例上,造成数据倾斜。

这个情况重新分配哈希槽就可以了。可以通过命令进行重新分配。

内存碎片

当实例长时间运行频繁的内存分配和释放操作,导致一些内存块被分配和释放多次,从而在内存中形成了很多不连续的小块,这些小块的总和虽然足够大,但是无法满足某些 Key 的分配请求,也会导致数据倾斜。

info 命令中 mem_fragmentation_ratio 表示Redis当前的内存碎片率,它是 used_memory_rss(操作系统中内存占用量) 和 used_memory(内存使用量) 相除的结果 该值越高,表示内存碎片越严重。正常值在1到1.5之间。如果大于1.5表示碎片已经超过50%。就需要采取一些手段降低碎片率。

清理内存碎片简单就是搬家让位,合并空间,有下面几种方式方式:

  1. 重启 Redis:通过重启 Redis 服务来清理 Redis 中的碎片。在 Redis 服务重启后,所有的内存会被完全释放,并重新初始化内存布局,这样可以避免碎片的问题。
  2. 主动碎片整理(Active Defragmentation):Redis 4.0 以上的版本提供的新特性.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # 启用主动碎片整理
    activedefrag yes
    # 内存碎片的字节数达到 100MB 时,开始清理。
    active-defrag-ignore-bytes 100mb
    # 当碎片超过 10% 时,开启内存碎片整理
    active-defrag-threshold-lower 10
    # 表示自动清理过程所用 CPU 时间的比例不低于 25%,保证清理能正常开展。·
    active-defrag-cycle-min 25
    # 表示自动清理过程所用 CPU 时间的比例不高于 75%,一旦超过,就停止清理
    active-defrag-cycle-max 75

访问倾斜原因和解决方法

访问量倾斜主要原因多数都是实例上的热点数据太多了,导致实例的访问量远超其他的实例。

如果只是只读的热点数据,可以在业务层给 key 进行分片,譬如可以在 key 中加入随机的前缀,让它和其它副本数据不会被映射到同一个 Slot 中,这样一来,热点数据访问压力就会被分配到不同的实例上面了。

如果是需要读写的数据就不适合采用多副本方法了,因为要保证多副本间的数据一致性,会带来额外的开销。对于有读有写的热点数据,就要给实例本身增加资源了,例如使用配置更高的机器,来应对大量的访问压力。

最后

在构建切片集群时,尽量使用大小配置相同的实例(例如实例内存配置保持相同),这样可以避免因实例资源不均衡而在不同实例上分配不同数量的 Slot。


redis 数据倾斜
http://example.com/posts/42674.html
作者
她微笑的脸y
发布于
2023年4月11日
许可协议