大数据(8g)图解共享变量:累加器 and 广播变量

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

1、共享变量(Shared Variables)

  • 通常,在向Spark传递函数(如map或reduce)时,可以使用驱动器中定义的变量,集群中每个任务都会得到该变量的独立副本,这些副本的更新不会回传给驱动器
  • 对此,Spark提供了共享变量的功能,下面介绍2个常用:累加器和广播变量

2、累加器(Accumulator)

  • 累加器支持并行

2.1、Spark自带累加器

//创建累加器
import org.apache.spark.util.LongAccumulator
val a: LongAccumulator = sc.longAccumulator("a")
//遍历数据
val r = sc.makeRDD(Seq(4, 3, 2, 1), 2)
r.foreach(a.add(_))
//打印累加器
print(a)
//LongAccumulator(id: 0, name: Some(a), value: 10)

2.2、自写累加器

2.2.1、累加器的基类

  • AccumulatorV2源码如下,是一个抽象类,需要被实现
  • 功能:累积 IN类型 的输入,产生 OUT类型 的输出
    OUT类型的读取 应符合 原子性(如:Int、Long)或 线程安全(如:synchronized collections)
abstract class AccumulatorV2[IN, OUT] extends Serializable

IDE小技巧

2.2.2、完整示例1:词频统计

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.util.AccumulatorV2
import scala.collection.mutable

object Hello {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf().setAppName("a1").setMaster("local[2]")
    val sc = new SparkContext(conf)
    // 创建累加器对象
    val a: A = new A()
    // 注册累加器对象
    sc.register(acc = a, name = "Aa")
    // 累加
    val r = sc.makeRDD(Seq("a", "a", "b", "a", "a", "b"))
    r.foreach(a.add)
    // 打印累加器对象的值
    println(a) // A(id: 0, name: Some(Aa), value: Map(b -> 2, a -> 4))
  }
}

// 自定义累加器,继承AccumulatorV2,光标停在A,并按【Alt+Enter】实现方法
class A extends AccumulatorV2[String, mutable.Map[String, Int]] {
  // 定义OUT:可变映射
  var m: mutable.Map[String, Int] = mutable.Map[String, Int]()
  // 判断是否为初始化状态,映射为空则返回true
  override def isZero: Boolean = m.isEmpty
  // 复制对象
  override def copy(): AccumulatorV2[String, mutable.Map[String, Int]] = {
    new A()
  }
  // 重置
  override def reset(): Unit = m.clear()
  // 累加
  override def add(v: String): Unit = {
    m(v) = m.getOrElse(v, 0) + 1
  }
  // 合并累加器
  override def merge(other: AccumulatorV2[String, mutable.Map[String, Int]]): Unit = {
    m ++= other.value.map(t => t._1 -> (t._2 + m.getOrElse(t._1, 0)))
  }
  // 累加器的值
  override def value: mutable.Map[String, Int] = m
}

2.2.3、完整示例2:求平均

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

object Hello {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf().setAppName("a1").setMaster("local[2]")
    val sc = new SparkContext(conf)
    // 创建累加器对象
    val a: A = new A()
    // 注册累加器对象
    sc.register(acc = a, name = "Aa")
    // 累加
    val r = sc.makeRDD(Seq(1, 2, 3, 4, 5, 6, 7, 8, 9))
    r.foreach(a.add)
    // 打印累加器对象的值
    println(a)  // A(id: 0, name: Some(Aa), value: 5)
  }
}

class A extends AccumulatorV2[Int, Int] {
  // 定义OUT:可变映射
  var sum: Int = 0
  var num: Int = 0
  // 判断是否为初始化状态,映射为空则返回true
  override def isZero: Boolean = sum == 0 && num == 0
  // 复制对象
  override def copy(): A = {
    new A()
  }
  // 重置
  override def reset(): Unit = {
    sum = 0
    num = 0
  }
  // 累加
  override def add(s: Int): Unit = {
    sum += s
    num += 1
  }
  // 合并累加器
  override def merge(other: AccumulatorV2[Int, Int]): Unit = {
    other match {
      case o: A =>
        sum += o.sum
        num += o.num
    }
  }
  // 累加器的值
  override def value: Int = sum / num
}

