分库分表的数量为什么一般选择2的幂?

一般来说,在很多大厂中,需要做分表的时候,分表的数量都会选择2的幂,比如16、64、128、512、1024等,这么做有什么好处呢?

首先,如果你看过HashMap的hash算法的话,应该知道,HashMap的容量其实也是2的幂,这么做的好处是可以将取模操作改为更加高效的位运算。

因为,hash % 8 相当于 hash & (8-1),所以对于分8个表,可以使用哈希值与7进行按位与操作,这不仅简化了计算,还提升了性能。

所以,使用2的幂作为分表数量的第一个好处,就是可以将取模算法优化成位运算算法。

除了这个好处以外,我们通常分表都是伴随着分库的,比如我们分16个库128张表,这样如果我们的分表数量和分库数量都是2的幂,那么就可以实现均匀分布。128张表就可以均匀的分到16个库中,每个库中有8张表。

所以,使用2的幂作为分表数量的第二个好处,就是可以使得多张分表在多个库中均匀分配。

当我们在做分库分表的时候,必然要考虑的一个问题那就是二次分表的问题,比如我们根据当前的业务发展,计算出可能需要分4张表就够了,但是随着业务增长,可能认为需要更多表才行,这时候如果我们把新的分表数量定位8张表,那么在做数据迁移的时候,就可以只迁移部分数据。

假设我们最开始将订单表分成了4张表,分别是 order_00、order_01、order_02、order_03,这时候假设我们的分表算法是根据 userId 取模。即 userId % 4:

  • order_00:userId % 4 == 0
  • order_01:userId % 4 == 1
  • order_02:userId % 4 == 2
  • order_03:userId % 4 == 3

当数据量增长,需要将表扩展到8个时,需要将算法改为 userId % 8:

新的哈希值计算:

  • order_00:userId % 8 == 0
  • order_01:userId % 8 == 1
  • order_02:userId % 8 == 2
  • order_03:userId % 8 == 3
  • order_04:userId % 8 == 4
  • order_05:userId % 8 == 5
  • order_06:userId % 8 == 6
  • order_07:userId % 8 == 7

而在做增量数据迁移的时候,我们只需要重新分配那些原来在表0、1、2、3中,且哈希值满足 userId % 8 >= 4 的数据进行迁移就好了,userId % 8 的结果在0-3范围内的数据其实是不用动的。

  • 从表0迁移到表4:如果 hash % 8 == 4
  • 从表1迁移到表5:如果 hash % 8 == 5
  • 从表2迁移到表6:如果 hash % 8 == 6
  • 从表3迁移到表7:如果 hash % 8 == 7

也就是说,从4张表扩容到8张表其实只需要迁移一半的数据。而如果不是2的幂,比如说从5张表扩容成9张表,那每个原数据都需要重新计算哈希值并重新分配到新的表中。因为扩展后的表数量不是2的幂次,大多数数据都会被重新分配到不同的表中。

所以,使用2的幂作为分表数量的第三个好处,也是最重要的一个好处,那就是在做数据迁移时只需重新计算和迁移一半数据。这种方法不仅降低了系统扩展的复杂性,还减少了扩展过程中对系统性能的影响。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

全真王重阳

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

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

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

打赏作者

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

抵扣说明:

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

余额充值