Spark2.0自定义累加器
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自定义累加器的更多相关文章
- 初识Spark2.0之Spark SQL
内存计算平台spark在今年6月份的时候正式发布了spark2.0,相比上一版本的spark1.6版本,在内存优化,数据组织,流计算等方面都做出了较大的改变,同时更加注重基于DataFrame数据组织 ...
- Spark2.0机器学习系列之4:Logistic回归及Binary分类(二分问题)结果评估
参数设置 α: 梯度上升算法迭代时候权重更新公式中包含 α : http://blog.csdn.net/lu597203933/article/details/38468303 为了更好理解 α和 ...
- Spark中自定义累加器Accumulator
1. 自定义累加器 自定义累加器需要继承AccumulatorParam,实现addInPlace和zero方法. 例1:实现Long类型的累加器 object LongAccumulatorPara ...
- spark2.0新特性之DataSet
1.Spark SQL,DataFrame,DataSet的错误类型检测时机 spark SQL:其类型检测与语法检测是在运行时检测的 DataFrame:在spark2.0以前的版本中,DataFr ...
- geotrellis使用(二十五)将Geotrellis移植到spark2.0
目录 前言 升级spark到2.0 将geotrellis最新版部署到spark2.0(CDH) 总结 一.前言 事情总是变化这么快,前面刚写了一篇博客介绍如何将geotrellis移植 ...
- Ubuntu14.04或16.04下安装JDK1.8+Scala+Hadoop2.7.3+Spark2.0.2
为了将Hadoop和Spark的安装简单化,今日写下此帖. 首先,要看手头有多少机器,要安装伪分布式的Hadoop+Spark还是完全分布式的,这里分别记录. 1. 伪分布式安装 伪分布式的Hadoo ...
- maven+spark2.0.0最大连通分量
运用到了spark2.0.0的grarhx包,要手动的在pom.xml里面添加依赖包,要什么就在里面添加依赖,然后在run->maven install
- Eclipse+maven+scala2.11.8+spark2.0.0的环境部署
主要在maven-for-scalaIDE纠结了,因为在eclipse版本是luna4.x 里面有自己带有的maven. 根据网上面无脑的下一步下一步,出现了错误,在此讲解各个插件的用途,以此新人看见 ...
- spark2.0.1 安装配置
1. 官网下载 wget http://d3kbcqa49mib13.cloudfront.net/spark-2.0.1-bin-hadoop2.7.tgz 2. 解压 tar -zxvf spar ...
随机推荐
- 在eclipse的maven插件中搜寻本地仓库中的jar搜索不到的解决方案
在eclipse的maven插件中搜寻本地仓库中的jar搜索不到的解决方案 之前,用过maven管理项目的童鞋都知道本地会有一个${User_Home}.m2/repository仓库 是用来存放ja ...
- 第二篇.Bootstrap起步
第二篇Bootstrap起步 我们可以在http://getbootstrap.com下载bootstrap的文件 点击左边的download bootstrap可以下载bootstrap的css,j ...
- Unity3D之GUITexture的坐标体系
Unity3D的GUITexture的坐标,其中x和y的取值在0~1之间,层次使用z来划分,值越大越靠前.
- ubuntu方块乱码
更改下环境变量/etc/default/locale LANG="en_US.UTF-8"LANGUAGE="en_US:en"
- Java泛型学习笔记 - (三)泛型方法
泛型方法其实和泛型类差不多, 就是把泛型定义在方法上, 格式大概就是: public <类型参数> 返回类型 方法名(泛型类型 变量名) {...}泛型方法又分为动态方法和静态方法,:1. ...
- javascript页面加载完执行事件
<script type="text/javascript" language="JavaScript"> //: 判断网页是否加载完成 docum ...
- 【转】 Easy RadControl 之 RadGridView(Silverlight)
1.不显示第1列即列指示器(Row Indicators) 在 telerik:RadGridView中设置属性 RowIndicatorVisibility="Collapsed&qu ...
- python3下载远程代码并执行
第一步: 先在gist之类的网站上贴上代码,目的不是高亮,而可以raw的形式获取代码,这样可以省掉处理html的时间,我这里用的是pasteraw: 远程上的代码:http://cdn.pastera ...
- vs2013发布网站
第一次在Server2008中发布网站,期间发生了很多的错误,这里记录下来,以供以后的学习. (1).首先在IIS上先建一个网站,(网站名称.物理路径.类型 IP地址 和端口)然后点击确认,这样就是先 ...
- 基于KNN的newsgroup 18828文本分类器的Python实现
还是同前一篇作为学习入门. 1. KNN算法描述: step1: 文本向量化表示,计算特征词的TF-IDF值 step2: 新文本到达后,根据特征词确定文本的向量 step3 : 在训练文本集中选出与 ...