2.2.4、完整示例3:分组求平均

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.util.AccumulatorV2
import scala.collection.mutable

object Hello {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf().setAppName("a1").setMaster("local[*]")
    val sc = new SparkContext(conf)
    // 创建累加器对象
    val a: A = new A()
    // 注册累加器对象
    sc.register(acc = a, name = "Aa")
    // 累加
    val r = sc.makeRDD(Seq(("a", 2), ("b", 7), ("b", 9), ("a", 1), ("a", 3)), 2)
    r.foreach(a.add)
    // 打印累加器对象的值
    println(a) // A(id: 0, name: Some(Aa), value: Map(b -> 8, a -> 2))
  }
}

class A extends AccumulatorV2[(String, Int), mutable.Map[String, Int]] {
  // 定义OUT:可变映射
  val s: mutable.Map[String, Int] = mutable.Map[String, Int]()
  val c: mutable.Map[String, Int] = mutable.Map[String, Int]()
  // 判断是否为初始化状态,映射为空则返回true
  override def isZero: Boolean = s.isEmpty && c.isEmpty
  // 复制对象
  override def copy(): AccumulatorV2[(String, Int), mutable.Map[String, Int]] = {
    new A()
  }
  // 重置
  override def reset(): Unit = {
    s.clear()
    c.clear()
  }
  // 累加
  override def add(t: (String, Int)): Unit = {
    s(t._1) = s.getOrElse(t._1, 0) + t._2
    c(t._1) = c.getOrElse(t._1, 0) + 1
  }
  // 合并累加器
  override def merge(other: AccumulatorV2[(String, Int), mutable.Map[String, Int]]): Unit = {
    other match {
      case o: A =>
        s ++= o.s.map(t => t._1 -> (t._2 + s.getOrElse(t._1, 0)))
        c ++= o.c.map(t => t._1 -> (t._2 + c.getOrElse(t._1, 0)))
    }
  }
  // 累加器的值
  override def value: mutable.Map[String, Int] = {
    s.map(t => t._1 -> (t._2 / c.getOrElse(t._1, -1)))
  }
}

3、广播变量(Broadcast Variables)

Broadcast variables allow the programmer to keep a read-only variable cached on each machine rather than shipping a copy of it with tasks.
广播变量允许在每台机器上缓存一个只读变量,而非在每个任务中附带一个独立副本

3.1、示例

需求:过滤不在s中的数据

val s = Set("b", "c")
val r0 = sc.makeRDD(Seq("b", "a", "b", "c", "e", "f", "c"))

不使用广播变量

val r1 = r0.filter(s.contains)
println(r1.collect.toList) //List(b, b, c, c)

使用广播变量,更节省内存

//创建广播变量
import org.apache.spark.broadcast.Broadcast
val b: Broadcast[Set[String]] = sc.broadcast(s)
//使用广播变量
val r2 = r0.filter(b.value.contains)
println(r2.collect.toList) //List(b, b, c, c)


appendix

en🔉cn
implementˈɪmplɪməntvt. 实施;实现;n. 器具;手段
synchronizedˈsɪŋkrənaɪzd同步的
shipʃɪpn. 船;v. (用船、飞机、卡车)运送;上船;
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

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

优快云 精品推荐 839

Spark_使用累加器实现WordCount避免shuffle

