【分库分表】什么是数据倾斜?会带来哪些问题?如何解决?

目录

一、什么是数据倾斜?

二、数据倾斜会带来哪些问题?

三、如何解决?

3.1 拆分

3.2 隔离


一、什么是数据倾斜?

数据倾斜是指在分布式计算或数据库环境中,数据分布不均匀的现象。在理想的分布式系统中,数据和计算负载应该均匀分布在所有节点上。然而,由于各种原因,某些节点可能承载比其他节点更多的数据或计算负载,这就是数据倾斜。

比如一个系统中共有500万数据,但是属于同一个商家的数据就有400万,那么如果数据库按照商家做分库分表,就会导致出现严重的数据倾斜。

一般来说,数据倾斜发生在分库分表的场景中比较多,因为主要是因为分表字段选择的不够合适导致的。你比如说我之前做过一个定价系统,然后我们是按照付款方做的分库分表。原来都挺好的,同一个用户的付款也不会有什么特别多的数据,但是后来出现了一种机构付款的情况,有一个商户作为付款方了,那么就会导致这个商户的数据有很多,就会大量的堆积在同一张表中,就导致这个表数据量剧增。

二、数据倾斜会带来哪些问题?

数据倾斜主要会带来以下几个问题:

  1. 性能瓶颈:数据倾斜可能导致某些节点的负载明显高于其他节点,从而成为整个系统的性能瓶颈。比如在Redis中,出现的热key问题,其实也是数据倾斜的一种具体情况,那么就会导致这个节点的负载非常高。

  2. 资源利用不均:导致资源利用不均衡,一部分节点可能过载,而其他节点则闲置。

  3. 查询效率低下:在数据库中,数据倾斜可能导致查询效率低下,特别是在执行JOIN操作或聚合查询时。比如数据库分表后数据倾斜,就会使得分表的效果并不明显,单表的数据量还是可能会很大,导致查询速度变慢。

  4. 影响其他业务:某些数据倾斜会导致查询比较慢,这样不仅使这个业务有影响,和他在同一张表中的其他业务的数据也会有影响。比如某个小商家和一个大商户的数据在同一张表,那么它的查询也会变慢。

所以,我们在做分库分表的时候,在选择分表字段的时候,一定要考虑数据倾斜的问题,尽量选择那种不会有聚集性数据的字段来做分表字段,如订单表,尽量选择买家ID。

三、如何解决?

要解决数据倾斜的问题,其实和解决单表数据量大是同样的方案,无非就是把数据拆分一下,分散数据量。

3.1 拆分

比如在Redis中,为了解决热key的问题,可以采用Cluster模式,把一个大key拆分到多个实例上存储。

还有就是在分库分表场景,那就是做一下二次分表。

比如我之前提的那个定价记录表付款方严重倾斜的问题,为了解决它,我修改了一下我的路由算法。如果付款方式机构类型,那么我在分表时就会把时间因素考虑进去。基于时间在做一次分表。

// 为了解决机构账户的热点问题,这里对于付款方是机构的情况做特殊处理,拼接时间戳后进行分表
switch (customerTypeEnum) {
    case INSTITUTION_NAME:
        externalId = quotationDO.getPayerId() + DateUtils.truncate(quotationDO.getBizTime());
        break;
    default:
        externalId = quotationDO.getPayerId();
}

// 这里再基于externalId做哈希取模

或者如果付款方一样,那么就基于收款方再做一次分表。这样后续每一次的插入、查询、更新都用同一个分表算法就行了。算法内部自己把这个逻辑包掉就可以了。

只不过在查询的时候,就需要的信息就会多一些,以前可能根据一个付款方就够查询了,因为只需要这一个字段就能知道会路由到哪张表,但是修改之后,就需要付款方、付款方类型以及时间戳三个字段了。就会使得查询更加麻烦一些,当然也不是所有查询都需要,只有热点账户相关的才需要,非热点的并不需要。

3.2 隔离

除了做二次分表或者数据拆分以外,还有一个办法,为了降低因为数据倾斜而带来的影响,有的时候我们也会采取物理隔离的方式。

所谓物理隔离,其实就是把这个严重倾斜的商户的数据,单独独立出来放到一个单独的数据库中。

这样既可以降低对其他用户的影响,又可以单独给这个数据库增加配置,提升可用性。

这样做只不过会带来一些额外的成本,并且需要应用在数据库访问的时候动态决策具体去哪个表中做查询,在分表算法中需要做一些定制逻辑。

  • 15
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

全真王重阳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值