Java DoFn.Setup和DoFn.StartBundle之间有什么区别? 这两种注释之间的区别是什么?
用于准备用于处理元素束的实例的方法的注释 使用单词“bundle”,接受零个参数 用于准备实例以处理一批元素的方法的注释 使用单词“batch”,接受零个或一个参数(,一种访问Java DoFn.Setup和DoFn.StartBundle之间有什么区别? 这两种注释之间的区别是什么?,java,apache-beam,Java,Apache Beam,用于准备用于处理元素束的实例的方法的注释 使用单词“bundle”,接受零个参数 用于准备实例以处理一批元素的方法的注释 使用单词“batch”,接受零个或一个参数(,一种访问PipelineOptions)的方法) 我想做什么 我需要在DoFn实例中初始化一个库,然后对“batch”或“bundle”中的每个元素使用该库。我通常不会用这两个词来吹毛求疵,但在管道中,可能会有一些不同?DoFn的生命周期如下所示: 设置 重复处理捆绑包: StartBundle 重复ProcessElemen
PipelineOptions
)的方法)
我想做什么
我需要在DoFn实例中初始化一个库,然后对“batch”或“bundle”中的每个元素使用该库。我通常不会用这两个词来吹毛求疵,但在管道中,可能会有一些不同?DoFn的生命周期如下所示:
设置
- 重复处理捆绑包:
StartBundle
- 重复
ProcessElement
FinishBundle
拆卸
Setup
/Teardown
和StartBundle
/FinishBundle
都是可选的-可以在不使用它们的情况下实现任何DoFn
,并且只在ProcessElement
中执行工作,但是效率低下。这两种方法都允许优化:
- 通常需要在元素之间批处理工作,例如,不是对每个元素执行RPC,而是对N个元素的批处理执行RPC
/StartBundle
告诉您批处理的允许边界:基本上,您不允许跨FinishBundle
-FinishBundle
批处理,必须强制刷新批处理(并且FinishBundle
必须初始化/重置批处理)。这是我所知道的这些方法的唯一常见用法,但如果您对更一般或更严格的解释感兴趣,那么捆绑包是容错的一个单元,并且运行程序假定当StartBundle
返回时,您已经完成了所有工作(输出元素或执行副作用)与此束中看到的所有元素关联;捆包之间的作业不得“泄漏”FinishBundle
- 通常需要管理长期存在的资源,例如网络连接。您可以在
/StartBundle
中执行此操作,但是,与挂起的副作用或输出不同,这些资源可以在bundle之间保留。这就是FinishBundle
和设置
的目的拆卸
- 通常还需要执行成本高昂的
DoFn初始化,例如解析配置文件等。这最好在
设置中完成
- 在
/设置
中管理资源和昂贵的初始化拆卸
- 管理
/StartBundle
中的工作批处理FinishBundle
DoFn文档旨在使这一点更加清楚。感谢您提供详细的答案!在安装方法中执行的操作与在构造函数中执行的操作不同,还是只是惯例问题?这是非常不同的:如果在构造函数中执行某项操作,它将在构建管道的程序中运行一次,然后将DoFn序列化并发送给工作人员(这意味着,例如,您无法在构造函数中打开连接-无法序列化连接并将其发送给工作进程)。如果您在安装程序中执行此操作,它将在工作程序上的每个DoFn实例上运行一次-此构造函数不会在工作程序上调用。基本上,仅在将配置传递给DoFn时使用此构造函数-例如,将构造函数参数分配给成员变量。使用安装程序进行其他操作。@jkff您可以分享一些如何使用安装程序的示例吗/Dataflow中的Teardown?构造函数只有在构造管道的主程序中自己调用时才会被调用。从那时起,DoFn被序列化,然后在每个辅助程序上反序列化;反序列化不会调用构造函数,它使用低级JVM机制创建类的空实例并还原字段值s、 但Beam将在使用每个反序列化实例之前调用其上的安装程序。