刚做了一些关于spark unpersist()的实验,并对它实际上做了什么感到困惑。我google了很多,几乎所有人都说unpersist()会立即从激励器的记忆中驱逐RDD。但是在这个测试中,我们可以看到它并不总是真的。看下面的简单测试:
private static int base = 0;
public static Integer[] getInts(){
Integer[] res = new Integer[5];
for(int i=0;i<5;i++){
res[i] = base++;
}
System.out.println("number generated:" + res[0] + " to " + res[4] + "---------------------------------");
return res;
}
public static void main( String[] args )
{
SparkSession sparkSession = SparkSession.builder().appName("spark test").getOrCreate();
JavaSparkContext spark = new JavaSparkContext(sparkSession.sparkContext());
JavaRDD<Integer> first = spark.parallelize(Arrays.asList(getInts()));
System.out.println("first: " + Arrays.toString(first.collect().toArray())); // action
first.unpersist();
System.out.println("first is unpersisted");
System.out.println("compute second ========================");
JavaRDD<Integer> second = first.map(i -> {
System.out.println("double " + i);
return i*2;
}).cache(); // transform
System.out.println("second: " + Arrays.toString(second.collect().toArray())); // action
second.unpersist();
System.out.println("compute third ========================");
JavaRDD<Integer> third = second.map(i -> i+100); // transform
System.out.println("third: " + Arrays.toString(third.collect().toArray())); // action
}
输出是:
number generated:0 to 4---------------------------------
first: [0, 1, 2, 3, 4]
first is unpersisted
compute second ========================
double 0
double 1
double 2
double 3
double 4
second: [0, 2, 4, 6, 8]
compute third ========================
double 0
double 1
double 2
double 3
double 4
third: [100, 102, 104, 106, 108]
正如我们所看到的,unpersist()'first'是无用的,它不会重新计算。 但是unpersist()'second'会触发重新计算。 任何人都可以帮我弄清楚为什么unpersist()'first'不会触发重新计算?如果我想强迫'先'被驱逐出记忆,我该怎么办?从parallelize或textFile()API有什么特殊的RDD? 谢谢!
答案 0 :(得分:1)
此行为与缓存和unpersisting
无关。实际上first
甚至不是persisted
,尽管这里没有太大区别。
当您parallelize
时,您传递一个本地的非分布式对象。 parallelize
通过值获取其参数,其生命周期完全超出Spark的范围。因此,一旦ParallelCollectionRDD
初始化,Spark就没有理由重新计算它。如果您想分发不同的集合,只需创建一个新的RDD
。
值得注意的是,unpersist
可以在阻塞和非阻塞模式下调用,具体取决于blocking
参数。