我有一个PairRDD<Metadata, BigData>
。
我想执行两项操作:一项针对RDD
中的所有数据,另一项仅针对元数据。
输入来自读取海量文件,我不想重复。
我知道经典的做法是在输入RDD上使用cache()
或persist()
以便将其保存在内存中:
JavaPairRDD<Metadata, Bigdata> inputRDD = expensiveSource();
JavaPairRDD<Metadata, Bigdata> cachedRDD = inputRDD.cache();
cachedRDD.foreach(doWorkOnAllData);
cachedRDD.keys().foreach(doWorkOnMetadata);
问题在于输入量太大,以致无法容纳在内存中,因此cache()
不能执行任何操作。
我可以使用persist()
将其缓存在磁盘上,但是由于数据很大,因此保存和读取所有数据实际上比读取原始数据要慢。
我可以使用MEMORY_SERDE
来获得一些空间,但这可能是不够的,即使当我只对0.1%的数据感兴趣时,甚至整个序列化都显得很愚蠢。
我想要的是仅缓存我的PairRDD
的关键部分。我以为可以通过在cache()
keys()
上调用RDD
来做到这一点:
JavaPairRDD<Metadata, Bigdata> inputRDD = expensiveSource();
JavaRDD<Metadata, Bigdata> cachedRDD = inputRDD.keys().cache();
inputRDD.foreach(doWorkOnAllData);
cachedRDD.foreach(doWorkOnMetadata);
但是在那种情况下,它似乎并没有缓存任何东西,而只是返回以加载源代码。
是否可以仅将一部分数据放入缓存?对元数据的操作非常小,但是在对整个数据进行操作之后,我必须这样做。
答案 0 :(得分:0)
只有调用inputRDD.keys()
您可以尝试的是:JavaRDD<Metadata> keys = inputRDD.keys().cache();
来缓存JavaRDD<Metadata>
然后创建缓存的RDD:
JavaRDD<Metadata,Bigdata> cachedRDD = keys.join(JavaPairRDD<Bigdata>)
如果您的RDD很大,则第一次从缓存中读取速度最慢,因为您必须保存RDD,但是下次读取它时,它将更快。