我们有一个小的蜂巢表(大约50000条记录),每天更新一次。
我们为此表提供了一个缓存的数据框,并且正在加入火花流数据。在基础配置单元中加载新数据时,我们如何刷新数据框?
DataFrame tempApp = hiveContext.table("emp_data");
//Get Max Load-Date
Date max_date = max_date = tempApp.select(max("load_date")).collect()[0].getDate(0);
//Get data for latest date and cache. This will be used to join with stream data.
DataFrame emp= hiveContext.table("emp_data").where("load_date='" + max_date + "'").cache();
// Get message from Kafka Stream
JavaPairInputDStream<String, String> messages = KafkaUtils.createDirectStream(....);
JavaDStream<MobileFlowRecord> rddMobileFlorRecs = messages.map(Record::parseFromMessage);
kafkaRecs.foreachRDD(rdd->{DataFrame recordDataFrame = hiveContext.createDataFrame(rdd, Record.class);
DataFrame joinedDataSet = recordDataFrame.join(emp,
recordDataFrame.col("application").equalTo(app.col("emp_id"));
joinedDataSet. <Do furthur processing>
});
答案 0 :(得分:1)
如果不再使用RDD或Dataframe,则自动unpersist
。为了知道是否缓存了RDD或Dataframe,您可以进入Spark UI - &gt;存储选项卡并查看内存详细信息。您可以使用df.unpersist()
或sqlContext.uncacheTable("sparktable")
uncacheTable APi从内存中移除df或表。此选项在新SparksessionAPi中不可用,但向后兼容性始终存在。 Spark为Lazy Evaluation做,除非你说任何动作,否则它不会将任何数据加载或处理到RDD或DataFrame中。
为此,为您执行join
后,为您的Dataframe执行unpersist()。这将提高性能,并解决您的问题。
答案 1 :(得分:1)
您可以手动执行此操作。像这样:
DataFrame refresh(DataFrame orig) {
if (orig != null) {
orig.unpersist();
}
DataFrame res = get the dataframe as you normally would
res.cache()
return res
现在每天拨打一次电话或者您希望像这样刷新:
DataFrame join_df = refresh(join_df)
这基本上做的是先前版本的unpersists(删除缓存),读取新版本然后缓存它。因此,在实践中,数据框将被刷新。
您应该注意,只有在第一次使用数据帧后才会将数据帧保留在内存中,因为缓存是惰性的。