繁体   English   中英

Apache Beam 管道写入多个 BQ 表

[英]Apache Beam Pipeline Write to Multiple BQ tables

我有一个需要执行以下操作的场景:

  1. 从 pubsub 读取数据
  2. 对数据应用多个转换。
  3. 基于某些配置将 PCollection 保存在多个 Google Big Query 中。

我的问题是如何将数据写入多个大查询表。

我使用 apache beam 搜索了多个 bq 写入,但找不到任何解决方案

您可以使用 3 个接收器来做到这一点,例如使用Beam Python

def map1(self, element):
    ...

def map2(self, element):
    ...

def map3(self, element):
    ...

def main() -> None:
    logging.getLogger().setLevel(logging.INFO)

    your_options = PipelineOptions().view_as(YourOptions)
    pipeline_options = PipelineOptions()

    with beam.Pipeline(options=pipeline_options) as p:

        result_pcollection = (
          p 
          | 'Read from pub sub' >> ReadFromPubSub(subscription='input_subscription') 
          | 'Map 1' >> beam.Map(map1)
          | 'Map 2' >> beam.Map(map2)
          | 'Map 3' >> beam.Map(map3)
        )

        (result_pcollection |
         'Write to BQ table 1' >> beam.io.WriteToBigQuery(
                    project='project_id',
                    dataset='dataset',
                    table='table1',
                    method='STREAMING_INSERTS',
                    write_disposition=beam.io.BigQueryDisposition.WRITE_APPEND,
                    create_disposition=beam.io.BigQueryDisposition.CREATE_NEVER))

        (result_pcollection |
         'Write to BQ table 2' >> beam.io.WriteToBigQuery(
                    project='project_id',
                    dataset='dataset',
                    table='table2',
                    method='STREAMING_INSERTS',
                    write_disposition=beam.io.BigQueryDisposition.WRITE_APPEND,
                    create_disposition=beam.io.BigQueryDisposition.CREATE_NEVER))

        (result_pcollection_pub_sub |
         'Write to BQ table 3' >> beam.io.WriteToBigQuery(
                    project='project_id',
                    dataset='dataset',
                    table='table3',
                    method='STREAMING_INSERTS',
                    write_disposition=beam.io.BigQueryDisposition.WRITE_APPEND,
                    create_disposition=beam.io.BigQueryDisposition.CREATE_NEVER))


if __name__ == "__main__":
    main()
  • 第一个PCollection是来自PubSub的输入结果。
  • 我在输入PCollection中应用了 3 个转换
  • 将结果汇入 3 个不同的Bigquery
res = Flow 
=> Map 1
=> Map 2
=> Map 3

res => Sink result to BQ table 1 with `BigqueryIO`
res => Sink result to BQ table 2 with `BigqueryIO`
res => Sink result to BQ table 3 with `BigqueryIO`

在此示例中,我使用STREAMING_INSERT提取到Bigquery表,但您可以根据需要调整和更改它。

我看到以前的答案满足您将相同结果写入多个表的要求。 但是,我假设以下情况,提供了一些不同的管道。

  • 从 PubSub 读取数据
  • 根据配置过滤数据(来自事件消息键)
  • 将不同/相同的转换应用于过滤后的 collections
  • 将之前 collections 的结果写入不同的 BigQuery 接收器

在这里,我们过滤了管道早期阶段的事件,这有助于:

  • 避免多次处理相同的事件消息。
  • 您可以跳过不需要的消息。
  • 将相关转换应用于事件消息。
  • 整体高效且具有成本效益的系统。

例如,您正在处理来自世界各地的消息,您需要处理和存储与地理相关的数据——将欧洲消息存储在欧洲地区。

此外,您需要应用与国家特定数据相关的转换——将 Aadhar 号码添加到从印度生成的消息中,将社会安全号码添加到从美国生成的消息中。

而且您不想处理/存储来自特定国家/地区的任何事件 - 来自海洋国家/地区的数据无关紧要,不需要在我们的用例中处理/存储。

因此,在这个虚构的示例中,在早期过滤数据(基于配置),您将能够存储特定于国家/地区的数据(多个接收器),并且您不必处理从生成的所有事件美国/任何其他地区添加 Aadhar 编号(事件特定转换),您将能够跳过/删除记录或简单地将它们存储在 BigQuery 中而不应用任何转换。

如果上面的虚构示例与您的场景相似,示例管道设计可能如下所示

import apache_beam as beam
from apache_beam.options.pipeline_options import PipelineOptions,...
from apache_beam.io.gcp.internal.clients import bigquery

class TaggedData(beam.DoFn):
    def process(self, element):
        try:
            # filter here
            if(element["country"] == "in")
                yield {"indiaelements:taggedasindia"}
            if(element["country"] == "usa")
                yield  {"usaelements:taggedasusa"}
        
            ...
        except:
            yield {"taggedasunprocessed"}

def addAadhar(element):
    "Filtered messages - only India"
    yield "elementwithAadhar"

def addSSN(element):
    "Filtered messages - only USA"
    yield "elementwithSSN"

p = beam.Pipeline(options=options)
    
messages =  (
    p
    | "ReadFromPubSub" >> ...
    | "Tagging >> "beam.ParDo(TaggedData()).with_outputs('usa', 'india', 'oceania', ...) 
    )

india_messages = (
    messages.india 
    | "AddAdhar" >> ...
    | "WriteIndiamsgToBQ" >> streaming inserts
    )

usa_messages = (
    messages.usa
    | "AddSSN" >> ...
    | "WriteUSAmsgToBQ" >> streaming inserts
    )

oceania_messages = (
    messages.oceania
    | "DoNothing&WriteUSAmsgToBQ" >> streaming inserts
    )

deadletter = (
    (messages.unprocessed, stage1.failed, stage2.failed)
    | "CombineAllFailed" >> Flatn...
    | "WriteUnprocessed/InvalidMessagesToBQ" >> streaminginserts...
)    

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM