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 ...
随机推荐
- 如何使用.NET开发全版本支持的Outlook插件产品(一)——准备工作
这半年一直在做Outlook的插件,因为不会VC++,所以想找一款基于.NET,用C#开发Outlook插件的技术方案.没想到,光技术选型这件事,就用各种技术手段验证了将近一个月,还花费了大量的精力做 ...
- centos7安装
1.准备工具 VMware,我用的是 VMware11 2.打开VMware,创建新的虚拟机 3.选择典型-->下一步 4.稍后安装操作系统-->下一步 5.选择linux操作系统,lin ...
- kanboard邮件通知
1. 复制config.default.php为config.php 2. 修改一下内容 define('MAIL_TRANSPORT', 'smtp');define('MAIL_SMTP_HOST ...
- hard
硬盘电路板将信号转化为电压高低,电压控制电脉冲被送到磁头,产生一个电磁.磁盘和磁头很紧密.读写都是不断扫描磁盘的过程.有操作系统负责控制文件的组织,可能在不同的块中.
- C#同一项目中不同文件或类中的方法进行调用
有两种方法,一是将被调用的类设置成静态类Static,这样就可以直接点出来了,二是将被调用的方法所在类设置成public,这几必须在调用类中先将被调用的类进行实体化,new()出来,再点出来. 一. ...
- BootStrap 的modal 中使用typeahead
刚开始怎么也不现实,在页面上显示正常. 调试发现是下拉框被modal遮挡住了, 找到样式dropdown-menu 修改z-index值为2000后,显示正常.(modal的z-index值为1 ...
- 北大poj-2688
Cleaning Robot Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4395 Accepted: 1763 De ...
- [解决方案] pythonchallenge level 1
http://www.pythonchallenge.com/pc/def/map.html g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amk ...
- 【RobotFramework自动化测试】数据库值验证
${sqlCount} Row Count ${sqlStr} #注释:Row Count 将SQL查询结果的行数返回给前面的参数: @{rs} query ${sqlS ...
- Settings
任何一个构件都有唯一的坐标,根据这个坐标可以定义其在仓库中的唯一存储路径,这是Maven的仓库布局方式. groupId/artifactId/version/artifactId-version(- ...