题目:分库分表的数量为什么一般选择 2 的幂?
难度:medium
标签:db/sharding, general/knowledge, difficulty/medium
评分:⭐⭐⭐☆☆(3/5)
其实计算机里大部分的设计,比如说数据方面的计算统计方面,都会选择 2^m 进行处理。首先 2^m 是更符合数据的计算机计算的逻辑,因为计算机本身所有的数据衍生都是基于二进制的,2^m 次方更容易被计算机处理。另外就是 2^m 可以更好的用于进行扩展计算。比如选择一次性哈希的时候,2^m 你做扩容的时候,二次扩容,比如说 2,两个分片到 4 个分片,4 个分片到 8 个分片,你要移动的分片相对数量都会比较少。基本上 1~4,4 的分片,1~8 的分片,你要移动的数据只有一半。如果选择其他数据,可能移动的数据要更大量。扩容的时候,选择 2 的幂次进行分片,可以减少扩容时数据的迁移。
优点:
不足:
补充:
核心考点定位:能否穿透"2 的幂是计算机习惯"的表层,讲清取模扩容的数学本质和工程收益。
知识点拆解:
hash(x) & (N-1) 等价于 hash(x) % N,仅当 N 是 2 的幂时才成立hash(x) % N,新分片号 = hash(x) % (N+1),两者几乎无关)N=4 → N=5 迁移约 80%;N=8 → N=9 迁移约 88.9%s_old = hash(x) % (2N),新分片号 s_new = hash(x) % (4N)s_new 要么等于 s_old,要么等于 s_old + 2N(因为 hash(x) = s_old + k * 2N,取模 4N 后只有两种结果)hash(x) & (N-1),纳秒级完成考察方向:
延伸递进面试题:
hash(x) & (N-1) 和 hash(x) % N 什么时候等价?7 & 3 = 3,7 % 4 = 3 巧合对,但 6 & 3 = 2,6 % 4 = 2 又对,11 & 3 = 3,11 % 4 = 3 对,5 & 3 = 1,5 % 4 = 1 对——只有 2 的幂稳定等价)hash(x) % 8 vs hash(x) % 12,理论上所有数据都要重新映射,只有 hash(x) % 24 同时被 8 和 12 整除时才不迁,约 8.3% 不迁面试官您好,选 2 的幂做分片数,表面看是"计算机喜欢 2",真正的核心原因是扩容时的数据迁移成本可控。
先看数学本质。假设我们用取模做路由:shard = hash(x) % N。当 N 从 8 扩到 9 时,几乎每一条数据的分片号都要重新算——hash(x) % 8 和 hash(x) % 9 的关系是随机无关的,迁移比例接近 100%。这个代价是不可接受的。
但如果 N 从 8 扩到 16(翻倍),迁移比例只有 50%。为什么?因为 hash(x) % 8 = s 意味着 hash(x) = s + k * 8,扩到 16 后 hash(x) % 16 只有两种结果:s 或 s + 8。所以每条数据最多迁一次,一半数据根本不用动。这就是 2 的幂的核心优势——翻倍扩容时迁移比例恒定为 50%,其他倍数扩到 N+1 会逼近 100%。
第二层是位运算优化。当 N 是 2 的幂时,hash(x) % N 可以写成 hash(x) & (N-1)——位与运算比模运算快得多(除法要几十周期,位运算是 1 周期)。这个优化在路由层高频计算时非常关键,尤其是网关、缓存、分片中间件这些路径上。
第三层是工程侧的收益:
但要提醒一点:2 的幂不是必须。如果业务规模固定不打算扩(比如内网系统),选 100 分片也没问题;如果分片键是时间段(Range 分片),扩容代价本来就不高,也不受这个约束。
对比反例:假设某业务从 8 分片扩到 100 分片。理论迁移比例 = 100%,因为 hash(x) % 8 和 hash(x) % 100 几乎完全独立。这种情况下要么一次性全表迁,要么用一致性哈希。所以我们团队的规定是:新业务上分片前,先估 3-5 年后的目标分片数,选一个 2 的幂,一次到位,后续只翻倍。
一句话总结:2 的幂让扩容从"不可控的全表重映射"变成"可控的翻倍迁移",是低成本水平扩展的数学基石。