我一直听说Spark比Hadoop等经典的Map Reduce框架快100倍。但最近我读到,只有当RDD被缓存时,这才是真的,我认为这一直都是这样,但需要显式的cache((方法。
我想了解在整个工作过程中如何存储所有生成的RDD。假设我们有这样的工作流程:
- 我读了一个文件->我得到RDD_ONE
- 我使用RDD_ONE上的地图->我得到RDD_TWO
- 我在RDD_TWO上使用任何其他变换
问题:
如果我不使用cache((或persistent((,那么每个RDD都存储在内存、缓存或磁盘(本地文件系统或HDFS(中吗?
如果RDD_THREE依赖于RDD_TWO,而这又取决于RDD_ONE(沿袭(如果我没有在RDD_THERIE上使用cache((方法,Spark应该重新计算RDD_ONE(从磁盘上重读(,然后RDD_TWO来获得RDD_THRIE?
提前谢谢。
在spark中有两种类型的操作:转换和操作。数据帧上的转换将返回另一个数据帧,对数据帧的操作将返回一个值。
转换是惰性的,所以当执行转换时,spark会将其添加到DAG中,并在调用操作时执行它。
假设,您将一个文件读取到数据帧中,然后执行筛选、联接、聚合,然后计数。计数操作是一个操作,它实际上会踢开之前的所有转换。
如果我们调用另一个操作(如show(,整个操作将再次执行,这可能会很耗时。因此,如果我们不想一次又一次地运行整个操作集,我们可以缓存数据帧。
缓存时可以考虑的几个指针:
- 仅当从重要转换生成结果数据帧时才缓存。如果spark可以在几秒钟内重新生成缓存的数据帧,那么就不需要缓存了
- 当数据帧用于多个操作时,应执行缓存。如果数据帧上只有1-2个操作,那么不值得将该数据帧保存在内存中
默认情况下,每次对每个转换后的RDD运行操作时,都可能会重新计算它。但是,您也可以使用persistent(或cache(方法将RDD持久化在内存中,在这种情况下,Spark将保留集群中的元素,以便下次查询时更快地访问它。还支持将RDD永久化在磁盘上,或跨多个节点复制
回答您的问题:
Q1:如果我不使用cache((或persistent((,那么每个RDD都存储在内存、缓存或磁盘(本地文件系统或HDFS(中吗?Ans:当为文件创建rdd作为时,将worker节点中可用的数据视为HDFS中的块
val rdd=sc.textFile("<HDFS Path>")
来自每个节点(HDFS(的底层数据块将作为分区加载到它们的RAM(i,e存储器((在spark中,一旦加载到存储器中,HDFS数据块就被称为分区(
Q2:如果RDD_THREE依赖于RDD_TWO,而这反过来又取决于RDD_ONE(沿袭(。如果我没有在RDD_THERIE上使用cache((方法,Spark应该重新计算RDD_ONE(从磁盘上重读(,然后RDD_TWO得到RDD_THRIE?答:是的。因为在这种情况下,基本结果不会通过使用cache((存储在驱动程序内存中。