java - 源与 PTransform

标签 java google-cloud-dataflow

我是该项目的新手,我正在尝试在 Dataflow 和数据库之间创建连接器。

文档明确指出我应该使用 Source 和 Sink,但我看到很多人直接使用与 PInput 或 PDone 关联的 PTransform。

源/接收器 API 处于实验阶段(它解释了 PTransform 的所有示例),但似乎更容易将其与自定义运行器集成(例如:spark)。

如果我引用代码,则使用了两种方法。我看不到任何使用 PTransform API 会更有趣的用例。

Source/Sink API 是否应该取代 PTranform API?

我是否错过了明确区分这两种方法的内容?

Source/Sink API 是否足够稳定以被认为是编码输入和输出的好方法?

谢谢你的建议!

最佳答案

Dataflow 的理念是 PTransform是抽象和可组合性的主要单位 ,即任何独立的数据处理任务都应该封装为 PTransform .这包括连接到第三方存储系统的任务:从某处摄取数据或将其导出到某处。

以 Google Cloud Datastore 为例。在代码片段中:

    PCollection<Entity> entities =
      p.apply(DatastoreIO.readFrom(dataset, query));
    ...
    p.apply(some processing)
     .apply(DatastoreIO.writeTo(dataset));
DatastoreIO.readFrom(dataset, query)的返回类型是 PTransform<PBegin, PCollection<Entity>> 的子类,以及 DatastoreIO.writeTo(dataset) 的类型是 PTransform<PCollection<Entity>, PDone> 的子类.

确实,这些功能是使用 Source 实现的。和 Sink类,但对于只想读取或写入数据到 Datastore 的用户来说,这是一个通常无关紧要的实现细节(但是,请参阅此答案末尾关于公开 SourceSink 类的注释) .任何连接器,或者就此而言,任何其他数据处理任务都是 PTransform .

注意:当前从某处读取的连接器往往是 PTransform<PBegin, PCollection<T>> ,写入某处的连接器往往是 PTransform<PCollection<T>, PDone> ,但我们正在考虑以更灵活的方式更轻松地使用连接器的选项(例如,从 PCollection 的文件名中读取)。

然而,当然,这个细节对于想要实现新连接器的人来说很重要。特别是,您可能会问:

问:为什么我需要 SourceSink类,如果我可以将我的连接器实现为 PTransform?

答:如果您可以仅使用内置转换(例如 ParDoGroupByKey 等)来实现连接器,那么这是开发连接器的一种非常有效的方式。 然而,SourceSink类提供了一些低级功能,如果您需要它们,您自己开发这些功能会很麻烦或不可能。

例如,BoundedSourceUnboundedSource提供用于控制并行化如何发生的钩子(Hook)(初始和动态工作重新平衡 - BoundedSource.splitIntoBundlesBoundedReader.splitAtFraction ),而这些钩子(Hook)当前未针对任意 DoFn 公开s。

您可以通过编写 DoFn<FilePath, SomeRecord> 在技术上为文件格式实现解析器。它将文件名作为输入,读取文件并发出 SomeRecord ,但是这个 DoFn如果文件在运行时变得非常大,将无法将文件的一部分动态并行读取到多个工作器上。另一方面,FileBasedSource具有内置的此功能,以及处理 glob 文件模式等。

同样,您可以尝试通过实现 DoFn 来实现到流媒体系统的连接器。以虚拟元素作为输入,建立连接并将所有元素流式传输到 ProcessingContext.output() ,但是 DoFn s 目前不支持从单个包中写入无限量的输出,也不明确支持 Dataflow 为流管道提供的强一致性保证所需的检查点和重复数据删除机制。 UnboundedSource ,另一方面,支持这一切。
Sink (更准确地说, Write.to() PTransform )也很有趣:它只是一个复合变换,您可以根据需要自行编写(即它在 Dataflow 运行器或后端中没有硬编码支持),但它开发时考虑到了在将数据并行写入存储系统时出现的典型分布式容错问题,并且它提供了强制您牢记这些问题的钩子(Hook):例如,因为数据包是并行写入的,一些包为了容错,可以重试或复制,有一个钩子(Hook)可以“提交”成功完成的包的结果( WriteOperation.finalize )。

总结一下:使用 SourceSink用于开发连接器的 API 可帮助您以在分布式处理设置中运行良好的方式构建代码,并且源 API 可让您访问框架的高级功能。但是,如果您的连接器是一个非常简单的连接器,两者都不需要,那么您可以自由地从其他内置转换中组装您的连接器。

问:假设我决定使用 SourceSink .那么我如何将我的连接器打包为一个库:我应该只提供 SourceSink类,或者我应该把它包装成一个 PTransform ?

答:您的连接器最终应打包为 PTransform , 这样用户就可以p.apply()它在他们的管道中。但是,在引擎盖下,您的转换可以使用 SourceSink类。

一个常见的模式是暴露 SourceSink类也是如此,利用 Fluent Builder 模式,并让用户将它们包装成 Read.from()Write.to()改造自己,但这不是一个严格的要求。

关于java - 源与 PTransform,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34724889/

相关文章:

python - TensorFlow 数据验证和 BigQuery

google-cloud-dataflow - 使用 Dataflow failed insert WriteResult 处理 table not found 异常

java - 无法从数据流中的 bigtable 读取

java - 了解问题,从编程层模型的角度来看,在 Hibernate 中使用 .save() 和 .commit() 的正确方法是什么

java - RMS 存储持久数据的问题

java - 如何不执行超过预定时间的作业

google-bigquery - 从 Google App Engine 应用程序运行 Google Dataflow 管道?

java - 实时应用程序(服务器/客户端)的设计(类、方法、接口(interface))

java - 是否有任何 java 插件可以为 Oracle、MySQL、PostGreSQL 生成 DDL?

google-cloud-dataflow - 使用 Dataflow 与 Cloud Composer