我有一个 ETL 流程,需要在一个键上组合两个 Pub/Sub 消息并将它们写入 BigQuery。其中一种消息类型是父消息类型;我正在处理付款处理,例如,这是订单或付款。另一个是孩子;这是付款的更新(“授权”、“已付款”等)。
我想使用 Dataflow 组合键并写入 BigQuery,其中这些更新将元素添加到原始事务中。 BigQuery 中的架构如下所示:
名字 | 描述 | 类型 | 模式 |
---|---|---|---|
id | 支付交易的UUID | 字符串 | 单人 |
金额 | 交易金额 | 整数 | 单人 |
活动 | 交易事件(见下文) | 记录 | 重复 |
...
在事件记录中,它有类似:
名字 | 描述 | 类型 | 模式 |
---|---|---|---|
事件_id | 此活动的 UUID | 字符串 | 单人 |
交易ID | UUID 绑定到支付交易(上图) | 字符串 | 单人 |
事件类型 | 一个枚举,指定它是否是授权等。 | 整数 | 单人 |
...
换句话说,每个 event-type Pub/Sub 消息都将与相应的 transaction-type Pub/Sub 消息相匹配。
CoGroupByKey
。 AFAICT,对于 CoGroupByKey
需要使用哪种类型的窗口(如果有的话),没有规范。在那种情况下,我不明白它是如何工作的。 我认为需要以下选项之一:
CoGroupByKey
会将每个元素无限期地保留在内存中,直到找到另一个元素。例如,如果交易中存在价值为 id
的 1234987
,那么它将保持“等待”状态,直到找到 transaction_id
的 1234987
。找到后,执行 CoGroupByKey
,无论后续管道操作完成,都可以从内存中清除具有该 ID 的消息。CoGroupByKey
不适用于streaming数据。与上面类似,它将一直等待,直到匹配相同的id
和transaction_id
。但是,一旦窗口(以及任何相关的允许延迟)过期,它就会清除 id
或 transaction_id
。
CoGroupByKey
example 没有窗口化。PCollection
上的某种方法可以进行某种清除。我说得对吗?我需要某种限制吗?这个限制是什么,或者应该是什么?
我只需要知道如何创建一个结合这两个流的管道,并且在生产中不会使我的系统崩溃。如果内存问题只有在大规模时才会出现,那么这很难测试。
(我使用 Python SDK,但任何语言的编码解决方案都值得赞赏;从一种语言转换为另一种语言很容易。)
你是对的,它是#2:
CoGroupByKey
不适用于无界数据,除非有一些窗口。
有几个原因,其中之一您已经确定:
很多时候,您可能需要
Session
窗口,因为这将允许您将两个元素连接在一起,而您只关心它们时间戳之间的差异。
在其他情况下,您可能需要通过合并 PCollection 并使用有状态 ParDo 在全局窗口中进行加入。为了简洁起见并得到这个答案