Apache spark 执行器失败后,Spark无法在HDFS中找到检查点数据
我将卡夫卡的数据整理如下:Apache spark 执行器失败后,Spark无法在HDFS中找到检查点数据,apache-spark,spark-streaming,spark-checkpoint,Apache Spark,Spark Streaming,Spark Checkpoint,我将卡夫卡的数据整理如下: final JavaPairDStream<String, Row> transformedMessages = rtStream .mapToPair(record -> new Tuple2<String, GenericDataModel>(record.key(), record.value())) .ma
final JavaPairDStream<String, Row> transformedMessages =
rtStream
.mapToPair(record -> new Tuple2<String, GenericDataModel>(record.key(), record.value()))
.mapWithState(StateSpec.function(updateDataFunc).numPartitions(32)).stateSnapshots()
.foreachRDD(rdd -> {
--logic goes here
});
进一步更新:
我发现Spark试图在HDFS中找到的RDD已经被“ReliableRDDCheckpointData”进程删除,它为检查点数据创建了一个新的RDD。
达格莫名其妙地指向这个旧RDD。如果对该数据有任何引用,则不应将其删除。考虑火花流上的转换管道:
rtStream
.mapToPair(record -> new Tuple2<String, GenericDataModel>(record.key(), record.value()))
.mapWithState(StateSpec.function(updateDataFunc).numPartitions(32)).stateSnapshots()
.foreachRDD(rdd -> {
if(counter ==1){
--convert RDD to Dataset, and register it as a SQL table names "InitialDataTable"
} else
--convert RDD to Dataset, and register it as a SQL table names "ActualDataTable"
});
rtStream
.mapToPair(record->new Tuple2(record.key(),record.value())
.mapWithState(StateSpec.function(updateDataFunc).numPartitions(32)).stateSnapshots()
.foreachRDD(rdd->{
如果(计数器==1){
--将RDD转换为Dataset,并将其注册为SQL表名称“InitialDataTable”
}否则
--将RDD转换为数据集,并将其注册为SQL表名称“ActualDataTable”
});
mapWithState与每个批处理后状态数据的自动检查点相关联,因此上述“forEachRdd”块中的每个“rdd”都是检查点,在检查点时,它会覆盖上一个检查点(因为最新状态显然需要保留在检查点中)
但是假设用户仍然使用rdd编号1,就像我的情况一样,我将第一个rdd注册为一个不同的表,并且每隔一个rdd注册为一个不同的表,那么它不应该被覆盖。(在java中也是如此,如果某个对象引用某个对象,则该对象将不符合垃圾收集的条件)
现在,当我尝试访问表“InitialDataTable”时,显然用于创建此表的“rdd”不再存在于内存中,因此它将转到HDFS以从检查点恢复,并且它也不会在那里找到它,因为它被下一个rdd覆盖,spark应用程序停止引用原因
“org.apache.spark.sparkeexception:作业因阶段失败而中止:任务创建失败:java.io.FileNotFoundException:文件不存在:hdfs://mycluster/user/user1/sparkCheckpointData/2db59817-d954-41a7-9b9d-4ec874bc86de/rdd-1005/part-00000"
所以为了解决这个问题,我必须明确地检查第一个rdd
rtStream
.mapToPair(record -> new Tuple2<String, GenericDataModel>(record.key(), record.value()))
.mapWithState(StateSpec.function(updateDataFunc).numPartitions(32)).stateSnapshots()
.foreachRDD(rdd -> {
if(counter ==1){
--convert RDD to Dataset, and register it as a SQL table names "InitialDataTable"
} else
--convert RDD to Dataset, and register it as a SQL table names "ActualDataTable"
});