【Spark原理系列】Accumulator累加器原理用法示例源码详解

Spark 2.x 自定义累加器AccumulatorV2的使用 废除Spark2.x之后,之前的的accumulator被废除,用AccumulatorV2代替;更新增加创建并注册一个long accumulator, 从“0”开始,用“add”累加 def longAccumulator(name: String): LongAccumulator = { val acc = new LongAccumulator register(acc, 阅读详情

【Spark原理系列】Accumulator累加器原理场景示例源码详解

源自专栏《SparkML:Spark ML系列专栏目录》

原理

Accumulator是Spark中的一种分布式变量,用于在并行计算中进行累加操作。它是由MapReduce模型中的“全局计数器”概念演化而来的。

Accumulator提供了一个可写的分布式变量,可以在并行计算中进行累加操作。在Spark中,当一个任务对Accumulator进行累加操作时,这个操作会被序列化并发送到执行任务的节点上进行执行。然后,Spark会将所有节点上的结果合并起来,最终得到Accumulator的最终值。

场景

Accumulator的使用场景包括但不限于:

  • 在并行计算中进行全局计数或求和操作;
  • 在迭代算法中进行迭代过程中的统计操作;
  • 在分布式机器学习中进行模型参数的更新。

下面是一个使用Accumulator进行计数操作的示例代码:

import org.apache.spark.{
   
   SparkConf, SparkContext}

object AccumulatorExample {
   
   
  def main(args: Array[String]): Unit = {
   
   
    val conf = new SparkConf().setAppName("AccumulatorExample").setMaster("local")
    val sc = new SparkContext(conf)

    val input = sc.parallelize(Seq(1, 2, 3, 4, 5))
    val countAccumulator = sc.longAccumulator("countAccumulator")

    input.foreach(num => {
   
   
      countAccumulator.add(1)
    })

    println("Count: " + countAccumulator.value)

    sc.stop()
  }
}

在上述示例中,我们创建了一个名为countAccumulator的累加器,并将其初始化为0。然后,我们使用foreach操作对输入数据进行遍历,在每次遍历时将计数器加1。最后,我们通过调用value方法获取累加器的最终值并输出。

总结起来,Accumulator是Spark中用于分布式计算的一种特殊变量,可以在并行计算中进行累加操作,并提供了全局共享的能力。它的设计使得Spark可以高效地进行并行计算,并实现了类似于MapReduce模型中全局计数器的功能。

方法

AccumulatorV2是Spark中的一个类,用于定义和实现累加器的功能。下面是该类的方法总结

方法 描述
register 注册累加器,将其添加到累加器上下文中
isRegistered 判断累加器是否已经注册
id 获取累加器的ID
name 获取累加器的名称
countFailedValues 是否统计失败任务的值
toInfo 将累加器转化为AccumulableInfo对象
isAtDriverSide 判断当前累加器是否在Driver端
isZero 判断累加器是否为零值
copyAndReset 创建一个新的累加器副本,并将其重置为零值
copy 创建一个新的累加器副本
reset 重置累加器为零值
add 添加输入值进行累加
merge 合并另一个相同类型的累加器到当前累加器中
value 获取累加器的当前值

重要类

这些源码中定义了几个重要的类:

  1. AccumulatorMetadata:用于存储累加器的元数据,包括ID、名称和是否计数失败值等。

  2. AccumulatorV2:抽象类,定义了累加器的基本操作。它包含了注册、获取ID和名称、添加值、合并其他累加器、重置、复制、判断是否为零值、获取当前值等方法。

  3. LongAccumulator:继承自AccumulatorV2,用于计算64位整数的和、计数和平均值的累加器。

  4. DoubleAccumulator:继承自AccumulatorV2,用于计算双精度浮点数的和、计数和平均值的累加器。

  5. CollectionAccumulator:继承自AccumulatorV2,用于收集元素列表的累加器。

  6. AccumulatorContext:用于跟踪和管理累加器的对象。它包含了注册、获取、取消注册、清除等方法。

这些方法和类提供了对累加器的定义、注册、操作和管理的功能。通过使用这些累加器,可以方便地在Spark应用程序中进行分布式的聚合操作,并将结果返回给Driver端进行进一步处理。

示例

import org.apache.spark.util.{
   
   CollectionAccumulator, DoubleAccumulator, LongAccumulator}
import org.apache.spark.{
   
   SparkConf, SparkContext}

object AccumulatorExample {
   
   
  def main(args: Array[String]): Unit = {
   
   
    val conf = new SparkConf().setAppName("AccumulatorExample").setMaster("local[*]")
    val sc = new SparkContext(conf)

    // 创建LongAccumulator用于计算总和
    val sumAccumulator = new LongAccumulator
    sc.register(sumAccumulator, "sum")

    // 创建DoubleAccumulator用于计算平均值
    val avgAccumulator = new DoubleAccumulator
    sc.register(avgAccumulator, "avg")

    // 创建CollectionAccumulator用于收集元素列表
    val listAccumulator = new CollectionAccumulator[Int]
    sc.register(listAccumulator, "list")

    // 构造一个RDD
    val numbers = sc.parallelize(Seq(1L, 2L, 3L, 4L, 5L))

    // 使用累加器计算总和和平均值,并收集元素列表
    numbers.foreach {
   
    num =>
      sumAccumulator.add(num)
      avgAccumulator.add(num.toDouble)
      listAccumulator.add(num.toInt)
    }

    // 获取累加器的结果
    val sum = sumAccumulator.value
    val avg = avgAccumulator.value
    val list = listAccumulator.value

    println(s"The sum of numbers is: $sum")
    println(s"The average of numbers is: $avg")
    println(s"The list of numbers is: $list")

//    The sum of numbers is: 15
//    The average of numbers is: 15.0
//    The list of numbers is: [4, 1, 3, 2, 5]

    sc.stop()
  }
}

中文源码分析

Accumulator是一种在并行计算中用于进行聚合操作的变量。它可以被多个并行任务同时访问和更新,但确保了线程安全性。

AccumulatorV2是一个抽象类,用于定义自定义累加器。它定义了累加器的基本操作,例如重置、添加值、合并等。LongAccumulator、DoubleAccumulator和CollectionAccumulator是AccumulatorV2的具体子类,用于处理不同类型的累加操作。

AccumulatorMetadata是一个用于存储累加器元数据(例如ID、名称、是否计数失败值等)的案例类。

AccumulatorContext是一个用于跟踪和管理Spark内部使用的累加器的对象。它提供了注册、获取、删除累加器等功能。

private[spark] case class AccumulatorMetadata(
    id: Long,
    name:
Spark自定义累加器Accumulator 在Spark中,除了系统提供的累加器(例如和)之外,我们还可以创建自定义累加器。自定义累加器允许我们以分布式和高效的方式累加复杂类型的数据。定义累加器的类型定义累加器将累加的数据类型。这可以是任何类型,例如整数、浮点数、集合等。继承 AccumulatorV2创建一个新类,继承自,并为其指定输入类型(IN)和输出类型(OUT)。实现必须的方法抽象类定义了一组需要被子类实现的方法。sum = 0count = 0count += 1newAccaverage在这个例子中, 阅读详情

相关推荐

Spark 自定义累加器 Map 编程

通过以上代码,我们成功地使用自定义的 Map 累加器计算了 RDD 中所有元素的平方和。首先,让我们创建一个自定义的累加器类,继承自 Spark 的 AccumulatorV2 抽象类。在上面的代码中,我们定义了一个名为 MapAccumulator 的累加器类。如有疑问,请随时提问。接下来,我们将累加器注册到 Spark 上下文中,以便在集群中进行共享。操作对 RDD 中的元素进行遍历,并将每个元素的平方值添加到累加器中。接下来,我们将使用自定义的 Map 累加器来计算 RDD 中所有元素的平方和。

CyberLynxX的博客 334

Python使用netmiko配置华为交换机

1.netmiko就是专门为网络设备做的模块,非常强大。1.更适合网络设备的自动化运维模块。2、批量配置变更、备份。1.安装netmiko。2. 创建SSH连接。一、netmiko介绍。

博然的宝藏库 2797

从ADS到SystemVue:当简单链路预算不够用时,我的射频系统级仿真方案升级实录

本文详细介绍了从ADS到SystemVue的射频系统级仿真升级路径,重点分析了基础链路预算在多端口元件和复杂场景下的局限性,并提供了SystemVue在非线性系统验证和跨域协同分析中的优势。通过实际案例展示了如何平滑迁移工具链,提升仿真精度和效率,适用于5G、毫米波雷达等现代射频系统设计。

weixin_34233974的博客 344

Cadence Allegro实战:如何精准导入结构DXF文件避免安装偏差(附图层配置技巧)

本文详细讲解了在Cadence Allegro中精准导入结构DXF文件以避免安装偏差的实战技巧。核心在于导入前的单位校准、创建专用图层结构,以及基于坐标基准点的精确对齐方法。文章还分享了将DXF图形转化为正式板框和禁布区、高效管理图层以及向结构工程师导出DXF的完整流程,帮助PCB工程师确保设计与机械结构完美契合。

1a2s3d4f5g的博客 506

YOLOv12改进策略【Neck】| CGA Fusion:内容引导的注意力融合模块,空间权重引导的多模态特征自适应融合

本文记录的是利用CGA Fusion 模块改进 YOLOv12 的多模态融合部分。(Content-Guided Attention Fusion)通过内容引导注意力生成空间权重,引导高低层特征的自适应融合。本文利用模块,通过内容引导注意力生成空间权重,自适应地融合两个模态的特征,在特征融合阶段实现跨模态语义对齐与噪声抑制,增强对不同模态互补特征的利用能力,从而提升模型在多模态场景下的检测鲁棒性与准确性。DEA-Net: Single image dehazing based on detail-enhan

Limiiiing的博客 435

第十六篇:Camx IFE 、OPE 各 port口功能定义

需要注意的是,类似 CSLTFEPortIdRawDump 是没有downscale功能的,所以如果遇到fov不正确的问题,可以排除下TFE这边的 output port是否被接到了 CSLTFEPortIdRawDump 上面来。我们知道Camx 的IFE 、OPE有不少的output port,各个port是有哪些功能的呢?老一点的框架平台,采用的TEF、OPE。

235

爬虫Incapsula reese84加密案例:Etihad航空

声明:该文章为学习使用,严禁用于商业用途和非法用途,违者后果自负,由此产生的一切后果均与作者无关。

老衲爱洗头的博客 2430

自注意力机制(SelfAttention Mechanism)原理与代码实战案例讲解

自注意力机制(Self-Attention Mechanism)原理与代码实战案例讲解 作者:禅与计算机程序设计艺术 / Zen and the Art of Computer Programming 1. 背景介绍

AI天才研究院 1293

【CanMV K210】AI 视觉 MNIST 手写数字识别与分类推理

本文介绍了基于CanMV K210开发板的MNIST手写数字识别实验。实验通过摄像头采集图像,经过开窗、灰度化、缩放、反色等预处理后,使用KPU神经网络加速器运行MNIST分类模型,最终在LCD上显示识别结果。重点讲解了分类模型与检测模型的区别、图像预处理流程以及KPU推理结果的解析方法。实验帮助理解从图像采集到分类输出的完整AI视觉处理链路,并提供了调试思路和硬件连接说明。

Mr数据杨 366

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

上一篇: 【scala原理系列】scala Random原理方法示例源码详解
下一篇: 【python床头书】 heapq 堆队列算法参数用法示例详解
BigDataMLApplication
博客等级 码龄11年 7363粉丝 565原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BigDataMLApplication

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值