Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala spark是否在内存中加载基本RDD_Scala_Apache Spark - Fatal编程技术网

Scala spark是否在内存中加载基本RDD

Scala spark是否在内存中加载基本RDD,scala,apache-spark,Scala,Apache Spark,我是新手。需要帮助了解spark的工作原理。 假设README.md存储在3个节点的HDFS128块中,我正在使用spark shell处理它 val textFile = sc.textFile("README.md") val linesWithSpark = textFile.filter(line => line.contains("Spark")) linesWithSpark.first() 在上述情况下,执行将由第3行触发 Spark将在HDFS节点的RAM中加载3段REA

我是新手。需要帮助了解spark的工作原理。 假设
README.md
存储在3个节点的HDFS128块中,我正在使用spark shell处理它

val textFile = sc.textFile("README.md")
val linesWithSpark = textFile.filter(line => line.contains("Spark"))
linesWithSpark.first()
在上述情况下,执行将由第3行触发

Spark将在HDFS节点的RAM中加载3段
README.md
,然后过滤
linesWithSpark
,并在内存中保留片刻。并从
linesWithSpark
发送第一行(从第一次拆分开始)? 或者,它只需从HDFS节点磁盘的Split1中拉出带有“Spark”的第一行,并将其发送给驱动程序

如果我将第二行更改为

val linesWithSpark = textFile.filter(line => line.contains("Spark")).cache()

让我们从一个简单的实验开始。首先让我们加载数据并检查其分布:

val textFile = sc.textFile("README.md", 2)
textFile.glom.map(_.size).collect
// Array[Int] = Array(54, 41)
正如我们可以怀疑的那样,simple
filter
只生成一个任务:

textFile.filter(line => line.contains("Spark")).toDebugString
// String = 
// (2) MapPartitionsRDD[11] at filter at <console>:30 []
//  |  MapPartitionsRDD[8] at textFile at <console>:27 []
//  |  README.md HadoopRDD[7] at textFile at <console>:27 []
正如您所看到的,没有缓存的作业将只处理一条记录。之所以发生这种情况,是因为
first
作为
take(1)
执行。在第一次迭代中,
take
仅运行作业并使用它。take(左),其中
left
在其迭代器上等于一

由于迭代器是惰性的,我们的程序在处理第一行后立即返回。如果第一个分区没有提供所需的结果
take
每次迭代都会增加已处理分区的数量

接下来,让我们对缓存重复相同的实验:

val cacheCntCache = sc.accumulator(0L, "cacheCnt")

val linesWithSparkCached = textFile.filter(line => {
  cacheCntCache  += 1L
  line.contains("Spark")
}).cache()

linesWithSparkCached.first()
// String = # Apache Spark
cacheCntCache.value
// Long = 54
此外,让我们检查存储信息:

sc.getRDDStorageInfo
// Array[org.apache.spark.storage.RDDInfo] = Array(
//   RDD "MapPartitionsRDD" (12)
//   StorageLevel: StorageLevel(false, true, false, true, 1); 
//   CachedPartitions: 1; TotalPartitions: 2; MemorySize: 1768.0 B; 
//   ExternalBlockStoreSize: 0.0 B; DiskSize: 0.0 B)
正如您所看到的那样,CACHESPARK将完成对分区的处理并将其缓存在内存中。虽然我不能提供造成这种行为的源代码的确切部分,但它看起来是一个合理的优化。由于分区已加载,因此没有理由停止作业


另请参见:

不是实际答案,而是几句话。您不应该关心用户级步骤的精确执行顺序,这就是Spark的用途。不过,您可以在spark的web UI中检查执行DAG。另一点是,
sc.textFile(“README.md”)
将在路径/工作目录上查找“README.md”文件,而不是在HDFS上,您必须显式地为函数/方法指定HDFS URI。感谢您的详细解释。
sc.getRDDStorageInfo
// Array[org.apache.spark.storage.RDDInfo] = Array(
//   RDD "MapPartitionsRDD" (12)
//   StorageLevel: StorageLevel(false, true, false, true, 1); 
//   CachedPartitions: 1; TotalPartitions: 2; MemorySize: 1768.0 B; 
//   ExternalBlockStoreSize: 0.0 B; DiskSize: 0.0 B)