我在Spark中有一个StreamingQuery(v2.2.0),即
val df = spark
.readStream
.format("kafka")
.option("kafka.bootstrap.servers", "localhost:9092")
.option("subscribe", "test")
.load()
val query = df
.selectExpr("CAST(key AS STRING)", "CAST(value AS STRING)")
.writeStream
.format("parquet")
.option("checkpointLocation", "s3n://bucket/checkpoint/test")
.option("path", "s3n://bucket/test")
.start()
当我运行query
时,数据会在AWS S3上保存,并在s3n://bucket/checkpoint/test
创建检查点。但是,我还在日志中收到以下警告:
WARN [o.a.s.s.e.streaming.OffsetSeqLog]无法使用FileContext API在路径s3n:// bucket / checpoint / test / offsets管理元数据日志文件。使用FileSystem API代替管理日志文件。失败时日志可能不一致。
我无法理解为什么会出现警告。另外,如果发生任何故障,我的检查点会不一致吗?
有人可以帮我解决吗?
答案 0 :(得分:5)
查看源代码,此错误来自HDFSMetadataLog类。代码中的注释声明:
注意:[[HDFSMetadataLog]]不支持类似S3的文件系统,因为它们不保证目录中的列表文件始终显示最新文件。
所以问题是由于使用AWS S3而导致您使用FileSystemManager
API。检查该课程的评论,我们看到了,
使用旧版FileSystem API实现FileManager。请注意,此实现无法提供路径的原子重命名,因此可能导致一致性问题。当不能使用FileContextManager时,这应仅用作备份选项。
因此,当多个编写者想要同时进行重命名操作时,可能会出现一些问题。有一个相关的票证here,但由于该问题无法在Spark中修复,因此已关闭。
如果需要在S3上检查点,需要考虑的一些事项:
答案 1 :(得分:1)
确实需要以不同的方式完成对象存储的检查点。如果你仔细观察,就没有rename()
,但是现有的代码太多了,所以希望它是一个O(1)原子操作。