Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.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 在持久化RDD上执行多个操作时缓存RDD的工作方式_Scala_Apache Spark_Caching_Rdd - Fatal编程技术网

Scala 在持久化RDD上执行多个操作时缓存RDD的工作方式

Scala 在持久化RDD上执行多个操作时缓存RDD的工作方式,scala,apache-spark,caching,rdd,Scala,Apache Spark,Caching,Rdd,这个案子怎么办?在以下代码的情况下 val logList: RDD[String] = ... val errorLogs = logList.filter(_.contains("Error")).persist() //first action val first100 = errorLogs.take(100) //second action val count = errorLogs.count Spark不会扫描所有日志,因为Park知道我们只对100行日志感兴趣。但是当我

这个案子怎么办?在以下代码的情况下

val logList: RDD[String] = ...
val errorLogs = logList.filter(_.contains("Error")).persist()
//first action   
val first100 = errorLogs.take(100)
//second action
val count = errorLogs.count 
Spark不会扫描所有日志,因为Park知道我们只对100行日志感兴趣。但是当我们缓存这个RDD并对其调用多个操作时会发生什么呢?第一个操作只需要很少的记录,而后面的操作则需要转换整个RDD


当调用第一个操作时,它会缓存记录吗?或者,在调用第一个操作时,它是否只缓存第一个操作所需的部分记录?

在这种情况下,Spark将只缓存收集100条记录所需的最小分区数(由于采用了实现,实际数目可能会更高)


只有第二个保证缓存所有记录。

如何
缓存
工作

  • cache
    persist
    是惰性的-如果未对标记为缓存数据的
    RDD调用任何操作,则不会持久化。类似地,如果未计算分区,则不会持久化数据
  • 缓存
    持久化整个分区。它不能保存单个记录或部分分区。若数据被标记为缓存,并且分区至少被部分计算,Spark将对其进行完全计算并尝试持久化
限制如何起作用

  • 第一个
    limit
    计算第一个分区。如果可以从第一个分区收集limit所需的所有记录,则作业完成
  • 如果不是,Spark会增加由
    Spark.rdd.limit.scaleUpFactor
    计算的分区数。如果limit所需的所有记录都可以从这些分区中收集,则作业完成。否则,重复此步骤
这意味着:

  • val first100=errorLogs.take(100)
    将至少缓存第一个分区。如果第一个分区不包含100条记录,它将计算并缓存后续分区,直到得到100条记录或计算完整的数据集
  • val count=errorLogs.count
    将评估所有分区,并尽可能缓存其余分区
  • val errorLogs=logList.filter(u.contains(“Error”)).take(100)
    的工作原理与
    errorLogs.take(100)
    几乎完全相同。
    filter
    的唯一影响是
    limit
    可能需要评估更多数据。如果所有行都包含
    错误
    ,则结果与第一步相同

    如果在前两个步骤之后运行,并且数据已完全缓存且未被逐出,则它将使用缓存中的数据


似乎是合理的,但是。那么,在第一种情况下,让我与您核对一下:假设日志文件根据磁盘大小有22个分区,那么,如果所有错误都位于12个分区-->上,并且包含2.2M条记录,那么收集100条记录所需的最小记录数是多少,给出了RDD并行处理的一般原理和并行发生的事情?如果我们明白这一点,那么我们就知道答案,而你很可能知道?因此也就是说,我发现这方面的文档很难找到。只有第二个可以保证缓存所有记录。。。您的意思是val count=errorLogs.count还是val errorLogs=logList.filter(u.contains(“Error”))。取(100)。我不确定我是否明白。这是很难的事情,没有很好的解释。问题是什么是持久的RDD。@蓝色幻影:第二个意思是调用action errorLogs.count。因为count必须扫描整个数据集才能得到实际结果。因此,在这个操作过程中,错误日志将被完全缓存。这似乎是有道理的,但我的第一个问题可能意味着,事实上,由于1)并行化,所有日志都被缓存,或者缓存的数量超过了最小值;2)如果没有找到任何记录,它将缓存所有日志,因为它必须扫描所有日志才能确定这一点
val errorLogs = logList.filter(_.contains("Error")).take(100)