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"


                    });