数据倾斜

数据倾斜有两类。

  • 数据量倾斜:在某些情况下,实例上的数据分布不均衡,某个实例上的数据特别多。
  • 数据访问倾斜:虽然每个集群实例上的数据量相差不大,但是某个实例上的数据是热点数据,被访问得非常频繁。

数据量倾斜

  1. bigkey 导致倾斜

    bigkey 的 value 值很大(String 类型),或者是 bigkey 保存了大量集合元素(集合类型),会导致这个实例的数据量增加,内存资源消耗也相应增加。

    解决方法:

    • 我们在业务层生成数据时,要尽量避免把过多的数据保存在同一个键值对中。
    • 如果 bigkey 正好是集合类型,我们还有一个方法,就是把 bigkey 拆分成很多个小的集合类型数据,分散保存在不同的实例上。
  2. Slot 分配不均衡导致倾斜

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

    解决方法:

    • 在分配之前,我们就要避免把过多的 Slot 分配到同一个实例。
    • 如果已经分配,可以对不合理的slot进行迁移
  3. Hash Tag导致倾斜

    Hash Tag 是指加在键值对 key 中的一对花括号{}。这对括号会把 key 的一部分括起来,客户端在计算 key 的 CRC16 值时,只对 Hash Tag 花括号中的 key 内容进行计算。(也就是同一个Hash Tag会被映射到同一个Slot上)

    问题:但是,使用 Hash Tag 的潜在问题,就是大量的数据可能被集中到一个实例上,导致数据倾斜,集群中的负载不均衡

    建议:如果使用 Hash Tag 进行切片的数据会带来较大的访问压力,就优先考虑避免数据倾斜,最好不要使用 Hash Tag 进行数据切片。

数据访问倾斜

发生数据访问倾斜的根本原因,就是实例上存在热点数据。

解决方法:

采用热点数据多副本的方法,把热点数据复制多份,在每个数据副本的key中增加一个随机前缀,让它和其他副本数据不会映射在同一个Slot中。这样热点数据的访问压力就可以分摊到不同的实例上。

但是这种多副本的方法只能针对只读的热点数据,如果是有读有写的热点数据只能给实例增加资源了。

小结

image-20230407161459345