全量同步按 id 取模分成 10 片,9 片在 2 分钟内结束,第 7 片跑了 47 分钟,总耗时完全由它决定。第一次遇到会往复杂处想,其实漏掉的多是个小前提。

SELECT MOD(id,10) AS shard, COUNT(*) c
FROM orders GROUP BY shard ORDER BY c DESC;
-- 最大片和最小片差 200 倍时不要再按取模分

分片按 id 取模,大客户的数据集中在一段 id 区间,落到同一片。分片数固定,数据量却差了两个数量级。这一点先确认清楚,后面就不用反复试。

碰到「分片不均长尾」这类问题,我习惯先把当前配置原样备份一份,改坏了立刻换回来,不用现场推。新版本先放一台机器上跑一天再全量,问题一般在这段时间暴露。

备份不是备了就行,恢复一次才算数,很多备份文件打开才发现是空的。接口问题先分清是没发出去、发出去了没收到,还是收到了处理失败。

具体做法是,统计每片的实际行数和耗时 确认倾斜来自数据不是机器;按数据量分桶 不要按 id 取模;或者把大客户单独拆片 小客户合并;分片数改成可配置 按当前总量动态计算。

改完照着核一遍,重新分片后 10 片的行数差距在 20% 以内 总耗时从 47 分钟降到 6 分钟。

作者 9823189