如何删除Spark结构化流(Spark 2.4.5)创建的旧数据?
我有实木复合地板/ avro格式(非增量)上的HDFS数据,它是由 Spark Structured Streaming 创建的,并按时间(年份的年,月,日)进行了分区月,小时)。
数据创建如下:
cdo -setattribute,Band1@_FillValue=-1.0 infile.nc outfile.nc
结果,我的分区文件夹布局如下:
query = df.writeStream.format("avro").partitionBy("year", "month", "day", "hour").outputMode("append").option("checkpointLocation", "/data/avro.cp").start("/data/avro")
如何删除旧数据,例如早于year = 2020,month = 2,day = 13,hour = 14的旧数据?
只需删除相关文件夹
./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
从文件系统读取批处理数据帧时引发异常:
./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
文件夹有关。
感谢您的帮助。
答案 0 :(得分:3)
似乎我找到了解决方案/解决方法。
关键概念是使用FileStreamSinkLog,然后将SinkFileStatus加上其操作设置为delete
:
加载FileStreamSinkLog
sinkLog = new FileStreamSinkLog(1, spark, full-path-to-spark-metadata-dir);
获取最新的SinkFileStatus
Option<Tuple2<Object, SinkFileStatus[]>> latest = sinkLog.getLatest();
long batchId = (long)latest.get()._1;
SinkFileStatus[] fileStatuses = latest.get()._2;
删除旧文件
通过delete
动作向fileStatuses
数组添加新条目
使用更新后的batchId
fileStatuses
日志文件
答案 1 :(得分:1)
您不能删除该文件夹,除非您也删除了它对应的检查点文件夹。您试图在检查点仍然了解该文件夹的同时删除该文件夹,因此这就是发生错误的原因。
但是,除非有必要,否则我真的不建议您将检查点文件夹弄乱。如果您有可能,我建议您将旧数据移至其他数据存储类型,例如AWS Standard-> Glacier。
答案 2 :(得分:0)
为了便于复制/粘贴,这里有一个从 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))
)
答案 3 :(得分:0)
对于 Spark 3.0.0 及以上版本,已实现。
基本上它为已提交的文件添加了 3 个策略(ARCHIVE、DELETE、OFF)并允许对其进行配置。
老实说,我自己从未尝试过,但我在这里看到了一些关于 Spark 3+ 的答案,绝对值得一提。