如何跨多个数据集和日期分区从Dataproc写入BigQuery?

时间:2016-11-08 18:44:35

标签: google-bigquery google-cloud-dataflow google-cloud-dataproc

我们有一个每日Dataproc流程,可以代表我们的客户从多个来源导入数据进行分析。目前,我们每天都没有收到大量数据,但预计会大幅增加。我们当前的流程有四个Dataproc Spark作业,可以在最终作业中导入,解析,加入和输出到Cloud SQL,在每个作业之间编写临时Avro文件。即使使用我们当前的数据级别,Cloud SQL也开始变得紧张(部分原因是由于一个公认的糟糕模式)。我们想要转向BigQuery,所以我的第一个工作是第五个工作,读取最终的Avro文件并输出到BigQuery,基本上与当前的Cloud SQL输出工作并行。

使用Using the BigQuery Connector with Spark的示例我已经研究了如何做到这一点,但需要更多的复杂性。具体来说,我需要:

  • 将单个客户数据(多个客户'数据可以从单一来源)分离到单个数据集中
  • 根据" DateOfService"按天分区数据。字段

我认为这样做的唯一方法是由customer和DateOfService创建单独的RDD,并将它们分别写入适当的数据集和表分区。我对此的担心是,对于单个RDD,写作似乎需要花费很长时间(几分钟),如果我必须编写几个单独的RDD,它可能会变得过高。

到目前为止,这是我的代码的重要部分。剩下的就是所有的配置,除了我的表格架构和项目的价值外,与谷歌的例子相同。

// Read the processed data from Avro
val claimsRdd = sc.hadoopFile[AvroWrapper[GenericRecord], NullWritable, AvroInputFormat[GenericRecord]]("gs://path/to/avro/file")

// Convert from a RDD[Row] to RDD[String]. Conveniently these are JSON strings.
val claimsJson = claimsRdd.map(l => new String(l._1.datum.toString()))

// Convert into a RDD[(Null, JsonObject)]
val claimsJsonObj = claimsJson.map(s => (null, (new JsonParser).parse(s).getAsJsonObject))

// Write to BigQuery
claimsJsonObj.saveAsNewAPIHadoopDataset(conf)

我的问题是:

  1. 这是多种RDD方法,我描述了唯一或最好的方法 这样做?

  2. 有没有更快的方法从Dataproc写入BigQuery?或者是 数据流在这方面更快?我或许可以改写 数据流,但我有一个用Scala编写的解析器,我必须这样做 重写为Java,我们使用Spark的SQL功能和 在Dataflow中研究如何做到这一点似乎有点令人生畏。但如果 这是我认为的更好的方式。

1 个答案:

答案 0 :(得分:1)

批处理数据流当前不支持写入动态的BigQuery表集,因此您需要预先了解客户和日期。但是,如果是这种情况,Dataflow将有效地处理此问题并并行执行上传。

此外,可以直接在Dataflow管道中使用Scala代码;只需使用Scala程序中的Dataflow API。

我对Spark不太了解,所以无法评论在那里处理这个问题的最佳方法。