Spark2.0 自定义累加器

在2.0中使用自定义累加器需要继承AccumulatorV2这个抽象类,同时必须对以下6个方法进行实现:

1.reset 方法: 将累加器进行重置;

abstract defreset(): Unit

Resets this accumulator, which is zero value.

2.add 方法: 向累加器中添加另一个值;

abstract defadd(v: IN): Unit

3.merge方法: 合并另一个类型相同的累加器;

abstract defmerge(other: AccumulatorV2[IN, OUT]): Unit

Merges another same-type accumulator into this one and update its state, i.e.

4.value 取值

abstract defvalue: OUT

Defines the current value of this accumulator

5.复制:Creates a new copy of this accumulator.

abstract defcopy(): AccumulatorV2[IN, OUT]

6.

abstract defisZero: Boolean

Returns if this accumulator is zero value or not.

需要注意的是,对累加器的更新只有在action中生效,spark对累加器的每个task的更新只会应用一次,即重新启动的任务不会更新累加器的值.而在transform中需要注意,每个任务可能会多次进行更新,如果task或者job被重复执行.同时累加器不会改变spark的lazy策略.

由于业务需求经常要构造若干Dataframe间数据的映射关系,而使用collectionAccumulator又要有一定量的重复性的Map操作, 故写了这个生成Map的自定义累加器,IN为代表key和value的String 类型的tuple,最后生成Map, 如果累加器中已经含有了要添加的key且 key->value不重复则以字符串||对value进行分隔,并更新累加器的值;

代码如下:


/**
* Created by Namhwik on 2016/12/27.
*/
class MapAccumulator extends AccumulatorV2[(String,String),mutable.Map[String, String]] {
private val mapAccumulator = mutable.Map[String,String]()
def add(keyAndValue:((String,String))): Unit ={
val key = keyAndValue._1
val value = keyAndValue._2
if (!mapAccumulator.contains(key))
mapAccumulator += key->value
else if(mapAccumulator.get(key).get!=value) {
mapAccumulator += key->(mapAccumulator.get(key).get+"||"+value)
}
}
def isZero: Boolean = {
mapAccumulator.isEmpty
}
def copy(): AccumulatorV2[((String,String)),mutable.Map[String, String]] ={
val newMapAccumulator = new MapAccumulator()
mapAccumulator.foreach(x=>newMapAccumulator.add(x))
newMapAccumulator
}
def value: mutable.Map[String,String] = {
mapAccumulator
}
def merge(other:AccumulatorV2[((String,String)),mutable.Map[String, String]]) = other match
{
case map:MapAccumulator => {
other.value.foreach(x =>
if (!this.value.contains(x._1))
this.add(x)
else
x._2.split("\\|\\|").foreach(
y => {
if (!this.value.get(x._1).get.split("\\|\\|").contains(y))
this.add(x._1, y)
}
)
)
}
case _ =>
throw new UnsupportedOperationException(
s"Cannot merge ${this.getClass.getName} with ${other.getClass.getName}")
}
def reset(): Unit ={
mapAccumulator.clear()
}
}
 

参考 <http://spark.apache.org/docs/latest/programming-guide.html>

ps:使用的时候需要register.

