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

Jac*_*ble 8 java apache-beam

这两个注释有什么区别?

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

使用单词"bundle",取零参数.

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

使用"批处理"一词,取零个或一个参数(StartBundleContext一种访问方式PipelineOptions).

我想做什么

我需要在DoFn实例中初始化一个库,然后将该库用于"批处理"或"包"中的每个元素.我通常不会用这两个词分开头发,但在管道中,可能会有一些区别?

jkf*_*kff 22

a的生命周期DoFn如下:

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

即,一个DoFn实例可以处理许多(零个或多个)束,并且在一个束中,它处理许多(零个或多个)元素.

无论Setup/ TeardownStartBundle/ FinishBundle是可选的-这是可以实现的任何DoFn不使用他们,只有在做的工作ProcessElement,但是这将是低效的.两种方法都允许优化:

  • 通常,人们想要在元素之间进行批处理,例如,不是为每个元素执行RPC,而是对N个元素的批处理执行RPC.StartBundle/ FinishBundle告诉你批处理的允许边界是什么:基本上,你不允许批处理FinishBundle- FinishBundle必须强制批量清理(并且StartBundle必须初始化/重置批处理).这是我所知道的这些方法的唯一常见用法,但是如果你对更一般或更严格的解释感兴趣 - 捆绑是一个容错的单位,并且跑者认为到时候FinishBundle回归,你已完全执行与此捆绑包中所有元素相关的所有工作(输出元素或执行副作用); 工作不得在捆绑之间"泄漏".
  • 通常人们想要管理长期存在的资源,例如网络连接.您可以在StartBundle/中执行此操作FinishBundle,但是,与待处理的副作用或输出不同,此类资源可以在bundle之间保留.这就是SetupTeardown是.
  • 通常也有人想要执行昂贵的初始化DoFn,例如解析配置文件等.这也是最好的Setup.

更简洁:

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

(管理bundle方法中的资源效率很低;在setup/teardown中管理批处理是明显不正确的,会导致数据丢失)

最近更新了DoFn文档以使其更加清晰.

  • 仅当您在构造管道的主程序中自己调用构造函数时,才会调用构造函数。从那时起,DoFn 被序列化,然后在每个工作线程上反序列化;反序列化不会调用构造函数,它使用低级 JVM 机制来创建类的空实例并恢复字段值。但 Beam 将在使用每个反序列化实例之前调用它。 (3认同)
  • 这是非常不同的:如果你在构造函数中做一些事情,它会在构造管道的程序中运行一次,在 DoFn 被序列化并传送给工作人员之前(这意味着你不能在构造函数中打开连接 - 一个连接无法序列化并发送给工作人员)。如果您在 Setup 中执行此操作,它将在 worker 上为每个 DoFn 实例运行一次 - 在 worker 上*不*调用构造函数。 (2认同)