我正在研究使用Google Cloud中的DataFlow的两个管道的场景:
Pipeline A 以流媒体模式运行,基于每小时窗口和一些像这样的分片在Google-Storage中不断创建文件:
data.apply(TextIO.write().to(resource.getCurrentDirectory())
.withFilenamePolicy(new PerWindowFiles(prefix))
.withWindowedWrites()
.withNumShards(42));
管道 B 以批处理模式工作,定期加载这些文件以进行进一步处理,例如:每小时。
问题是:管道 B 哪些文件可以从GS中加载?
所有这些 - >可能不是一个好主意,如果 A 没有完成写一些,我们会得到损坏的文件。
基于时间(例如仅加载至少2小时的文件) - >如果 A 迟到
在 A 中创建“完成”标志的一些方法,告诉 B 完成了哪些文件。
以某种方式在窗口的最终窗格完成处理时得到通知 - >没有办法做到这一点。
我想要第三种方法,但找不到一种方法来确定TextIO何时实际完成编写文件而不等待管道完成。
TextIO的作者不会返回另一个PCollection。一种方法是覆盖在TextIO内部创建的FileBasedSink.WriteOperation的finalize
方法,并且需要复制整个类并最终构建自定义接收器。在我看来这太过分了。
任何人都有更简单的解决方案或体验如何实现这一目标的想法?
答案 0 :(得分:3)
TextIO.write()将数据写入临时文件,然后以原子方式将每个成功写入的临时文件重命名为其最终位置。您可以安全地使用与"前缀匹配的文件"在管道B中,因为临时文件的命名方式与前缀不匹配(我们在决定如何命名临时文件时明确说明了您的用例),因此管道B看到的所有文件都将完整。
或者,我们重新about to add (link to pull request)一个TextIO.read()版本,它以流模式连续摄取新文件;准备就绪后,您可以在管道B中使用它。另请参阅http://s.apache.org/textio-sdf和链接的JIRA。