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 后即可参与,发布和回复都在本页完成。

评论区进入视口后自动加载。