火花里的闭包是什么

介绍

本篇内容主要讲解“火花里的闭包是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“火花里的闭包是什么”吧!

<节>

闭包的概念如下图:

火花里的闭包是什么

在火花应用里,变量及函数的作用范围和声明周期在火花的集群运行模式下是比较难理解的,尤其是对初学者来说.RDD的操作,要修改其作用范围的变量,经常会出点叉子。下面,可以举个用foreach,修改一个计数器的例子。

<>强例子

求和抽样元素的例子,该例子会根据该段代码是否执行在同一个jvm里面有不同的输出结果,比如当地模式,运行于同一个jvm,输出是15;集群模式运行于不同jvm输出是0。

val data=https://www.yisu.com/zixun/Array (1、2、3、4、5)

var counter=0

var抽样=sc.parallelize(数据)

//错误的:不要# 39;t这么做! !

抽样。foreach (x=比;计数器+=x)

println(“计数器值:“;+计数器)

<强>本地或集群模式

上述代码的行为是未定义的,并且不同模式下运行情况不同。为了执行作业,火花将抽样操作的处理分解为任务,每个任务由执行人执行。在执行之前,火花会计算任务的闭包,闭包是遗嘱执行人在抽样上进行计算的时候必须可见的那些变量和方法(在这种情况下是foreach()),闭包会被序列化并发送给每个执行人。

发送给每个执行人的闭包中的变量是副本,因此,当foreach函数内引用计数器时,它不再是司机节点上的计数器.driver节点的内存中仍有一个计数器,但该变量是遗嘱执行人不可见的!执行者只能看到序列化闭包的副本。因此,计数器的最终值仍然为零,因为计数器上的所有操作都引用了序列化闭包内的值。

在本地模式下,在某些情况下,该foreach函数实际上将在与司机相同的JVM内执行,并且会引用相同的原始计数器,并可能实际更新它。

为了确保在这些场景中明确定义的行为,应该使用一个Accumulator.Spark中的累加器专门用于提供一种机制,用于在集群中的工作节点之间执行拆分时安全地更新变量。

一般来说,闭包——构造像循环或本地定义的方法,不应该被用来改变一些全局状态.Spark并没有定义或保证从闭包外引用的对象的改变行为。这样做的一些代码可以在本地模式下工作,但这只是偶然,并且这种代码在分布式模式下的行为不会像你想的那样。如果需要某些全局聚合,请改用累加器。

<>强打印抽样的元素

另一个常见的习惯用法是尝试使用rdd.foreach println()或rdd.map println()打印出抽样的元素。在单台机器上,这将产生预期的输出并打印所有抽样的元素。但是,在集群模式下,由遗嘱执行人执行输出写入的是执行程序的标准输出,而不是驱动程序上的那个stdout,所以驱动程序的标准输出不会显示这些!要在驱动程序中打印所有元素,可以使用该收集()方法首先将抽样数据带到司机节点:rdd.collect () .foreach (println)。但这可能会导致驱动程序内存不足,因为收集()会将整个抽样数据提取到司机端;如果您只需要打印抽样的一些元素,则更安全的方法是使用带():rdd.take (100) .foreach (println)。

到此,相信大家对“火花里的闭包是什么”有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

火花里的闭包是什么