文档

如何处理Redis集群数据倾斜

更新时间:

Redis集群中,若个别数据分片节点(Data Node)的内存使用率或CPU使用率、带宽使用率、延时等性能指标远远高于其他数据分片,该Redis集群可能已产生数据倾斜。数据倾斜严重时,会导致实例在整体内存使用率不高的情况下,发生内存逐出(Key eviction)、内存溢出OOM(Out Of Memory)、实例响应时间上升等异常情况。

为什么会产生数据倾斜

Redis集群架构作为一个分布式系统,整个数据库空间会被分为16384个槽(Slot),每个数据分片节点将存储与处理指定Slot的数据(Key),例如3分片集群实例,3个分片分别负责的Slot为:[0,5460]、[5461,10922]、[10923,16383]。当用户写入或更新数据时,客户端会通过CRC算法计算出Key所属的Slot,具体公式为Slot=CRC16(key)%16384,并将数据写入Slot所属的数据分片节点。通常情况下,各数据分片节点的Key数量是均匀分布的,同时内存使用率、CPU使用率等性能指标也是相近的。

但在使用数据库的过程中,可能会由于前期规划不足、不规范的数据写入及突发的访问量,造成数据量倾斜或数据访问倾斜,最终引起数据倾斜。

说明

数据倾斜通常是指大多数据分片节点的性能指标较低,而个别节点的性能指标较高的情况,高或低没有明确的标准。

您可以在性能监控数据节点页面中查看各数据分片节点的对应指标,通常情况下,若某数据分片节点(最高)的性能指标高出其他数据分片节点(最低)20%及以上时,可认为已产生数据倾斜,差值越大,数据倾斜程度越严重。

下图介绍两个典型的数据倾斜场景,如下图所示,虽然Key均匀地分布在集群中,每个数据分片节点2个Key,但仍产生了数据倾斜:

热key

  • Replica 1节点中key1的QPS明显高于其他Key,属于典型的数据访问倾斜,会导致该Key所在的数据分片节点CPU使用率、带宽使用率升高,从而影响该分片上所有Key的处理。

  • Replica 2节点中key5的QPS虽然不高,但该Key的大小为1 MB,属于典型的数据量倾斜,会导致该Key所在的数据分片节点的内存使用率、带宽使用率升高,从而影响该分片上所有Key的处理。

本文介绍如何确认是否存在数据倾斜,以及导致数据倾斜的原因和处理方法。同时,本文也适用于排查标准架构内存使用率、CPU使用率、带宽使用率和延迟等性能指标高的问题。

如何确认是否存在数据倾斜

  • 使用实例诊断功能(推荐),一键排查当前实例是否存在倾斜的情况。

  • 在实例的性能监控 > 数据节点页面中查看各数据分片节点的对应指标,具体操作请参见查看性能监控

数据倾斜的临时方案

若实例已产生数据倾斜,您可以通过如下临时方案进行过渡,但以下临时方案无法解决数据倾斜的根源问题。

同时,您也可以在短时间内可降低大Key、热Key的请求量,暂缓数据倾斜问题,但大Key、热Key问题只能通过业务上的改造才能解决。建议您及时对实例进行数据倾斜的原因排查,并根据对应处理方法在业务层进行改造,对实例进行优化,更多信息请参见数据倾斜的原因与处理方法

倾斜场景

可能原因

临时方案

内存倾斜

大Key、Hash Tags。

升级实例规格,具体操作请参见变更实例配置

重要
  • 变配时Redis会进行数据倾斜预检查,若您选择的实例规格无法解决内存倾斜问题,Redis会进行拦截与报错,请您调大实例规格后重试。

  • 在成功升级实例规格后,会改善内存倾斜问题,但可能也引起带宽倾斜或CPU倾斜。

带宽倾斜

大Key、热Key、高消耗命令。

提升实例中指定1个或多个分片的带宽,具体操作请参见手动增加实例带宽

说明

由于单个实例分片最多可额外增加原实例默认带宽的6倍但不能超过192MB/s。若业务流量仍大于该值,则只能在业务层进行改造。

CPU使用率倾斜

大Key、热Key、高消耗命令。

无临时方案,请进行原因排查并在业务层进行改造。

数据倾斜的原因与处理方法

请提前规划业务增长率,合理地拆分大Key,并保持规范的数据写入,才能解决数据倾斜的根源问题。

产生倾斜原因

说明

处理方法

大Key

大Key通常以Key的大小和Key中成员的数量来综合判定。

常见于在KKV(Key-key-value)类型的数据结构中,例如Hash、List、Set、Zset等,存放过多或过大的field,从而导致单个Key过大,产生实例数据倾斜。更多关于大Key的信息,请参见发现并处理Redis的大Key和热Key

  • 避免使用大Key。

  • 对大Key进行拆分,例如将含有数万成员的一个HASH Key拆分为多个HASH Key,并确保每个Key的成员数量在合理范围。

热Key

热Key指某个Key或者少部分Key的操作QPS明显高于其他Key。常见于压测时选了单一Key或秒杀场景下热点商品ID Key。更多关于热key信息,请参考发现并处理Redis的大Key和热Key

  • 请避免使用热Key。

  • 使用Tair的QueryCache特性,缓存热点数据,更多信息请参见优化大Key与热Key

高消耗命令

不同的命令具有不同的复杂度,高复杂度的命令会消耗大量性能资源,例如HGETALL命令的复杂度为O(n),该命令会随着您存储的Field越多,消耗越大。同时,简单的SETGET命令也会在Value过大时,消耗大量数据分片节点的性能资源。

  • 可通过查询慢日志功能查询数据分片节点的慢日志。

  • 业务侧需减少或禁止使用高消耗命令,如需禁用命令,可以在参数设置中配置#no_loose_disabled-commands参数。

Hash Tags

若Key名称中包含{},例如{item}id1,则Tair仅会对{}中的内容进行Slot计算并选择数据分片节点。若存在{item}id1{item}id2{item}id3等等大量Key,由于{}中的内容相同,上述Key均会被分配至同一数据分片节点,导致该数据分片节点的内存资源、性能消耗大幅升高。

  • 避免在Key名称中使用{}

    说明

    如需在Key名称中使用{},需保证{}中的内容尽可能不同,从而使Key尽量均匀地分布在集群的不同数据分片节点上。