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. JAVAFX纯手写布局

    主页面效果: 第一栏的效果: 工程目录: package MessageBean; /** * * @author novo */ public class Message { private Str ...

  2. Devexpress Winform Gridcontrol 中根据条件单元格的值改变单元格的颜色等属性。

    提供一下三种方法 1.使用设计器 点击gridcontrol控件,run designer,format Condtions, add,然后进行各种条件的设置. 2.用代码代替设计器. 实例代码: p ...

  3. MySQL 通过semi join 优化子查询

    半连接是MySQL 5.6.5引入的,多在子查询exists中使用,对外部row source的每个键值,查找到内部row source匹配的第一个键值后就返回,如果找到就不用再查找内部row sou ...

  4. php项目中使用memcache

    memcache为分布式内存缓存系统,通过在内存中存取数据和对象减少对数据库的访问从而减轻数据库的负载,memcache分为客户端和服务端,服务端为C实现,有现成的服务端应用程序,无需开发,只需要配置 ...

  5. Spring中的自动装配

    src\dayday\Person.java package dayday;/** * Created by I am master on 2016/11/28. */public class Per ...

  6. Ubuntu 14.10 创建虚拟网卡实现桥接网络

    目标需求:在Ubuntu主机创建一张虚拟网卡,使得搭建在VirtualBox中的其他主机能借助虚拟网卡构建的局域网进行相互间的通讯 步骤一:准备工具包 安装 uml-utilities 以及 brid ...

  7. 注意linux下面的命令行,要将PATH声明出来

    export PATH=/apps/svr/maven/bin:/apps/svr/jdk7/bin:/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/s ...

  8. IDEA安装配置(SVN)

    IntelliJ IDEA 14 注册码 Win7系统上配置使用Intellij Idea 13的SVN插件 IntelliJ 设置JDK http://blog.sina.com.cn/s/blog ...

  9. 虚机centos和本机Windows之间文件的拷贝无法用xftp时用FileZilla也行

    步骤如下: 1.如果Centos没有安装ssh,则需要先安装: 2.查看虚拟机中IP地址,命令如下: ifconfig 3.在windows中安装ftp软件 FileZilla启动软件如图: 6  这 ...

  10. 第一章:Android系统移植与驱动开发概述

    Android是基于Linux内核的,与Linux内核没有太大的区别,只是增加了一些自己独有的驱动,随着Android发布版本的不断升级,他所使用的Linux内核也在不断升级,以适应新的安卓版本,为他 ...