Apache spark 如何删除Spark结构化流媒体创建的旧数据?

Apache spark 如何删除Spark结构化流媒体创建的旧数据?,apache-spark,apache-spark-sql,spark-structured-streaming,apache-spark-2.0,Apache Spark,Apache Spark Sql,Spark Structured Streaming,Apache Spark 2.0,如何删除Spark结构化流媒体Spark 2.4.5创建的旧数据 我有拼花/avro格式的HDF数据,而不是Delta,它是由Spark结构化流媒体创建的,并按时间年、月、月日、小时进行分区 数据创建如下所示: query = df.writeStream.format("avro").partitionBy("year", "month", "day", "hour").outputMode("append").option("checkpointLocation", "/data/avro.

如何删除Spark结构化流媒体Spark 2.4.5创建的旧数据

我有拼花/avro格式的HDF数据,而不是Delta,它是由Spark结构化流媒体创建的,并按时间年、月、月日、小时进行分区

数据创建如下所示:

query = df.writeStream.format("avro").partitionBy("year", "month", "day", "hour").outputMode("append").option("checkpointLocation", "/data/avro.cp").start("/data/avro")
因此,我有以下分区文件夹布局:

./year=2020/month=3/day=13/hour=12
./year=2020/month=3/day=13/hour=13
./year=2020/month=3/day=13/hour=14
./year=2020/month=3/day=13/hour=15
./year=2020/month=3/day=13/hour=16
如何删除旧数据,例如,早于2020年、2月、13日、14小时的数据

只是删除相关文件夹

./year=2020/month=3/day=13/hour=12
./year=2020/month=3/day=13/hour=13
从文件系统读取批处理数据帧时引发异常:

df = spark.read.format("avro").load("/data/avro")
java.io.FileNotFoundException: File file:/data/avro/year=2020/month=3/day=13/hour=12/part-00000-0cc84e65-3f49-4686-85e3-1ecf48952794.c000.avro does not exist
我发现它与检查点使用的_spark_元数据文件夹有某种关联


感谢您的帮助。

除非您也删除了相应的检查点文件夹,否则无法删除该文件夹。您正在尝试删除该文件夹,而检查点仍知道该文件夹,因此发生错误


然而,除非必要,否则我真的不建议弄乱checkpoint文件夹。如果您的情况允许,我建议您将旧数据移动到不同的数据存储类型,例如AWS Standard->Glacier。

除非您也删除了相应的检查点文件夹,否则无法删除该文件夹。您正在尝试删除该文件夹,而检查点仍知道该文件夹,因此发生错误


然而,除非必要,否则我真的不建议弄乱checkpoint文件夹。如果您的情况允许,我建议您将旧数据移动到不同的数据存储类型,如AWS Standard->Glacier。

似乎我找到了解决方案/解决方法。 关键概念是使用FileStreamSinkLog并将其与SinkFileStatus一起使用,操作集为delete:

加载FileStreamSinkLog

 sinkLog = new FileStreamSinkLog(1, spark, full-path-to-spark-metadata-dir);
获取最新的文件状态

 Option<Tuple2<Object, SinkFileStatus[]>> latest = sinkLog.getLatest();
 long batchId = (long)latest.get()._1;
 SinkFileStatus[] fileStatuses = latest.get()._2;
删除旧文件

向fileStatuses数组添加带有删除操作的新条目

使用更新的文件状态写回batchId日志文件

但是,这需要停止结构化流式处理作业。
因此,要删除Spark Structured Streaming编写的旧文件而不停止它,没有解决方案。

看来我找到了解决方案/解决办法。 关键概念是使用FileStreamSinkLog并将其与SinkFileStatus一起使用,操作集为delete:

加载FileStreamSinkLog

 sinkLog = new FileStreamSinkLog(1, spark, full-path-to-spark-metadata-dir);
获取最新的文件状态

 Option<Tuple2<Object, SinkFileStatus[]>> latest = sinkLog.getLatest();
 long batchId = (long)latest.get()._1;
 SinkFileStatus[] fileStatuses = latest.get()._2;
删除旧文件

向fileStatuses数组添加带有删除操作的新条目

使用更新的文件状态写回batchId日志文件

但是,这需要停止结构化流式处理作业。
因此,要删除Spark Structured Streaming编写的旧文件而不停止它,没有任何解决方案。

为了便于复制/粘贴,以下是Spark 3.0.1版本的scala代码片段。删除一个文件并写入新批:

import org.apache.spark.sql.execution.streaming.FileStreamSinkLog

import scala.language.postfixOps
import scala.sys.process._
import scala.util.Try

        val sinkLog = new FileStreamSinkLog (
            1,
            spark,
            SPARK_METADATA_ROOT
        )
        val head = sinkLog.allFiles().head

        val deleteCommand = s"hadoop fs -rm ${head.path}"
        println (Try (deleteCommand ! processlogger).getOrElse(s""""$deleteCommand" failed""") )

        head.copy(action = FileStreamSinkLog.DELETE_ACTION)

        sinkLog
            .add (
                latestBatch.get._1+1,
                Array(head.copy(action = FileStreamSinkLog.DELETE_ACTION))
                )

为了便于复制/粘贴,下面是spark 3.0.1版本的scala代码片段。删除一个文件并写入新批:

import org.apache.spark.sql.execution.streaming.FileStreamSinkLog

import scala.language.postfixOps
import scala.sys.process._
import scala.util.Try

        val sinkLog = new FileStreamSinkLog (
            1,
            spark,
            SPARK_METADATA_ROOT
        )
        val head = sinkLog.allFiles().head

        val deleteCommand = s"hadoop fs -rm ${head.path}"
        println (Try (deleteCommand ! processlogger).getOrElse(s""""$deleteCommand" failed""") )

        head.copy(action = FileStreamSinkLog.DELETE_ACTION)

        sinkLog
            .add (
                latestBatch.get._1+1,
                Array(head.copy(action = FileStreamSinkLog.DELETE_ACTION))
                )

那么如何删除旧数据呢?从长远来看,结构化流媒体应用程序会创建大量数据,在某些情况下,非常旧的数据不再相关,它只使用HDFS磁盘空间。@YuriiOleynikov看这里:谢谢@Zack,但真的很奇怪,没有解决方案可以清除24/7运行Spark SS应用程序的旧数据。那么如何删除旧数据呢?从长远来看,结构化流媒体应用程序会创建大量数据,在某些情况下,非常旧的数据不再相关,它只使用HDFS磁盘空间。@YuriiOleynikov看这里:谢谢@Zack,但真的很奇怪,没有解决方案可以清除24/7运行Spark SS应用程序的旧数据。是的,但据我所知,这要求停止结构化流媒体是的,但据我所知,这要求停止结构化流媒体