1.累加器
1.产生背景
问题:统计此次执行过程中map执行的次数
//创建程序入口
val conf = new SparkConf()
.setAppName("Demo2")
.setMaster("local[2]")
val sc = new SparkContext(conf)
//生成RDD对象
val RDD = sc.makeRDD(1 to 10)
//编写逻辑
val value = RDD.map(x => x + 1)
value.foreach(println)
观察上面的代码,我们不难发现对1到10每个数字进行加一操作,总共执行了十次。但是由于多核心多线程的因素,每个RDD任务会放到不同的机器上,开启不同的线程来完成它,因此我们这里无法直接拿到这个次数10,因而就产生了累加器。
2.累加器的使用步骤
//1.创建累加器
val acc = new LongAccumulator
//2.使用sc注册计数器
sc.register(acc)
//3.在转换算子中使用累加器
acc.add(1)
//4.RDD任务执行结束以后,访问累加器的值
println(acc.value)
3.累加器的原理
class myAcc extends AccumulatorV2[Long, Long] {
var count: Long = 0L
/**
* 判断当前累加器是否为初始值
*
* @return
*/
override def isZero: Boolean = this.count == 0
/**
* 复制当前累加器的状态
*
* @return
*/
override def copy(): AccumulatorV2[Long, Long] = {
val acc = new myAcc
acc.count = this.count
acc
}
/**
* 重置当前累加器的值
*/
override def reset(): Unit = this.count = 0L
/**
* 为累加器添加输入值
*
* @param v
*/
override def add(v: Long): Unit = this.count += v
/**
* 将另一个累加器的值合并到当前累加器
*
* @param other
*/
override def merge(other: AccumulatorV2[Long, Long]): Unit = {
this.count += other.value
}
/**
* 取出累加器中保存的值
*
* @return
*/
override def value: Long = this.count
}
2.广播变量
1.产生背景
例如有些数据校验文件在运行过程中需要对每个数据进行校验,如果在每一个线程中都保存一份资源文件,那么就显得极为浪费资源,倘若检验文件过大,就无法完成正常的程序。因此需要一个公共区域来保存这些资源文件,每个线程只要访问公共区域的资源文件就可以解决上述问题。
2.创建及其使用
//1.使用sc创建广播变量
val ss = sc.broadcast(公共资源)
//2.从广播变量中取出
val value1 = ss.value