ARTICLE / 2 MIN READ
Spark 与 Hive 批处理如何控制小文件和数据倾斜
从分区规划、文件格式、Shuffle 和 AQE 讲解离线任务的性能与稳定性。
离线任务慢,常见原因不是计算逻辑复杂,而是读了太多小文件、Shuffle 倾斜、分区裁剪失效或重复扫描历史数据。
分区设计
事实表通常按业务日期分区。查询必须带分区条件,任务也应只重算受影响的日期。分区字段不能高基数,否则元数据和文件数量会快速膨胀。
SELECT shop_id, sum(amount)
FROM dwd_order_item
WHERE dt >= '2026-07-01' AND dt < '2026-07-02'
GROUP BY shop_id;
小文件治理
流式写入或任务并发过高会产生大量小文件,NameNode 元数据和对象存储 LIST 操作都会受影响。通过 compaction、合并输出文件和控制并发,把单文件大小稳定在适合扫描的范围。
不要为了文件数量盲目 coalesce;应结合下游并行度、压缩比和单文件读取时间设置目标。
数据倾斜
一个超级大租户或空值 Key 会让单个 Reduce 任务远慢于其他任务。先统计 Key 分布,再使用热点 Key 加盐、两阶段聚合或单独处理空值。
两阶段聚合示意:
原始数据 -> Key + 随机盐 -> 局部聚合
-> 去盐后的 Key -> 全局聚合
Spark 的执行检查
重点看 Shuffle read/write、Task 时间分布、spill、输入文件数量和分区裁剪。启用自适应查询执行可以缓解部分倾斜和分区合并,但不能替代数据建模。
可重跑和数据正确性
批任务使用批次号和临时目录,成功后再原子切换目标分区。失败重跑不能叠加写入,写入方式应支持覆盖或按主键去重。任务日志保存输入分区、输出行数、校验和和运行版本。
离线性能优化的终点是更短的处理时间和更低的成本,同时保持任务可重跑、结果可对账、历史可回溯。
GITHUB DISCUSSION
评论与回复
评论保存在 GitHub Discussions,登录 GitHub 后即可参与,发布和回复都在本页完成。
评论区进入视口后自动加载。