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) 测试:
    • 单分片聚合: 如 SUMCOUNTMAXMIN 在单个分表上执行,验证结果正确。
    • 跨分片聚合: 如 COUNT(*) 统计全表总数,SUM(amount) 统计总金额。验证中间件能否将聚合操作下推到各分片执行,再将结果合并(Gather),最终返回正确结果。
  • 分页查询 (Pagination) 测试:
    • 按分片键分页: 相对简单,验证正确性。
    • 按非分片键分页 (如 ORDER BY create_time): 复杂且高风险!验证 LIMIT offset, size 是否能正确返回全局有序的结果。中间件通常需要从所有分片获取数据,内存中合并排序,性能开销大。测试大数据偏移量下的性能和正确性。
  • 事务测试 (Transaction Testing):
    • 单分片事务: 验证在同一个分片内,跨多张表的本地事务(ACID)是否正常。
    • 跨分片事务: 挑战最大!验证涉及多个分片的分布式事务(通常基于 XA 或柔性事务如 TCC、Saga)是否能保证最终一致性。测试提交、回滚、网络超时、节点故障等场景下的行为。强烈建议业务设计上尽量避免跨分片事务。

2. 数据一致性与迁移验证 (Data Consistency & Migration Validation)

分表通常伴随着数据迁移,这是风险最高的环节。

  • 全量数据迁移一致性校验:
    • 在迁移完成后,使用校验工具(如开源的 dataxgh-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 流程中。

总结

千万量级表的分表测试是一项系统工程,必须周密计划、分步实施、充分验证:

  1. 功能是前提: 确保“能用”。
  2. 数据一致性是底线: 确保“数据没错”。
  3. 性能是目标: 确保“更快了”。
  4. 稳定性是保障: 确保“扛得住”。
  5. 可观测性是眼睛: 确保“看得见”。
  6. 可维护性是未来: 确保“能扩容”。

最佳实践是采用影子库/影子表 (Shadow Table) 或 双写 (Dual Write) 策略进行灰度验证,在真实流量下对比新旧逻辑的结果,将风险降至最低。

posted @ 2025-08-29 18:02  bestsarah  阅读(7)  评论(0)    收藏  举报