如何在流传输管道中添加重复数据删除[apache-beam]

时间:2019-07-25 18:45:18

标签: python google-cloud-platform google-cloud-dataflow apache-beam google-cloud-pubsub

我在apache beam [python]中有一个正在工作的流传输管道,该管道从pub / sub提取数据,对数据流进行丰富处理并将其传递给big-query。

对于流媒体窗口,我想确保消息不会重复(因为pub / sub至少保证一次传递)。

因此,我认为我只会使用与Beam不同的方法,但是一旦使用它,我的管道就会中断(无法继续进行,任何本地打印内容也不可见)。

这是我的管道代码:

    with beam.Pipeline(options=options) as p:
        message = (p | "ReadFromPubSub" >> beam.io.ReadFromPubSub(topic=known_args.topic).
                   with_output_types(bytes))

        bq_data = (message | "Decode" >> beam.FlatMap(lambda x: [x.decode('utf-8')])
                           | "Deduplication" >> beam.Distinct()
                           | "JSONLoad" >> beam.ParDo(ReadAsJSON())
                           | "Windowing" >> beam.WindowInto(window.FixedWindows(10, 0))
                           | "KeepRelevantData" >> beam.ParDo(KeepRelevantData())
                           | "PreProcessing" >> beam.ParDo(PreProcessing())
                           | "SendLimitedKeys" >> beam.ParDo(SendLimitedKeys(), schema=schema)
                   )

        if not known_args.local:
            bq_data | "WriteToBigQuery" >> beam.io.WriteToBigQuery(table=known_args.bq_table, schema=schema)
        else:
            bq_data | "Display" >> beam.ParDo(Display())

您会在重复数据删除标签中看到,我正在调用beam.Distinct方法。

问题:

  1. 重复数据删除应该在哪里进行?

  2. 这甚至是正确/理智的方法吗?

  3. 我还能如何删除流缓冲区数据的重复项?

  4. 是否甚至需要重复数据删除,还是我只是在浪费时间?

任何解决方案或建议将不胜感激。谢谢。

1 个答案:

答案 0 :(得分:2)

您可能会发现Exactly-once processing上的此博客很有帮助。首先,Dataflow已经基于发布/订阅记录ID执行重复数据删除。但是,如博客所述:“但是,在某些情况下,这还不够。用户的发布过程可能会重试发布。”

因此,如果将消息发布到Pub / Sub的系统可能多次发布同一条消息,则您可能希望添加自己的确定性记录ID。然后,Cloud Dataflow将检测到这些。这是我建议的方法,而不是尝试在自己的管道中进行重复数据删除。

您可以通过使用PubSubIO.Read上的withIdAttribute来执行此操作。 Example

关于为什么我认为“相异”会导致卡住的一些解释。 Distinct尝试对窗口中的数据进行重复数据删除。我相信您正在尝试对全局窗口进行重复数据删除,因此您的管道必须缓冲并比较所有元素,并且由于这是无界的PCollection。它将尝试永久缓冲。

我认为,如果您先执行窗口化,并且具有确定性的事件时间戳(看起来不像您正在使用withTimestampAttribute),则此方法将正常工作。然后,Distinct将仅应用于窗口内的元素(并且具有相同时间戳的相同元素将放置在同一窗口中)。您可能想看看这是否适用于原型,但我建议尽可能添加唯一的记录ID,并允许Dataflow根据记录ID处理重复,以实现最佳性能。