
针对TB级用户数据,采用垂直分库(按业务模块拆分)与水平分片(基于ShardingSphere的哈希分片),通过分布式事务(两阶段提交+Saga模式)处理跨库操作,并设计动态扩容与数据迁移方案,确保高并发下的数据一致性与查询效率。
分库分表是为了应对TB级数据,将数据分散到多个数据库实例。垂直分库是将不同业务(如用户信息、浏览记录)拆分到独立库,水平分片是将同一业务的数据按规则(如哈希、范围)拆分到多个表。跨库查询需聚合不同库的数据,事务需保证跨库操作一致性。分片键是核心,决定数据分布。
类比:分库分表就像把用户数据按ID哈希到3个数据库实例,每个实例下再按ID范围分3张表,查询用户123456的浏览记录时,只需访问库0的表0和表1,避免跨库查询延迟。
| 策略 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| 垂直分库 | 按业务模块拆分(如用户库、行为库) | 单库数据量小,查询集中 | 业务模块多,数据量差异大 | 需服务间通信,跨库事务复杂 |
| 水平分片(哈希分片) | 按哈希值分表(如用户ID哈希) | 数据均匀分布,查询本地 | 数据量巨大,需高并发 | 分片键选择影响数据分布 |
| 水平分片(范围分片) | 按范围分表(如时间范围、ID范围) | 数据有序,适合范围查询 | 时间序列数据、有序数据 | 分片键选择影响查询效率 |
假设用户表为user,浏览记录表为behavior,分库分表规则:库按用户ID哈希,表按ID范围分片。
分库分表逻辑:
库编号 = 用户ID % 库数(如3个库:库0、库1、库2);
表编号 = 用户ID % 表数(如每个库下3张表:表0、表1、表2)。
跨库查询示例:
查询用户ID=123456的所有浏览记录,需定位到库0的user_0_0表(用户信息),再从库0的behavior_0_1表(行为记录)读取数据。
跨库事务示例(两阶段提交):
用户注册时,插入user表(库1表1)和behavior表(库1表2):
(约90秒)
“面试官您好,针对TB级用户数据,分库分表的核心策略是结合垂直分库与水平分片。垂直分库按业务拆分,比如用户信息、浏览记录分不同库,水平分片用用户ID哈希分片,保证数据均匀分布。跨库查询时,通过分片键(用户ID)定位到对应库表,再聚合数据,比如查询用户所有浏览记录需要从多个库表读取并汇总。事务处理采用分布式事务,关键业务(如用户注册)用两阶段提交确保强一致性,非关键业务(如浏览记录更新)用Saga模式提高性能。具体来说,比如用户注册时,插入用户表(库1表1)和初始浏览记录(库1表2),事务提交前检查两个操作都成功,否则回滚。这样既能应对数据量增长,又能保证数据一致性和查询效率。”
问:分片键选择时,如何避免数据倾斜?
答:选择业务中分布均匀的键(如用户ID),避免热点数据集中,定期重新哈希调整分片。
问:跨库事务选两阶段提交的话,性能如何?
答:两阶段提交保证强一致性,但可能阻塞,适合关键业务;非关键业务可采用最终一致性,提高性能。
问:分库分表后,如何优化跨库查询?
答:通过预聚合(如物化视图)、分布式查询引擎(如ClickHouse),减少实时聚合的延迟。
问:如果用户数据有更新,分库分表如何保证一致性?
答:通过分布式事务(如两阶段提交),或异步补偿机制,确保更新操作在所有分库分表中同步。