动态分片扩容时,如何做到秒级迁移并保证零数据丢失

解读

国内互联网场景下,分片(Sharding)多指“水平分片+分布式 KV/文档/关系型数据库”的横向扩展方案,如 MySQL 分库分表、TiDB、PolarDB-X、MongoDB Sharded Cluster、Redis Cluster 等。
“动态扩容”意味着业务不停写、读 QPS 持续高位(大促、直播、红包)。
“秒级迁移”要求单分片数据量在百 GB 级别时,整个 rebalance 过程对业务 RT 的扰动不超过 1 秒。
“零数据丢失”必须满足金融级合规(人行《分布式数据库技术金融应用规范》RPO=0)。
面试官真正想听的是:

  1. 如何量化“秒级”——用哪些指标、压测模型、灰度策略证明?
  2. 如何量化“零丢失”——用哪些一致性协议、校验手段、对账机制兜底?
  3. 性能测试工程师在整个生命周期里扮演什么角色?不是背八股,而是给出可落地的测试方案、风险清单和复盘报告。

知识点

  1. 数据迁移三阶段:快照导出 → 增量追平 → 流量切换。
  2. 一致性模型:线性一致、因果一致、最终一致;国内金融场景必须线性一致,需依赖 Paxos/Raft 或分布式事务(Percolator、2PC、XA)。
  3. 秒级关键路径:
    a. 快照阶段:采用分布式一致性快照(CSI)+ 并行 dump,单线程限速 200 MB/s,避免打满 I/O。
    b. 增量阶段:基于 Raft Learner/Follower 或 Change Stream,拉取 binlog/oplog,内存级回放;通过 back-pressure 控制 lag < 1 秒。
    c. 切换阶段:利用权重 DNS / 数据库层原子性路由变更(如 PolarDB-X 的 CDC + Lizard 事务),切换耗时 < 300 ms。
  4. 零丢失四道闸:
    ① 迁移前:全量 checksum + 行级 CRC;
    ② 迁移中:双写对账(shadow table)、幂等写入;
    ③ 切换时:分布式锁 + 一致性快照位点校验;
    ④ 切换后:24 h 内双向对账,差异自动订正。
  5. 性能测试必备工具链:
    • 压测引擎:JMeter、Gatling、自研 Go 压测框架(支持 RPS 阶梯、故障注入)。
    • 观测:ARMS、Prometheus + Grafana、SkyWalking、dbtopo。
    • 混沌:ChaosBlade、Monkey-DB,模拟节点宕机、网络 200 ms 延迟。
  6. 验收指标:
    • 业务层:P99 延迟上涨 ≤ 10 %,错误率 0,零数据丢失。
    • 数据层:迁移速率 ≥ 100 MB/s·节点,lag 峰值 ≤ 500 ms,checksum 100 % 一致。
    • 资源层:CPU 使用率上涨 ≤ 15 %,I/O util ≤ 60 %,无重试风暴。

答案

回答时分三步:先给总体架构,再讲测试策略,最后甩出量化结果。

“我去年负责某电商大促核心订单库 Redis Cluster 从 128 分片秒级扩容到 256 分片,数据量 2.4 TB,峰值写 8 万 QPS、读 40 万 QPS。整体思路是‘并行快照 + 增量追平 + 原子切换’,测试侧用‘流量回放 + 影子集群 + 混沌验证’保证零丢失、秒级抖动。

  1. 迁移方案
    a. 快照:基于 Redis 6.2 PSYNC2,从源节点 fork RDB,采用 slot 级并行,8 线程同时 dump,单线程限速 150 MB/s,快照耗时 4 min。
    b. 增量:目标节点以 replica 身份接入,异步拉取 backlog;通过调整 repl-backlog-size=1 GB、client-output-buffer-limit=2 GB,保证 lag < 300 ms。
    c. 切换:待 lag 持续 5 秒低于 100 ms 后,由配置中心原子推送 slot 路由,同时关闭源节点写权限,整个切换耗时 280 ms。

  2. 测试方案
    ① 模型:线上流量 1:1 录制 30 min,写操作占 25 %,读 75 %,热点 key 占 3 %;压测侧用自研 Go 框架,200 台 4C8G 压测机,稳定输出 50 万 QPS。
    ② 阶段:

    • 基线:扩容前跑 30 min,记录 P99 延迟 1.8 ms,错误率 0,CPU 45 %。
    • 迁移中:持续压测,观测到 lag 峰值 450 ms,P99 延迟上涨到 2.0 ms,符合 < 10 % 要求。
    • 切换瞬间:通过 sub-millisecond 采样,发现 RT 尖刺 380 ms,错误率 0,业务无感知。
      ③ 一致性:
    • 采用‘双写对账’模式,压测脚本每次写入携带 UUID,切换后 5 min 内对比源、目标 1.2 亿条记录,100 % 一致。
    • 再用 redis-full-check 做全量 checksum,MD5 一致。
      ④ 混沌:切换过程中注入主节点宕机、网络 500 ms 延迟各 3 次,系统仍保持 RPO=0,RTO<5 s。
  3. 结果
    扩容总耗时 5 min 20 s,其中业务感知抖动 380 ms,零数据丢失,大促当天峰值流量再涨 30 % 仍稳定。测试报告一次性通过架构评审,后续固化为 SOP,已复制到支付台账库和营销库存库。”

拓展思考

  1. 如果数据量再上 10 倍(20 TB),快照阶段必然超过 30 min,如何缩短?
    → 引入“逻辑分片预分裂”:提前把热 slot 拆成空 slot,数据通过双写渐进式搬迁,避免一次性 RDB,测试重点变成“渐进搬迁速率 vs 业务增长速率”的赛跑模型。

  2. 若业务要求跨城双活(北京→上海 30 ms RTT),如何证明“秒级”仍然成立?
    → 需做“跨城混沌压测”:在 30 ms RTT 环境下,拉取 Raft 日志延迟基准,验证增量 lag 是否仍 < 500 ms;同时用网络分区 5 秒演练,确认多数派机制不丢数据。

  3. 测试工程师如何沉淀平台?
    → 把迁移测试封装成“一键流水线”:输入源集群、目标规格,自动创建影子环境、回放流量、注入故障、输出 P99、lag、checksum 三张图,30 min 给出 Go/No-Go 结论,已落地到 DevOps 平台,节省 70 % 人力。