package com.atguigu.spark import org.apache.spark.rdd.RDD import org.apache.spark.util.AccumulatorV2 import org.apache.spark.{SparkConf, SparkContext} import scala.collection.mutable object TestACCWc { def main(args: Array[String]): Unit = { val conf = new

weixin_43003792的博客 315

【信息科学与工程学】计算机科学与自动化-——第十五篇云计算 11 算法篇

在百万级虚拟机、百万级租户的超大规模云环境中,核心算法挑战包括:挑战维度具体问题算法需求技术复杂度规模性​百万级对象并发管理分布式算法、分区算法极高(NP-hard问题)多租户​租户间隔离与资源共享公平性算法、隔离算法高(多目标优化)动态性​资源需求实时变化自适应算法、在线算法高(实时决策)异构性​硬件/负载/需求差异分类算法、匹配算法中高(多维度优化)经济性​资源利用率与成本平衡优化算法、博弈论算法高(多目标博弈)以下是按领域分类的详细算法列表:算法名称数学建模表达核心思想时间复杂度适用场景推理步骤首次适

weixin_49199313的博客 1405

Spark实现WordCount的11种方式,你知道的有哪些?

学习任何一门语言,都是从helloword开始,对于大数据框架来说,则是从wordcount开始,Spark也不例外,作为一门大数据处理框架,在系统的学习spark之后,wordcount可以有11种方式实现,你知道的有哪些呢?还等啥,不知道的来了解一下吧!...............

笑看风云路的博客 1982

用Python实现四叉树(quad tree)

import numpy as np #正方形类 class square: #lx、ly为左上角坐标(x对应行号,y对应列号),rx、ry为右下角坐标 def __init__(self,lx,ly,rx,ry): self.lx=lx self.ly=ly self.rx=rx self.ry=ry #检查该矩阵中是否满足条件 #参数:原矩阵,阈值 #返回值:布尔类型 def check(s

weixin_44164489的博客 5868

YOLOv8/v9 遥感图像目标检测实战指南:建筑物检测与变化监测

遥感图像在城市规划、灾害评估、农业监管等领域应用广泛,但传统目标检测方法存在效率低、精度不足、难以适配遥感图像大尺寸、多尺度目标等问题。本文以“建筑物检测与变化监测”为核心,基于DOTA、NWPU VHR-10等公开数据集,系统讲解YOLOv8/v9在遥感图像中的实战流程。从数据获取、格式转换、模型训练优化,到大图切片推理、建筑物变化监测,全程提供可复现的代码与参数配置。通过针对性优化(旋转增强、切片推理等),模型在NWPU VHR-10数据集上mAP50达0.85以上,可适配卫星影像、无人机航拍等多场景

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 520

(电商项目实战)Spark累加器AccumulatorV2

spark2.x AccumulatorV2(累加器) Spark2.x之后,之前的的accumulator被废除,用AccumulatorV2代替; 累加器(accumulator):Accumulator是仅仅被相关操作累加的变量,因此可以在并行中被有效地支持。它们可用于实现计数器(如MapReduce)或总和计数。 Accumulator是存在于Driver端的,从节点不断把值发到Dr...

开水烫鱼的博客 1018

2024年11月架构设计师案例分析真题回顾,附参考答案、解析及所涉知识点(二)

软考高级系统架构设计师考试包含三个科目:信息系统综合知识、案例分析和系统架构设计论文。考试形式为机考。本文主要回顾2024年下半年(2024-11-10)系统架构设计师考试上午第二科案例分析的题目,同时附带参考解答、解析和所涉知识点。

一几文的编程学习笔记。 1664

Windows API 函数

《Windows API函数手册》摘要 本文档是Windows平台开发的权威参考手册,全面收录774个核心API函数,涵盖系统管理、进程线程、窗口消息、文件操作、图形处理等12大功能模块。手册采用结构化编排,主要特点包括: 编码规范 详细区分多字节(char)与宽字符(wchar_t)编码体系 提供LPSTR/LPCWSTR等字符串指针类型的完整解析 说明UTF-8与GBK编码转换的实际应用场景 核心功能模块 窗口创建:完整展示从注册类到消息循环的窗口生命周期 文件操作:覆盖CreateFile/ReadF

gqk01的博客 864

【项目实战】SOVD协议(面向服务的车辆诊断协议)

此外,AUTOSAR组织将SOVD部分内容的软件实现定义在了R22-11及以上版本的AUTOSAR Adaptive规范中,还支持动态发现车内诊断功能、获取高性能计算机(HPC)的Log信息等新的诊断需求,更符合当前软件定义汽车概念下的行业趋势。而SOVDGateway作为边缘节点,也肩负着对SOVD Client进行认证以及权限控制的责任,从而保证车辆的信息安全。相较于传统的UDS(Unified Diagnostic Services)协议,SOVD不仅保留了传统的读写数据、例程控制、故障读取等功能,

奶爸的编程之路,也就一周冷个三天 1905

半导体器件仿真:双极型晶体管仿真_15.双极型晶体管的高级仿真技术

双极型晶体管(Bipolar Junction Transistor, BJT)是一种重要的半导体器件,广泛应用于放大、开关和调制等电路中。随着半导体技术的发展,对BJT的仿真要求也越来越高。本节将详细介绍双极型晶体管的高级仿真技术,包括器件模型的选择、仿真参数的优化、温度效应的考虑以及噪声分析等。

2401_87715305的博客 1244

工作中使用到的单词(软件开发)

1.エイリアス   alias 别名 powershell使用 get-help 命令时,会得到与此命令 相关(别名)的命令 2.プロキシ proxy 代 理 3.プロモート   promote 促进,提升   开发的系统新功能上线发布,有时会使用到这个词,比如 STプロモート 还有使用リリース这个词的。比如STリリース。个人认为两者含义相同。 4.見逃し み................................................................

sun0322 6万+

马达种类全解析:VCM、Stepper、Piezo 在手机相机中的驱动原理与工程差异

在现代手机影像系统中,马达承担着核心成像组件的动态调节任务,如自动对焦(AF)、光学防抖(OIS)以及变焦调节。目前主流采用三类驱动器件:VCM(Voice Coil Motor)、Stepper(步进马达)、Piezo(压电马达)。不同马达方案在结构复杂度、响应速度、功耗、驱动方式与模组厚度适配等方面差异显著,对成像系统的性能表现有直接影响。本文将结合最新旗舰设备的应用现状,系统剖析这三类驱动马达的工作原理、架构特点与工程应用经验,为工程实践中选型与调试提供参考。

努力分享一些人工智能、计算机视觉、影像等相关的知识干货! 3792

Spark自定义AccumulatorV2

Spark自定义AccumulatorV2 1.概述### AccumulatorV2的简单使用与注意事项见上一遍博客https://blog.youkuaiyun.com/wtzhm/article/details/86481846 在实际开发中很多时候需要用到自定义Acummulator,Accumulator太多了,不便于维护,例如项目如果要出现一些逻辑上的变更,比如说,session数量的计算逻辑,...

zhm的博客 1041

Office系列完全干净卸载工具合集(最全)

使用 Microsoft Fix it 卸载 Microsoft Office 套件 一、Windows 7、Windows Vista或Windows XP下卸载Office 1.MicrosoftEasyFix50416 工具用来卸载office 2003 MicrosoftEasyFix50416_Office2003.msi 2.MicrosoftEasyFix50154 工具用来卸载office 2007 MicrosoftEasyFix50154_Office2007.msi 3.Microso

业精于勤,荒于嬉 3万+

uniapp [全端兼容] - 详细实现拍照或相册选取图片后插入水印功能,手机拍照或相册上传图像并添加自定义水印及指定位置显示水印,uniApp给图片加水印后上传到后端服务器或保存到本机相册详细教程!

uni-app,h5移动端网页,微信小程序,支付宝小程序,Android安卓,苹果ios,app,nvue,图片水印,上传照片带水印,从相册选择图片加水印功能,拍完照片给图片加水印,添加照片水印,uniapp图片加水印,为图片添加自定义水印,uni-app上传图片并添加水印,上传图片加水印,uni-app如何对拍摄的照片加水印,uni-app实现图片上传添加水印操作,给上传的图片添加上水印,图片加完水印后如何上传到服务器,水印相机,拍照图片加水印,相册选取后给图片加上水印,渲染失败,无法保存,文字水印,日期

🏆 前端领域优质创作者 1万+

Spark 之 Accumulator 累加器

累加器:分布式只写变量(Executor端的task不能互相访问累加器的值)。 累加器对信息进行聚合。 累加器分布式情况是线程安全的

南风知我意 2019

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Spark学习04(自定义累加器+自定义排序+自定义分区)

一、自定义累加器(Accumulator) 自定义累加器,可以任意累加不同类型的值,同时也可以在内部进行计算,或者逻辑编写,如果继承自定义累加器,那么需要实现内部的抽象方法,然后在每个抽象方法内部去累加变量值即可,主要是在全局性累加起到决定性作用。 累加器作为spark的一个共享变量的实现,在用于累加计数计算计算指标的时候可以有效的减少网络的消耗 累加器可以在每个节点上面进行Task的值,累加操作...

qq_41253208的博客 601

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

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

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Spark Core 累加器、广播变量

Accumulator累加器(重要) 累加器用来对信息进行聚合,通常在向 Spark 传递函数时,比如使用 map() 函数或者用 filter() 传条件时,可以使用驱 动器程序中定义的变量,但是集群中运行的每个任务都会得到这些变量的一份新的副本, 更新这些副本的值也不会影响驱动器中的对应变量。 如果我们想实现所有分片处理时更新共享变量的功能,那么累加器可以实现我们想要的效果。 Spark提...

weixin_43969505的博客 334

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

自定义Spark累加器

继续跟踪LongAccumulator这个类 可以看到,累加器底层其实是继承了AccumulatorV2这个方法,但是里面有两个类型参数,是什么东西呢?继续跟踪 最终是这个类型,也就是说,上面的两个参数也就是一个是输入,一个是输出 所以根据上面的源码可以知道,如果我们需要自定义自己的累加器的,只需要继承AccumulatorV2[IN, OUT] 这个类,然后重写其余的方法,自定义我们的逻辑即可 当创建完累加器之后,在使用的时候,spark是不知道我们自定义的累加器的,所有此

阿拉修 1231

Spark 累加器 & 广播变量

Spark 累加器和广播变量的测试

m0_72168501的博客 932

Spark 的 Accumulator与 AccumulatorV2

Spark 的 Accumulator 1.概述 Accumulator累加器能精确地统计数据的各种属性,eg:可以统计符合条件的session,在一段时间段内产生了多少次购买,统计出各种属性的数据。 2. 例子 def main(args: Array[String]): Unit = { val conf = new SparkConf().setMaster("local[2]")....

zhm的博客 2733

SparkCore快速入门-自定义累加器的编写

import org.apache.spark.util.AccumulatorV2 import org.apache.spark.{SparkConf, SparkContext} /** * 自定义累加器 */ object SparkCore_CustomAccumulator { def main(args: Array[String]): Unit = { val conf = new SparkConf().setAppName("test").setMaster("loca

weixin_46524944的博客 228

spark中使用Accumulator累加器使用和注意事项

Accumulator简介 Accumulator是spark提供的累加器,累加器的一个常用用途是在调试时对作业执行过程中的事件进行计数,但是只要driver能获取Accumulator的值(使用value方法), Task只能对其做增加操作(使用+=),也可以在为Accumulator命名(不支持Python),这样就会在spark web ui中显示, 可以帮助了解程序运行的情况。 数值累...

Ran_记忆犹新的博客 5328

Spark学习笔记——SparkCore核心编程之累加器、广播变量

学习笔记

xianrenzw的博客 334

Spark2.1 共享变量(Broadcast Variables&Accumulators)分析。

在spark中,当我们将一个function传递给算子去执行的时候,是会在集群的从节点执行的,例如map算子: List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); JavaRDD<Integer> numberRDD = sc.parallelize(numbers);// 得到一个RDD JavaRD

繁城落叶 2723
上一篇: 大数据(8c)RDD编程指南Scala版
下一篇: 大数据(8h)Spark页面单跳转化率
小基基o_O
博客等级 码龄9年 4414粉丝 467原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

打赏作者

小基基o_O

您的鼓励是我创作的巨大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值