如何在GCP上执行数据非规范化?

时间:2019-06-24 13:40:07

标签: google-bigquery etl google-cloud-dataflow apache-beam

我正在尝试对Bigquery中的三个表进行规范化和联接,这些表名为order,order_item和user。我已经有一个用于使用pubsub和dataflow更新这些表的管道。现在,我想创建一个管道,用于在提到的三个表中的任何一个发生更新或插入时更新一个新的,非规范化的表。这些对order和order_item的更新必须同步,并且仅当在订单上发生插入时才应加入用户(以便在创建新订单时显示用户的状态)。

到目前为止,我想出了两种解决方案。

  • 一种方法是,当通过数据流读取来自pubsub的消息并捕获来自非规范化表的最新对应记录时,捕获每个表上的更改。最后,旧记录被新记录替换。
  • 另一种方法是查询order和order_item表以获取更新的或新插入的行,然后使用bigquery sql将它们连接起来,从而将结果附加到非规范化表中。这项工作是在Airflow的帮助下定期执行的。

订单

id(主键) last_updated_at created_at user_id(外键)

====================

order_item

id(主键) last_updated_at created_at order_id(外键)

====================

用户

id(主键) last_updated_at created_at

我对数据流不是很熟悉,我无法碰到任何教程或示例来说明如何使用它进行工作(尽管有示例代码显示了如何完成ETL操作,但是没有解决方案同步问题)。有什么我可以研究的例子,哪种选择似乎更有效?

1 个答案:

答案 0 :(得分:0)

我想以BigQuery不是事务性数据库作为开头,因此在事实变得非常困难之后尝试保持一致工作。在这种情况下,我建议您使用Cloud Spanner或Cloud SQL(有关两者之间的区别,请参见此Quora post)。例如,在Cloud Spanner中这非常容易。 transactions有一个概念,您可以在任何给定时间使非规范化表与其他表保持完美同步。

从好的方面来说,如果您对非规范化表没问题,可能会与其他表不同步,那么可以找到更简单的解决方案。

在这种情况下,我假设切换到另一种存储产品成本高昂,并且表可能不同步也是可以的。如果您需要进行批处理或流数据分析,那么Cloud Dataflow是一个很棒的产品,但是在像您这样的用例(基于事件的处理)中使用该API时会很尴尬。如果您想继续使用Dataflow,第一个解决方案似乎是最好的,但是我实际上建议使用类似Cloud Functions的方法。

设置如下:

  1. Pub / Sub写入数据流
  2. 数据流将更新的行写入BigQuery
  3. 数据流写入包含增量的Pub / Sub消息(例如,将X行插入订单,在order_item中更新Y行)。
  4. 具有在发布/订阅订阅上触发的云函数,该订阅具有您指定的逻辑以从规范化表中读取正确的行,然后写入非规范化表。

herehere的启发,您的Cloud Function可能类似于以下内容(用Java语言编写)。 :

ShellExecute

How to insert How to query