syncExec()
or asyncExec()
包含以下规则:
3.2.2。不变性
PCollection是不可变的。创建后,您无法添加,删除或 改变个别元素。 Beam Transform可以处理每个 PCollection的元素并生成新的管道数据(作为新的 PCollection),但它不消耗或修改原始输入 集合。
这是否意味着我不能,不能或不应该修改自定义转换中的单个元素?
具体来说,我正在使用python SDK并考虑将dict {key: "data"}
作为输入的转换的情况,进行一些处理并添加更多字段{other_key: "some more data"}
。
我对上述规则3.2.2的解释是,我应该像
def process(self,element):
import copy
output = copy.deepcopy(element)
output[other_key] = some_data
yield output
但我想知道这是否有点矫枉过正。
使用TestPipeline,我发现如果我在process()
方法中对它们进行操作,也会修改输入集合的元素(除非元素是基本类型,如int,float,bool ......)
变异元素被认为是绝对禁止的,或者只是练习者必须小心吗?
答案 0 :(得分:4)
变异元素是绝对禁止的,它可以并且将导致违反Beam模型语义,即不正确和不可预测的结果。 Beam Java direct runner有意识地检测到突变并且管道失败 - 这在Python运行器中尚未实现,但它应该是。
原因主要是融合。例如。想象两个DoFn被应用于相同的PCollection“C”(f(C)和g(C) - 而不是f(g(C))),并且跑步者将它们安排在相同的碎片中运行。想象一下,第一个DoFn修改元素,然后到第二个DoFn运行时,元素已被更改 - 即第二个DoFn实际上并未应用于“C”。在许多其他情况下,突变会导致错误的结果。