Architure upgrade_DB Sharding
对千万量级且增长量大的核心业务表进行分表,以满足微信小程序toC场景的性能需求:
1.对会员核心业务表做水平切片,由原来存储在一个表分为存储在多个分表。
2.按用户id做sharding,将优惠券数据分表。
测试方式包括:
1. 功能正确性测试 (Functional Correctness Testing)
确保分表逻辑正确,所有业务场景都能正常工作。
- 分片键 (Shard Key) 路由准确性:
- 核心测试点!验证数据是否能根据分片规则(如用户ID取模、范围分片、哈希分片)精确路由到正确的物理表。
- 设计测试用例,覆盖分片键的边界值、典型值和异常值。
- 例如:
user_id % 4 = 0的数据必须写入user_table_0。
- CRUD 操作正确性:
- Create (INSERT): 验证新数据能根据分片键正确写入目标分表。
- Read (SELECT):
- 单分片查询: 根据分片键查询,验证能正确返回目标分表的数据。
- 非分片键查询: 验证无分片键的查询(如按姓名、手机号)是否能通过广播查询 (Broadcast Query) 或全局二级索引 (Global Secondary Index, GSI) 正确执行,并返回完整结果集。
- Update (UPDATE):
- 验证更新操作能定位到正确的分表并更新数据。
- 特别注意: 如果更新操作修改了分片键本身(应尽量避免),验证系统行为是否符合预期(通常不允许或需特殊处理)。
- Delete (DELETE): 验证删除操作能正确删除目标分表中的数据。
- 关联查询 (JOIN) 测试:
- 同库同分片 JOIN: 验证在同一个分片内,关联查询(如订单表和订单明细表按订单ID分片)能否正确执行。
- 跨分片 JOIN: 验证跨不同分片的表关联查询(如用户表和订单表,分片键不同)是否能通过中间件(如 ShardingSphere)或应用层逻辑正确执行。性能通常较差,需评估业务是否允许。
- 聚合查询 (Aggregation) 测试:
- 单分片聚合: 如
SUM,COUNT,MAX,MIN在单个分表上执行,验证结果正确。 - 跨分片聚合: 如
COUNT(*)统计全表总数,SUM(amount)统计总金额。验证中间件能否将聚合操作下推到各分片执行,再将结果合并(Gather),最终返回正确结果。
- 单分片聚合: 如
- 分页查询 (Pagination) 测试:
- 按分片键分页: 相对简单,验证正确性。
- 按非分片键分页 (如 ORDER BY create_time): 复杂且高风险!验证
LIMIT offset, size是否能正确返回全局有序的结果。中间件通常需要从所有分片获取数据,内存中合并排序,性能开销大。测试大数据偏移量下的性能和正确性。
- 事务测试 (Transaction Testing):
- 单分片事务: 验证在同一个分片内,跨多张表的本地事务(ACID)是否正常。
- 跨分片事务: 挑战最大!验证涉及多个分片的分布式事务(通常基于 XA 或柔性事务如 TCC、Saga)是否能保证最终一致性。测试提交、回滚、网络超时、节点故障等场景下的行为。强烈建议业务设计上尽量避免跨分片事务。
2. 数据一致性与迁移验证 (Data Consistency & Migration Validation)
分表通常伴随着数据迁移,这是风险最高的环节。
- 全量数据迁移一致性校验:
- 在迁移完成后,使用校验工具(如开源的
datax,gh-ost的校验功能,或自研脚本)对源表和所有目标分表的数据总量、关键字段的校验和 (Checksum)、主键范围进行比对。 - 抽样检查大量随机记录,确保内容完全一致。
- 在迁移完成后,使用校验工具(如开源的
- 增量数据同步验证:
- 在迁移切换期间,通常有增量同步(如基于 Binlog)。
- 验证增量数据能否实时、准确地同步到对应的分表。
- 模拟切换瞬间的写入,验证数据是否丢失或错乱。
- 回滚方案验证:
- 制定并测试数据回滚方案。如果分表上线后发现问题,能否快速、安全地将数据和流量切回原单表?
3. 性能测试 (Performance Testing)
验证分表是否真正解决了性能瓶颈。
- 基准对比:
- 在分表前(单表)和分表后(分片后),使用相同的性能测试脚本和环境,对比关键指标。
- 关键指标:
- 写入性能 (Write Throughput): 单表写入瓶颈(如 IOPS、锁竞争)是否因数据分散而缓解?TPS 是否提升?
- 读取性能 (Read Performance): 单分片查询的 P95/P99 延迟是否降低?非分片键查询的性能是否有可接受的下降?
- 数据库负载: 单个 MySQL 实例的 CPU、IOPS、连接数、慢查询数量是否显著下降?
- 分片中间件开销: 分析 Sharding 中间件(如 ShardingSphere-Proxy)自身的 CPU、内存、网络开销和延迟增加。
- 高并发压力测试:
- 模拟远超日常的并发量,测试分表系统在极限压力下的表现。
- 验证系统是否能稳定处理,是否存在新的瓶颈(如中间件、网络带宽)。
- 热点分片测试:
- 模拟某个分片(如
user_table_0)成为热点(访问量远超其他分片)。 - 验证该分片所在的数据库实例是否能承受压力,是否存在性能陡降。
- 模拟某个分片(如
4. 稳定性与容错性测试 (Stability & Fault Tolerance Testing)
模拟各种故障,考验分表架构的韧性。
- 单分片数据库故障:
- 模拟某个分片对应的 MySQL 实例宕机。
- 验证:
- 访问该分片的请求是否能被正确处理(如返回错误、降级)?
- 系统其他部分(访问其他分片)是否不受影响,保持可用?(验证故障隔离能力)
- 数据库恢复后,主从复制、服务发现是否正常,系统能否自动恢复?
- 分片中间件故障:
- 模拟 Sharding 中间件(如 ShardingSphere-Proxy 集群)的节点宕机或网络问题。
- 验证集群的高可用性,请求是否能被其他节点接管。
- 网络分区 (Network Partition):
- 模拟网络问题导致某个分片数据库与其他组件(应用、中间件)失联。
- 验证系统的降级和容错策略。
- 扩容/缩容演练 (Scaling Drill):
- 核心运维能力!模拟未来数据量增长,需要增加新分片(如从 4 个分片扩到 8 个)。
- 验证 Resharding (再分片) 过程的自动化脚本或工具是否可靠,数据迁移和流量切换是否平滑,对线上业务影响是否可控(通常要求低峰期、分钟级切换)。
5. 监控与可观测性验证 (Monitoring & Observability Validation)
确保分表后的复杂系统状态是“透明”的。
- 监控指标:
- 每个分片的独立监控: 为每个分表对应的数据库实例配置独立的监控(CPU, IOPS, 连接数, 慢查询, 复制延迟)。
- 中间件监控: 监控 Sharding 中间件的性能(QPS, 延迟, 错误率, JVM 指标)。
- 路由监控: 监控关键业务的 SQL 请求被路由到哪个分片,统计各分片的负载均衡情况。
- 全局聚合监控: 如全表总行数、总数据量,需要通过脚本定期汇总。
- 告警设置:
- 为每个分片数据库、中间件集群设置独立的、合理的告警阈值。
- 设置“热点分片”告警(如某个分片的 QPS/延迟显著高于其他分片)。
- 设置“数据不一致”告警(基于校验任务)。
- 日志与追踪:
- 确保日志中包含分片信息(如
shard_id=user_3),便于问题定位。 - 分布式追踪 (Tracing) 链路中应能清晰看到 SQL 请求被路由到了哪个物理数据库和表。
- 确保日志中包含分片信息(如
6. 回归测试 (Regression Testing)
- 全量回归: 分表是底层存储变更,必须对所有依赖该表的核心业务功能进行全量回归测试,确保没有引入意外的副作用。
- 自动化: 将核心的分表功能测试用例(特别是 CRUD、关键查询)自动化,并集成到 CI/CD 流程中。
总结
千万量级表的分表测试是一项系统工程,必须周密计划、分步实施、充分验证:
- 功能是前提: 确保“能用”。
- 数据一致性是底线: 确保“数据没错”。
- 性能是目标: 确保“更快了”。
- 稳定性是保障: 确保“扛得住”。
- 可观测性是眼睛: 确保“看得见”。
- 可维护性是未来: 确保“能扩容”。
最佳实践是采用影子库/影子表 (Shadow Table) 或 双写 (Dual Write) 策略进行灰度验证,在真实流量下对比新旧逻辑的结果,将风险降至最低。

浙公网安备 33010602011771号