ShardingSphere 分库分表实战
候选人小周在面试某互联网公司时,面试官看了他的项目经验"负责订单库拆分",问道:
"你们的订单库是怎么拆的?按什么字段分的片?"
小周说:"按用户 ID 取模分的,拆了16个库,每库16张表。"
面试官追问:"为什么是16不是32?取模和哈希分片有什么区别?"
小周说:"呃...感觉16差不多够用了..."
面试官追问:"那如果用户查自己的订单,要查多少张表?"
小周愣了一下:"要查16*16=256张表?"
面试官说:"不是。你分片键是用户ID,查用户订单只用查1个分片。换个问题:如果按订单ID分片,用户查订单会怎么样?"
小周答不上来了。
【面试官心理】 这道题我用来区分"做过拆分"和"理解拆分原理"的候选人。知道按用户ID分的占60%,能讲清楚分片键选择原则的占30%,能说出分片键选错后的查询放大问题的只有10%。分片键的选择是分库分表的核心,这道题能答到最后的,基本都有实际的生产经验。
一、分库分表的核心问题 🔴
1.1 为什么要分库分表
1.2 ShardingSphere 的两种模式
二、分片策略详解 🔴
2.1 四种标准分片算法
2.2 标准分片策略:分库 + 分表
2.3 分片键的选择原则 🔴
这是面试官最爱追问的点。
查询放大问题是分库分表最常见的翻车点:
- 按
order_id分片:查单条订单只需查1个分片(最优) - 按
user_id分片:查单用户订单只需查1个分片(OK) - 按
status分片:查某个用户的待支付订单需要查所有分片(灾难) - 不加分片键(扫全部分片):所有跨分片查询都要扫全部
所以分片键一定要选查询条件中高频且等值的字段。
2.4 绑定表:减少 JOIN 时的分片扫描
三、分布式主键生成器 🔴
3.1 为什么要自定义主键生成器
3.2 雪花算法的原理
3.3 时钟回拨问题
四、分页查询的坑 🔴
4.1 跨分片分页的困境
4.2 SHARDINGSPHERE-4813:分页问题
分页查询的坑在生产环境中非常容易翻车。用户翻到第100页,结果和第1页的数据完全不在同一个时间范围内。解决方案:尽量带上分片键查询,或者使用"上一页最后一条的ID"做游标分页。
五、数据迁移方案 🟡
5.1 全量迁移
5.2 增量数据同步
六、面试追问链 🟡
追问一:分库分表后,跨库 JOIN 怎么处理?
【面试官心理】 问这个问题的面试官,通常是想看候选人有没有踩过跨库查询的坑。能说出"在应用层聚合"和"ES方案"的,通常有实战经验。
追问二:分片数量怎么确定?
【面试官心理】 能回答出"先按预估数据量算,预留扩容空间"的候选人,说明他有容量规划意识。我会继续追问:"如果预估错了,扩容怎么办?"能说出"一致性哈希扩容"或"4库4表逐步扩容"的,说明他对扩容有实战经验。
常见做法:
- 单表数据量控制在 500 万以内
- 分片数量 = 预估总数据量 / 500万 / 库数
- 预留 2-3 倍的扩容空间
- 使用 Mod 取模,扩容时需要做数据迁移
- 使用一致性哈希,扩容时只需迁移部分数据(但查询复杂度增加)
追问三:ShardingSphere-Proxy 和 ShardingSphere-JDBC 选哪个?
【面试官心理】 能权衡出"多语言支持"和"性能"的候选人,说明他有架构视角。