代码之家  ›  专栏  ›  技术社区  ›  zangw

如何在googleclouddataflow/apachebeam中并行运行多个WriteToBigQuery?

  •  0
  • zangw  · 技术社区  · 7 年前

    {"type": "A", "k1": "v1"}
    {"type": "B", "k2": "v2"}
    {"type": "C", "k3": "v3"}
    

    我想分开 type: A 事件到表 A type:B 事件到表 B , type: C 事件到表 C

    下面是我的代码通过 apache beam pythonsdk并将数据写入 bigquery

    A_schema = 'type:string, k1:string'
    B_schema = 'type:string, k2:string'
    C_schema = 'type:string, k2:string'
    
    class ParseJsonDoFn(beam.DoFn):
        A_TYPE = 'tag_A'
        B_TYPE = 'tag_B'
        C_TYPE = 'tag_C'
        def process(self, element):
            text_line = element.trip()
            data = json.loads(text_line)
    
            if data['type'] == 'A':
                yield pvalue.TaggedOutput(self.A_TYPE, data)
            elif data['type'] == 'B':
                yield pvalue.TaggedOutput(self.B_TYPE, data)
            elif data['type'] == 'C':
                yield pvalue.TaggedOutput(self.C_TYPE, data)
    
    def run():
        parser = argparse.ArgumentParser()
        parser.add_argument('--input',
                          dest='input',
                          default='data/path/data',
                          help='Input file to process.')
        known_args, pipeline_args = parser.parse_known_args(argv)
        pipeline_args.extend([
          '--runner=DirectRunner',
          '--project=project-id',
          '--job_name=seperate-bi-events-job',
        ])
        pipeline_options = PipelineOptions(pipeline_args)
        pipeline_options.view_as(SetupOptions).save_main_session = True
        with beam.Pipeline(options=pipeline_options) as p:
            lines = p | ReadFromText(known_args.input)
    
        multiple_lines = (
            lines
            | 'ParseJSON' >> (beam.ParDo(ParseJsonDoFn()).with_outputs(
                                          ParseJsonDoFn.A_TYPE,
                                          ParseJsonDoFn.B_TYPE,
                                          ParseJsonDoFn.C_TYPE)))
    
        a_line = multiple_lines.tag_A
        b_line = multiple_lines.tag_B
        c_line = multiple_lines.tag_C
    
        (a_line
            | "output_a" >> beam.io.WriteToBigQuery(
                                              'temp.a',
                                              schema = A_schema,
                                              write_disposition = beam.io.BigQueryDisposition.WRITE_TRUNCATE,
                                              create_disposition = beam.io.BigQueryDisposition.CREATE_IF_NEEDED
                                            ))
    
        (b_line
            | "output_b" >> beam.io.WriteToBigQuery(
                                              'temp.b',
                                              schema = B_schema,
                                              write_disposition = beam.io.BigQueryDisposition.WRITE_TRUNCATE,
                                              create_disposition = beam.io.BigQueryDisposition.CREATE_IF_NEEDED
                                            ))
    
        (c_line
            | "output_c" >> beam.io.WriteToBigQuery(
                                              'temp.c',
                                              schema = (C_schema),
                                              write_disposition = beam.io.BigQueryDisposition.WRITE_TRUNCATE,
                                              create_disposition = beam.io.BigQueryDisposition.CREATE_IF_NEEDED
                                            ))
    
        p.run().wait_until_finish()
    

    输出:

    INFO:root:start <DoOperation output_banner/WriteToBigQuery output_tags=['out']>
    INFO:oauth2client.transport:Attempting refresh to obtain initial access_token
    INFO:oauth2client.client:Refreshing access_token
    WARNING:root:Sleeping for 150 seconds before the write as BigQuery inserts can be routed to deleted table for 2 mins after the delete and create.
    INFO:root:start <DoOperation output_banner/WriteToBigQuery output_tags=['out']>
    INFO:oauth2client.transport:Attempting refresh to obtain initial access_token
    INFO:oauth2client.client:Refreshing access_token
    WARNING:root:Sleeping for 150 seconds before the write as BigQuery inserts can be routed to deleted table for 2 mins after the delete and create.
    INFO:root:start <DoOperation output_banner/WriteToBigQuery output_tags=['out']>
    INFO:oauth2client.transport:Attempting refresh to obtain initial access_token
    INFO:oauth2client.client:Refreshing access_token
    WARNING:root:Sleeping for 150 seconds before the write as BigQuery inserts can be routed to deleted table for 2 mins after the delete and create.
    

    • 大查询 ?
    • 从日志来看,代码似乎不是并行运行,而不是按顺序运行3次?

    1 回复  |  直到 7 年前
        1
  •  3
  •   Guillem Xercavins    7 年前

    bigquery中没有数据?

    当数据被写入BigQuery时,您的代码看起来非常好( C_schema 应该是 k3 k2 ). 请记住,您正在流式传输数据,因此如果单击 Preview SELECT *

    enter image description here

    从日志来看,代码似乎不是并行运行,而不是按顺序运行3次?

    WARNING 中的消息 code 我们可以阅读以下内容:

    # if write_disposition == BigQueryDisposition.WRITE_TRUNCATE we delete
    # the table before this point.
    if write_disposition == BigQueryDisposition.WRITE_TRUNCATE:
      # BigQuery can route data to the old table for 2 mins max so wait
      # that much time before creating the table and writing it
      logging.warning('Sleeping for 150 seconds before the write as ' +
                      'BigQuery inserts can be routed to deleted table ' +
                      'for 2 mins after the delete and create.')
      # TODO(BEAM-2673): Remove this sleep by migrating to load api
      time.sleep(150)
      return created_table
    else:
      return created_table
    

    读后 BEAM-2673 BEAM-2801 ,似乎这是由于BigQuery sink使用流式API和 DirectRunner

    相反,如果我们在数据流上运行它(使用 DataflowRunner 22:19:45 结束于 22:19:56 :

    enter image description here