spark中RDD本身并不保存数据,每个对当前RDD的调用都需要从源头进行一次重新计算。因此,为了尽可能地复用计算结果,可以将当前RDD的内容保存到内存或者磁盘中。
首先看一个例子,理解一下RDD的工作流程:
JavaRDD<Integer> rdd1 = sparkContext.parallelize(List.of(1, 2, 3, 4, 5));
JavaRDD<Integer> rdd2 = rdd1.map(x->{
System.out.println("被调用");
return x+1;
});
JavaRDD<Integer> rdd3 = rdd2.map(x -> x);
JavaRDD<Integer> rdd4 = rdd2.map(x -> x);
rdd3.collect();
rdd4.collect();
会输出多少次“被调用”呢,实际上是十次。因为在saprk的执行过程中,这个工作过程实际上是这样的:
这里还好,依赖关系还不算长,如果依赖关系再长一点,那么计算代价就更大了,因此对于RDD2这种可能被复用的RDD,可以将其保存到内存或者瓷盘中,这样只需要一次计算,之后对RDD2的调用可以直接从内存或者磁盘中读取出来:
这里写入的过程就是cache()
或者persist()
,cache就是将rdd写到内存当中,persist()方法的参数可以指定将结果写入到内存还是磁盘。