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:通过先排序、后聚合的方式,用更稳定的性能表现换取系统的可靠性。

相关推荐
数据百晓通3 小时前
2026 智能体重构数据治理:全链路 AI、云生态、场景嵌入赛道解析
大数据·运维·人工智能
渣渣盟3 小时前
Flink 单流转换算子深度解析:从 Map 到 Reduce 的流式处理基石
大数据·flink
chanmama88884 小时前
品牌全域洞察怎么做?蝉妈妈拆解竞品策略
大数据·网络·人工智能·经验分享·社交电子
Tongzhi20264 小时前
考勤数据本地化存储:通芝科技无感考勤一体机的数据安全逻辑
大数据·数据结构·科技·均值算法·数据库开发·推荐算法
tanglinS4 小时前
双端面磨床汇总:面向工艺工程师的设备选型参考
大数据·运维·人工智能·自动化·材质
湘美书院--湘美谈教育5 小时前
湘美书院人工智能访谈录:AI助力科学研究自动化
大数据·运维·人工智能·机器学习·自动化·电脑·生活
倍利福猎头公司官方账号5 小时前
人形机器人分析——电机(机器人猎头公司专项分析)
大数据·人工智能·机器人·求职招聘·业界资讯
稳石氢能5 小时前
政策落地与市场冷遇并存,氢能产业如何跨越“最后一公里”?
大数据·人工智能
John jj5 小时前
拆解 Telegram 群组频道收录市场:三类方案,一个可运行的评分模型,目前TG中文人工评分加模型评分机制——LetsTG收录“快速”、“无门槛”
大数据·后端·python·深度学习·搜索引擎·django·全文检索
逐米时代6 小时前
工厂数字化规划:BIM与仿真让方案可验证
大数据·网络·人工智能