【问题标题】:Side output in ParDo | Apache Beam Python SDKParDo 中的侧输出 | Apache Beam Python SDK
【发布时间】:2018-09-14 20:09:05
【问题描述】:

由于文档仅适用于 JAVA,我无法真正理解它的含义。

它声明 - “虽然 ParDo 总是产生一个主输出 PCollection(作为 apply 的返回值),但您也可以让 ParDo 产生任意数量的附加输出 PCollection。如果您选择有多个输出,您的ParDo 将返回捆绑在一起的所有输出 PCollection(包括主输出)。例如,在 Java 中,输出 PCollection 捆绑在类型安全的 PCollectionTuple 中。"

我了解捆绑在一起的含义,但是如果我在我的 DoFn 中生成一个标签,它是否会在所有其他输出为空的情况下生成一个捆绑包,并在代码中遇到它们时生成其他输出?还是等待所有收益都准备好输入,然后将它们一起输出?

在文档中没有很清楚的说明。虽然我认为它不会等待,遇到时只会屈服,但我仍然需要了解发生了什么。

【问题讨论】:

    标签: google-cloud-dataflow apache-beam


    【解决方案1】:

    回答这个问题的最佳方法是举个例子。这个例子是available in Beam

    假设您要运行字数统计管道(例如,计算每个单词在文档中出现的次数)。为此,您需要将文件中的行拆分为单个单词。考虑到您还想单独计算字长。你的分裂变换是这样的:

    with beam.Pipeline(options=pipeline_options) as p:
    
        lines = p | ReadFromText(known_args.input)  # Read in the file
    
        # with_outputs allows accessing the explicitly tagged outputs of a DoFn.
        split_lines_result = (lines
                              | beam.ParDo(SplitLinesToWordsFn()).with_outputs(
                                  SplitLinesToWordsFn.OUTPUT_TAG_CHARACTER_COUNT,
                                  main='words'))
    
        short_words = split_lines_result['words']
        character_count = split_lines_result[
            SplitLinesToWordsFn.OUTPUT_TAG_CHARACTER_COUNT]
    

    在这种情况下,每个都是不同的PCollection,具有正确的元素。 DoFn 将负责拆分其输出,并通过标记元素来实现。见:

    class SplitLinesToWordsFn(beam.DoFn):
      OUTPUT_TAG_CHARACTER_COUNT = 'tag_character_count'
    
      def process(self, element):
        # yield a count (integer) to the OUTPUT_TAG_CHARACTER_COUNT tagged
        # collection.
        yield pvalue.TaggedOutput(
            self.OUTPUT_TAG_CHARACTER_COUNT, len(element))
    
        words = re.findall(r'[A-Za-z\']+', element)
        for word in words:
          # yield word to add it to the main collection.
          yield word
    

    如您所见,对于主输出,您不需要标记元素,但对于其他输出则需要标记。

    【讨论】:

    • 嗯,我明白了。也许我没有问正确的问题,我想知道的是,以您提供的示例为例。主产出和副产出产出是否同时发生。我的意思是在为 pcollection 的一个元素调用 DoFn 之后,是否所有的 yield 都等待彼此准备好并将返回值捆绑在一起。我知道这可能听起来很傻,但文档以一种非常奇怪的方式解释了它。
    • 我明白了。每个产量都应该独立传播。如果您返回一个可迭代对象(如列表),那么在任何元素顺流而下之前,当然需要先完全创建该可迭代对象;但是如果你是一个一个地让出元素,那么每个元素都应该在一个阶段自己走下去。您是否有让您感到困惑的特定用例?
    • 嗯,不是真的,我只是担心看文档。不过,我理解捆绑的部分,这意味着在访问它时是捆绑的,我只是想请人确定一下。非常感谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-13
    • 2019-10-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多