我有一个长期运行的结构化流媒体作业,该作业消耗多个Kafka主题并在一个滑动窗口上进行汇总。我需要了解如何在HDFS中管理/清理检查点。
作业运行正常,我可以从失败的步骤中恢复,而不会丢失数据,但是,我可以看到HDFS利用率日益提高。我找不到有关Spark如何管理/清理检查点的任何文档。以前,检查点存储在s3上,但是事实证明这很昂贵,因为要读取/写入大量小文件。
query = formatted_stream.writeStream \
.format("kafka") \
.outputMode(output_mode) \
.option("kafka.bootstrap.servers", bootstrap_servers) \
.option("checkpointLocation", "hdfs:///path_to_checkpoints") \
.start()
据我了解,检查点应该自动清理;几天后,我只是看到HDFS利用率线性增加。如何确保检查点受到管理且HDFS不会用完空间?
对Spark Structured Streaming Checkpoint Cleanup的公认答案表明,结构化流应该处理此问题,而不是如何或如何进行配置。
答案 0 :(得分:2)
正如您在the code for Checkpoint.scala中所看到的那样,检查点机制保留了最后10个检查点数据,但这几天不会出现问题。
通常的原因是,要保留在磁盘上的RDD也会随着时间线性增长。这可能是由于您不关心某些RDD会持续存在。
您需要确保使用结构化流时不会保留需要增长的RDD。例如,如果要计算数据集一列中不同元素的精确计数,则需要知道完整的输入数据(这意味着持久存储的数据会随着时间线性增加,如果每批数据不断涌入)。相反,如果您可以使用近似计数,则可以使用HyperLogLog ++之类的算法,通常需要更少的内存来权衡精度。
请记住,如果您使用的是Spark SQL,则可能需要进一步检查优化查询的内容,因为这可能与Catalyst如何优化查询有关。如果您不是,那么Catalyst可能会为您优化查询。
无论如何,还需要进一步思考:如果检查点的使用随着时间的增加而增加,这应该反映在您的流作业中,并且随着时间线性地消耗更多的RAM,因为检查点只是Spark上下文的序列化(加上常量) -size元数据)。如果是这种情况,请检查SO以获取相关问题,例如why does memory usage of Spark Worker increase with time?。
此外,请注意在哪个RDD上调用.persist()
(以及哪个缓存级别,以便您可以将元数据存储到磁盘RDD并将其一次仅部分加载到Spark上下文中。)