在Spark中,累加器(Accumulator) 是一种共享变量,主要用于在分布式计算中实现高效的全局计数或聚合操作。其核心作用如下:
核心作用
-
跨节点聚合数据
在并行任务(如map()、filter()等)中,累加器允许不同执行器(Executor)将局部计算结果汇总到驱动节点(Driver),实现全局统计。
例如:统计分布式处理中的错误日志总数。 -
避免分布式计算的闭包陷阱
若在任务中直接修改外部变量(如count += 1),因变量副本分发到各节点,结果会丢失。累加器通过中心化更新机制规避此问题。 -
高效只写操作
累加器设计为仅支持累加操作(如add()),各节点可向其写入数据,但无法读取值(读取需在Driver端完成)。这种设计减少了网络通信开销。
使用场景
- 计数统计:如记录过滤的数据量、异常次数等。
- 求和运算:如分布式数值累加。
- 自定义聚合:通过扩展
AccumulatorV2实现复杂聚合逻辑(如向量求和)。
简单示例
val spark = SparkSession.builder.appName("AccumulatorDemo").getOrCreate()
val accum = spark.sparkContext.longAccumulator("myCounter") // 创建累加器
val data = spark.sparkContext.parallelize(Seq(1, 2, 3, 4, 5))
data.foreach { x =>
if (x % 2 == 0) accum.add(1) // 对偶数计数
}
println(s"偶数总数: ${accum.value}") // 输出结果
输出:偶数总数: 2
注意事项
- 行动操作触发:累加器仅在
action(如foreach())执行后更新,transform(如map())不会立即生效。 - 任务重试风险:若任务失败重试,可能导致重复累加(需结合检查点机制避免)。
累加器通过简化分布式状态管理,为Spark作业提供了轻量级全局计数能力。
1614

被折叠的 条评论
为什么被折叠?