Spark2.0自定义累加器的更多相关文章

  1. 初识Spark2.0之Spark SQL

    内存计算平台spark在今年6月份的时候正式发布了spark2.0,相比上一版本的spark1.6版本,在内存优化,数据组织,流计算等方面都做出了较大的改变,同时更加注重基于DataFrame数据组织 ...

  2. Spark2.0机器学习系列之4:Logistic回归及Binary分类(二分问题)结果评估

    参数设置 α: 梯度上升算法迭代时候权重更新公式中包含 α :  http://blog.csdn.net/lu597203933/article/details/38468303 为了更好理解 α和 ...

  3. Spark中自定义累加器Accumulator

    1. 自定义累加器 自定义累加器需要继承AccumulatorParam,实现addInPlace和zero方法. 例1:实现Long类型的累加器 object LongAccumulatorPara ...

  4. spark2.0新特性之DataSet

    1.Spark SQL,DataFrame,DataSet的错误类型检测时机 spark SQL:其类型检测与语法检测是在运行时检测的 DataFrame:在spark2.0以前的版本中,DataFr ...

  5. geotrellis使用(二十五)将Geotrellis移植到spark2.0

    目录 前言 升级spark到2.0 将geotrellis最新版部署到spark2.0(CDH) 总结 一.前言        事情总是变化这么快,前面刚写了一篇博客介绍如何将geotrellis移植 ...

  6. Ubuntu14.04或16.04下安装JDK1.8+Scala+Hadoop2.7.3+Spark2.0.2

    为了将Hadoop和Spark的安装简单化,今日写下此帖. 首先,要看手头有多少机器,要安装伪分布式的Hadoop+Spark还是完全分布式的,这里分别记录. 1. 伪分布式安装 伪分布式的Hadoo ...

  7. maven+spark2.0.0最大连通分量

    运用到了spark2.0.0的grarhx包,要手动的在pom.xml里面添加依赖包,要什么就在里面添加依赖,然后在run->maven install

  8. Eclipse+maven+scala2.11.8+spark2.0.0的环境部署

    主要在maven-for-scalaIDE纠结了,因为在eclipse版本是luna4.x 里面有自己带有的maven. 根据网上面无脑的下一步下一步,出现了错误,在此讲解各个插件的用途,以此新人看见 ...

  9. spark2.0.1 安装配置

    1. 官网下载 wget http://d3kbcqa49mib13.cloudfront.net/spark-2.0.1-bin-hadoop2.7.tgz 2. 解压 tar -zxvf spar ...

随机推荐

  1. 基于H5的移动端开发,window.location.href在IOS系统无法触发问题

    最近负责公司的微信公众号开发项目,基于H5进行开发,某些页面window.location.href在Android机上能正常运行而IOS系统上无法运行,导致无法重定向到指定页面,查了好久终于找到方法 ...

  2. windows7 64位系统pl/sql 客户端的安装

    解压将下载到的将其解压,如我解压到了 E:\app\instantclient_11_2 3.设置PLSQL Developer在tools-prefrences,conncetion,OCI lib ...

  3. Python 3.x 使用csv模块写入数据

    with open(fileName,'w',newline='') as f: self.fileNames = ['timestamp','elapsedtime'] writer = csv.D ...

  4. scala学习----柯里化

    1.鸭子类型,走起来像鸭子,叫起来像鸭子,就是鸭子.函数中使用{ def close(): Unit }作为参数类型,因此任何含有此函数的类都可以作为参数传递.好处是不必使用继承特性. def wit ...

  5. Eclipse打不开,提示: An error has occurred. see the log file

    解决办法 删除.metadata目录下.plugins/org.eclipse.e4.workbench即可

  6. Python的平凡之路(21)

    上节内容回顾:1.请求周期url> 路由 > 函数或类 > 返回字符串或者模板语言?Form表单提交:    提交 -> url > 函数或类中的方法     - ... ...

  7. 使用Windows Form 制作一个简易资源管理器

    自制一个简易资源管理器----TreeView控件 第一步.新建project,进行基本设置:(Set as StartUp Project:View/Toolbox/TreeView) 第二步.开始 ...

  8. php+js实现分页

    使用onclick传递参数时,参数为空分页无效.因此无刷新页面时可利用js重新获取input的值同样通过get地址传递到分页显示的php页面.page参数接收和传递方式必须一致为post或get. j ...

  9. [Python学习笔记1]Python语言基础 数学运算符 字符串 列表

    这个系列是我在学习Python语言的过程中记录的笔记,主要是一些知识点汇总,而非学习教程,可供有一定编程基础者参考.文中偏见和不足难以避免,仅供参考,欢迎批评指正. 本系列笔记主要参考文献是官网文档: ...

  10. 本地测试AJAX请求

    要在本地测试AJAX,首先是环境的搭建,因为XHR对象的open方法中参数url是指文件在服务器上的文件.下面以WampServer为例. 1. 下载wamp的安装包,下载地址为:http://221 ...