数据倾斜(Data Skew)指的是:在分布式计算里,数据被切分到多个分片(partition)后,个别分片分到的数据量或计算量远大于其他分片,结果所有分片都得停下来等最慢的那个,整体任务时长被它一个决定。
打个生活化的比方。十个同事分拣一仓库快递,理想情况是每人一万件,两小时干完。但实际分下来,九个人只分到几百件,半小时就收工了;剩下一个人分到十万件,得干到明天早上。其他人再闲也帮不上忙,因为那十万件都在同一个人的传送带上。整个团队的下班时间,由最慢的那个人说了算。分布式系统里的“分片”就是这些同事,数据倾斜就是“活分得极不均匀”。
它常见于几类场景:按某个字段分组或聚合时,少数 key 特别“重”,比如按用户 ID 统计,几个大账号占了绝大多数记录;两张表做 join 时,某个 key 在一边有海量重复值;分区函数选得不好,把大量空值或默认值全塞进同一个分片;数据本身有自然热点,比如热门商品、热门话题。表现出来往往是:大部分 task 早就跑完了,少数 task 卡很久,甚至内存溢出(OOM)失败重试,整个作业跟着拖住。
这里要区分几个容易混的概念:
| 概念 | 核心问题 | 直接加机器管用吗 |
|---|---|---|
| 数据倾斜 | 分片之间负载不均 | 通常不管用,得先改分区或聚合策略 |
| 数据量大 | 整体规模超出当前集群 | 管用,水平扩展通常能线性提速 |
| 慢节点 | 个别机器硬件、网络或 GC 慢 | 可能管用,先排查或替换机器 |
数据倾斜不是“总量太大”,而是“分布太偏”。如果只是量大但均匀,加机器就能把活摊薄;可倾斜时,最大的那个分片仍然压在一个节点上,加再多机器也还是等它。
对从业者来说,排查信号很直接:看作业里各 task 的耗时分布和 shuffle 读写量。如果最大值比中位数高出几倍甚至几十倍,基本就是倾斜。常见缓解思路有:给热点 key 加随机后缀“加盐”打散,先局部聚合再全局聚合;把热点 key 拆出来单独处理;小表广播;自定义分区函数;使用引擎提供的自适应执行能力(是否默认开启、具体行为以所用引擎的官方文档为准)。在大模型训练里也有类似现象:数据并行时少数超长样本拖慢一步,或者混合专家(MoE)路由把过多 token 分给同一个专家,都会让 GPU 利用率忽高忽低。
对普通人来说,数据倾斜就是团队协作里的瓶颈:不是总工作量太大,而是最慢那一环决定了整体节奏。解决它的关键往往不是堆资源,而是重新切分工作。
