Scala中SparkContext.sequenceFile(…).foreach的作用域问题
我的目标是处理通过调用Scala中SparkContext.sequenceFile(…).foreach的作用域问题,scala,apache-spark,Scala,Apache Spark,我的目标是处理通过调用org.apache.spark.rdd.rdd[.].saveAsObjectFile(…)生成的一系列SequenceFile文件夹。我的文件夹结构与此类似: \MyRootDirectory \Batch0001 _SUCCESS part-00000 part-00001 ... part-nnnnn \Batch0002 _SUCCESS part-00000 part-000
org.apache.spark.rdd.rdd[.].saveAsObjectFile(…)
生成的一系列SequenceFile
文件夹。我的文件夹结构与此类似:
\MyRootDirectory
\Batch0001
_SUCCESS
part-00000
part-00001
...
part-nnnnn
\Batch0002
_SUCCESS
part-00000
part-00001
...
part-nnnnn
...
\Batchnnnn
_SUCCESS
part-00000
part-00001
...
part-nnnnn
我需要提取一些持久化的数据,但是我的收集-无论我使用的是ListBuffer
,mutable.Map
,还是任何其他可变类型,都会丢失范围,并且在sequenceFile(…)的每次迭代中都会出现新的内容。foreach
下面的概念验证生成了一系列“处理目录…”,后面是“1:1”,重复且从不增加,正如我所期望的那样counter
和intList.size
private def proofconcept(rootDirectoryName:String)={
val intList=ListBuffer[Int]()
变量计数器:Int=0
val config=new SparkConf().setAppName(“本地”).setMaster(“本地[1]”)
新文件(rootDirectoryName).listFiles().map(u.toString).foreach{folderName=>
println(s“正在处理目录$folderName…”)
val sc=新的SparkContext(配置)
sc.setLogLevel(“警告”)
sc.sequenceFile(folderName,classOf[NullWritable],classOf[BytesWritable]).foreach(f=>{
计数器+=1
intList+=计数器
println(s“$counter:${intList.size}”)
})
sc.停止()
}
}
输出:
"C:\Program Files\Java\jdk1.8.0_111\bin\java" ...
Processing directory C:\MyRootDirectory\Batch0001...
17/05/24 09:30:25.228 WARN [main] org.apache.hadoop.util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
[Stage 0:> (0 + 0) / 57] 1 : 1
1 : 1
1 : 1
1 : 1
1 : 1
1 : 1
1 : 1
1 : 1
Processing directory C:\MyRootDirectory\Batch0002...
1 : 1
1 : 1
1 : 1
1 : 1
1 : 1
1 : 1
1 : 1
1 : 1
Processing directory C:\MyRootDirectory\Batch0003...
1 : 1
1 : 1
1 : 1
1 : 1
1 : 1
1 : 1
1 : 1
1 : 1
foreach
中的函数在spark worker JVM中运行,而不是在定义变量的客户机JVM中运行。该worker在本地获取该变量的副本,对其进行递增并打印。我猜你是在本地测试这个?如果您在生产、分布式spark环境中运行此程序,您甚至看不到这些打印的输出
更一般地说,几乎所有传递到RDD方法中的函数都可能是远程执行的,并且不会对任何局部变量或任何东西进行可变访问。它将获得它们的一个基本不变的快照
如果要将数据从spark的分布式存储移回客户端,请使用RDD的
collect
方法。使用sc.parallelize
可实现相反的操作。但请注意,这两种情况通常很少发生,因为它们不会同时发生。当火花消失时,您看到了吗?