DoFn.Setup 和 DoFn.StartBundle 有什么区别?

What is the difference between DoFn.Setup and DoFn.StartBundle?

这两个注解有什么区别?

DoFn.Setup 用于为处理元素束准备实例的方法的注释。

使用单词 "bundle",参数为零。

DoFn.StartBundle 用于为处理一批元素准备实例的方法的注释。

使用单词 "batch",采用零个 或一个 个参数(StartBundleContext,一种访问 PipelineOptions 的方式)。

我想做什么

我需要在 DoFn 实例中初始化一个库,然后为 "batch" 或 "bundle" 中的每个元素使用该库。我通常不会用这两个词来分裂头发,但是在管道中,可能会有一些区别?

一个DoFn的生命周期如下:

  • Setup
  • 重复处理包:
    • StartBundle
    • 重复ProcessElement
    • FinishBundle
  • Teardown

即DoFn 的一个实例可以处理许多(零个或多个)包,并且在一个包内,它处理许多(零个或多个)元素。

Setup/TeardownStartBundle/FinishBundle 都是可选的 - 可以在不使用它们的情况下实现任何 DoFn,并且这样做仅在 ProcessElement 中工作,但效率很低。两种方法都允许优化:

  • 人们通常希望在元素之间进行批处理,例如不是对每个元素执行 RPC,而是对 N 个元素的批次执行 RPC。 StartBundle/FinishBundle 告诉您批处理的允许边界是什么:基本上,您不允许跨 FinishBundle 进行批处理 - FinishBundle 必须强制刷新您的批处理(并且StartBundle 必须初始化/重置批处理)。这是我所知道的这些方法的唯一常见用法,但如果您对更一般或更严格的解释感兴趣 - 包是容错的单位,并且运行器假设到 FinishBundle returns,您已经完成了与该包中所有元素相关的所有工作(输出元素或执行副作用);作品不得 "leak" 捆绑。
  • 人们通常想要管理长期存在的资源,例如网络连接。您可以在 StartBundle/FinishBundle 中执行此操作,但是,与未决的副作用或输出不同,此类资源可以在包之间持续存在。这就是 SetupTeardown 的目的。
  • 人们通常还想对 DoFn 执行昂贵的初始化,例如解析配置文件等。这也最好在 Setup.
  • 中完成

更简洁:

  • Setup/Teardown 中管理资源和昂贵的初始化。
  • 管理 StartBundle/FinishBundle 中的工作批处理。

(在捆绑方法中管理资源效率低下;在 setup/teardown 中管理批处理显然不正确,会导致数据丢失)

DoFn 文档 recently updated 使这一点更清楚。