1.共享变量
1.1累加器
对信息进行聚合,常见用途是在调试时对作业执行过程中的时间进行计数
使用过程
- 通过在驱动器中调用 SparkContext.accumulator(initialValue) 方法,创建出存有初
始值的累加器。返回值为 org.apache.spark.Accumulator[T] 对象,其中 T 是初始值
initialValue 的类型。 - park闭包里的执行器代码可以使用累加器的 += 方法(在Java中是 add )增加累加器的值。
- 驱动器程序可以调用累加器的 value 属性(在 Java 中使用 value() 或 setValue() )来访
问累加器的值。- [x] 注意,工作节点上的任务不能访问累加器的值
val sc = new SparkContext(...)
val file = sc.textFile("file.txt")
val blankLines = sc.accumulator(0) // 创建Accumulator[Int]并初始化为0
val callSigns = file.flatMap(line => {
if (line == "") {
blankLines += 1 // 累加器加1
}
line.split(" ")
})
callSigns.saveAsTextFile("output.txt")
println("Blank lines: " + blankLines.value)
由于flatMap是惰性的,只有执行saveAsTextFila行动操作时,才会触发开始求值
累加器于容错性
Spark 会自动重新执行失败的或较慢的任务来应对有错误的或者比较慢的机器。例如,如
果对某分区执行 map() 操作的节点失败了,Spark 会在另一个节点上重新运行该任务。即
使该节点没有崩溃,而只是处理速度比别的节点慢很多,Spark 也可以抢占式地在另一个
节点上启动一个“投机”(speculative)型的任务副本,如果该任务更早结束就可以直接获
取结果。即使没有节点失败,Spark 有时也需要重新运行任务来获取缓存中被移除出内存
的数据。因此最终结果就是同一个函数可能对同一个数据运行了多次,这取决于集群发生
了什么。
这种情况下累加器要怎么处理呢?实际结果是,对于要在行动操作中使用的累加器,Spark
只会把每个任务对各累加器的修改应用一次。因此,如果想要一个无论在失败还是重复计
算时都绝对可靠的累加器,我们必须把它放在 foreach() 这样的行动操作中。
对于在 RDD 转化操作中使用的累加器,就不能保证有这种情况了。转化操作中累加器可
能会发生不止一次更新。
1.2广播变量
高效分发较大的对象:高效地项所有工作节点发送一个较大的只读值
使用过程
- 通过对一个类型 T 的对象调用 SparkContext.broadcast 创建出一个 Broadcast[T] 对象。
任何可序列化的类型都可以这么实现。 - 通过 value 属性访问该对象的值(在 Java 中为 value() 方法)。
- 变量只会被发到各个节点一次,应作为只读值处理(修改这个值不会影响到别的节点)。
val broadcastData = sc.broadcast(List("java","scala","spark")) broadcastData.value # res1: List[String] = List(java, scala, spark)
点击查看更多内容
1人点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