Spark聚合算法:HashAggregate与SortAggregate详解

为了让你一眼看透本质,我们把 Spark 聚合 比作"分拣扑克牌":

  • HashAggregate = 按点数直接扔进对应的桶(内存中建哈希表)。

  • SortAggregate = 先把牌排好序,再从头数(排序后顺序扫描)。

假设我们有一堆杂乱的扑克牌(数据),要统计 每种花色(Suit)的张数GROUP BY suit)。

原始数据(乱序):

♥️3, ♠️K, ♦️5, ♥️7, ♠️A, ♦️2, ♣️4, ♣️Q


玩法一:HashAggregate(哈希聚合)------ "按花色扔桶"

操作步骤

  1. Spark 在内存中建一个"哈希桶"(HashMap),每个花色对应一个格子。

  2. 每来一张牌,直接计算花色 Hash 值,找到对应的格子:

    • 看到 ♥️3 → 找到"红桃"格,计数 1。

    • 看到 ♠️K → 找到"黑桃"格,计数 1。

    • 看到 ♦️5 → 找到"方块"格,计数 1。

    • 看到 ♥️7 → 找到"红桃"格,计数变成 2(原地更新)。

  3. 所有牌读完,直接统计每个格子里的总数。

维度 特点
优点 速度极快,数据来一条处理一条,无需等待其他数据。
缺点 吃内存。如果花色(分组 Key)有上亿种,哈希表会撑爆内存,导致 OOM 或频繁溢写磁盘。
适用场景 数据分组后 Key 的种类相对较少,内存装得下。

玩法二:SortAggregate(排序聚合)------ "排队后顺序数"

操作步骤

1. 先全局/分区排序:不管牌原来在哪,先把所有扑克牌按"花色"排好队(Shuffle + Sort)。排完后顺序为:

♣️4, ♣️Q, ♦️2, ♦️5, ♥️3, ♥️7, ♠️A, ♠️K

2. 再顺序扫描:从头到尾扫一遍,因为同花色都挤在一起了,所以只需要记住"当前花色":

  • 扫到 ♣️4(当前为梅花),累加;扫到 ♣️Q(还是梅花),累加;遇到 ♦️2(花色变了),立刻把梅花的统计结果输出,然后开始数方块。
  1. 扫完整个队列,所有统计结果就出来了。
维度 特点
优点 内存占用小。排序时可以借助磁盘(外部排序),不需要在内存中维持巨大的哈希表。
缺点 速度较慢。必须等所有数据排好序才能开始聚合,且排序本身消耗大量的 CPU 和 Shuffle 网络开销。
适用场景 数据量极大,Key 种类极多,内存不够装下哈希表时,作为"兜底策略"使用。

两者终极对决(一图看懂)

对比维度 HashAggregate SortAggregate
核心操作 哈希查找 + 内存更新 全局排序 + 顺序遍历
对数据要求 不需要数据有序 必须先按 Key 排好序
内存风险 高(Key 太多会撑爆) 低(依赖磁盘缓冲)
执行效率 快(O(1) 查找) 慢(O(n log n) 排序)
Spark 优先度 默认首选(高性能) 当 HashAgg 内存不足时回退使用

Spark 实际执行中的"骚操作"(必看)

在实际的物理执行计划中,Spark 为了兼顾速度和稳定性,常采用两阶段聚合

  1. 部分聚合(Partial HashAggregate)

    在每个数据分片(Task)内部,先用 HashAggregate 快速合并局部数据(比如每个 Task 内先数一遍自己手上的牌),大幅减少 Shuffle 的数据量。

  2. 最终聚合(Final 阶段)

    Shuffle 后,如果 Key 的数量依然巨大,Spark 可能会放弃 HashAggregate,改用 SortAggregate 来完成最后的全局合并,防止内存爆炸。

在 Spark SQL 中,HashAggregate 是默认首选,SortAggregate 则作为"替补" ,在 HashAggregate 无法胜任或效率不佳时登场。

简单来说,HashAggregate 追求极致速度,而 SortAggregate 保证系统稳定。


🚀 HashAggregate:高性能的默认选项

只要条件允许,Spark SQL 会优先选择 HashAggregate 来追求最佳性能。它通常出现在这些场景:

  • 标准 GROUP BY 聚合 :这是最典型的场景,例如 SELECT category, SUM(sales) FROM table GROUP BY category

  • DISTINCT 去重聚合 :执行 SELECT COUNT(DISTINCT col) FROM table 这类操作时,Spark 会使用 HashAggregate 分阶段去重。

  • 无 GROUP BY 的全局聚合 :即使是计算整个表的 SELECT COUNT(*) FROM table,也会使用 HashAggregate 进行全局聚合。

值得注意的是,HashAggregate 通常以"成对"方式出现:先在每个分区内进行局部聚合 (Partial),经过 Exchange 节点完成数据 shufflle 后,再进行全局聚合(Final)。

🛡️ SortAggregate:保障稳定的后备方案

当出现以下情况时,Spark SQL 会放弃 HashAggregate,转而使用更稳定的 SortAggregate

  • 内存压力过大 :当分组键(Key)过多,导致 HashAggregate 使用的哈希表大到无法放入内存时,Spark 会"回退"到 SortAggregate 以避免内存溢出(OOM)。

  • 数据类型不匹配(核心原因)HashAggregate 要求聚合函数中使用的数据类型是"可变"的。当你使用 first()last() 或某些自定义聚合函数(UDAF) 时,会因数据类型限制而强制使用 SortAggregate

  • 数据已预先排序 :如果数据流本身已经按分组键排好序,那么使用 SortAggregate 可以省去额外的排序开销,速度可能更快。

💎 总结

Spark SQL 选择聚合策略的逻辑是:

  1. 首选 HashAggregate :利用哈希表进行 O(1) 查找,实现高性能聚合。

  2. 条件不满足时,降级为 SortAggregate:通过先排序、后聚合的方式,用更稳定的性能表现换取系统的可靠性。

相关推荐
Raas1001 天前
MAI Gateway(魔芋企业级AI网关)技术揭秘:AI网关支持哪些模型?从原理到落地
大数据·人工智能·网关·gateway·mai gateway·企业级产品
YangYang9YangYan1 天前
2026 校招商品分析岗位 JD 拆解,核心指标、工具与面试考点
大数据·数据库·数据分析
大大大大晴天1 天前
OpenMetadata VS DataHub VS Atlas VS Gravitino
大数据
Qyr991 天前
2026全球汽车碳刷行业发展全景分析报告
大数据
蓝速科技1 天前
便民服务大厅 AI 数字人一体机场景适配与落地指南丨蓝速科技
大数据·网络·数据结构·人工智能·自然语言处理·数据分析·运维开发
精益数智工坊1 天前
云计算环境数据怎么同步?云计算集成方案有哪些?
大数据·人工智能·数据挖掘·数据可视化
huashengzsj1 天前
什么是DMS经销商管理系统?国内经销商管理系统有哪些品牌
大数据
IT毕设梦工厂1 天前
计算机毕业设计选题推荐:基于大数据的草鱼价格分析与可视化|毕业设计选题|计算机毕设|选题推荐|毕设指导|项目定制|源码|高质量项目
大数据·hadoop·python·数据挖掘·数据分析·课程设计·大数据毕设项目
辛迪聊物业数字化2 天前
智慧社区物业管理软件新手部署与实操指南
大数据·php
字节跳动数据平台2 天前
模型再强,为什么 Demo 还是进不了生产?
大数据