如何在 Apache Beam 中 "join" 频繁更新的流与不定期更新的流?

How to "join" a frequently updating stream with an irregularly updating stream in Apache Beam?

我有一个由 ID PCollection<KV<ID,Measurement>> 键控的测量流,以及类似该 ID PCollection<KV<ID,SomeIDInfo>> 的附加信息的更新日志流。新数据会定期添加到测量流中,比如每个 ID 每秒一次。另一方面,具有附加信息的流仅在用户执行手动重新配置时更新。我们不能说这种情况经常发生,特别是更新频率可能因 ID 而异。

我现在的目标是通过 ID 的附加信息丰富测量流中的每个条目。也就是说,输出应该类似于 PCollection<KV<ID,Pair<Measurement,SomeIDInfo>>>。或者,换句话说,我想将测量流与附加信息流进行左连接。

我希望这是一个非常常见的用例。来自 Kafka Streams,这可以很容易地通过 KStream-KTable-Join 实现。然而,对于 Beam,到目前为止我所有的方法似乎都不起作用。我已经想到了以下想法。

想法 1:CoGroupByKey 固定时间 windows

将 window 应用于测量流不会成为问题。但是,由于附加信息流更新不规律,而且更新频率明显低于测量流,因此没有合理的通用 window 大小,因此每个 ID 至少有一个更新信息。

想法 2:CoGroupByKey 具有全局 window 并且作为非默认触发器

完善之前的想法,我考虑使用处理时间触发器,例如触发每 5 秒。这个想法的问题是我需要使用 accumulatingFiredPanes() 来获取附加信息,因为两次触发之间可能没有新的密钥数据,但我必须使用 discardingFiredPanes() 来获取测量流,否则我的窗格很快就会变得太大。这根本行不通。当我以这种方式配置我的管道时,附加信息流也会丢弃更改。将两个触发器都设置为累积它可以工作,但是,正如我所说,这是不可扩展的。

想法 3:侧面输入

另一个想法是使用辅助输入,但这个解决方案并不是真正可扩展的——至少如果我没有遗漏任何东西的话。通过辅助输入,我将从附加信息流创建一个 PCollectionView,它是 ID 到(最新)附加信息的映射。 “加入”可以在 DoFn 中通过该视图的侧面输入来完成。但是,该视图似乎由执行侧面输入的所有实例共享。 (很难找到与此相关的任何信息。)我们不想对 ID 的数量和附加信息的大小做出任何假设。因此,在这里使用辅助输入似乎也行不通。


你讨论的辅助输入选项是目前最好的选择,尽管你对可扩展性的担忧是正确的,因为辅助输入被广播给所有工人。

或者,您可以将不经常更新的一侧存储在外部键值存储中,然后只从 DoFn 进行查找。如果你走这条路,通常首先在主输入上使用 ID 作为键执行 GroupByKey 通常很有用,这可以让你以良好的缓存命中率缓存查找。