假设您有来自两个不同pubsub主题的信息进入Google Cloud Dataflow,并且您希望将来自一个主题的信号与来自其他主题的信号进行比较,并在它们相等时生成匹配。如果同时(或几乎同时)在其中一个主题上有多个相等的信号,那么我们就不应该生成匹配。是否有可能以近乎实时的方式在Dataflow中生成匹配,这样我们就可以100%确定生成的匹配是否正确(即没有误报)?如果是这样,你会如何实现它?由于数据可能会延迟到Dataflow的时间窗口,我怀疑这很难。
为了简化,如果我们从一个pubsub主题获得“A”,从另一个主题获得“A”,我们应该生成一个匹配,但前提是没有任何其他A进入任一主题大约在同一时间(比如说加减1秒)。
答案 0 :(得分:0)
如果我理解你的问题,我会按如下方式分解。我将使用我们标准的四个问题,因为它在这种情况下很有用。
CoGroupByKey
的加入。Sessions
。但我不知道你是否希望会话在两个流上,或者每个流都是单独的。希望我的回答足以让你工作。我们假设你有这些输入:
PCollection<String> streamA
PCollection<String> streamB
如果你想根据流中的同时性进行匹配+重复数据删除,那么你可以直接进入Sessions
并进行CoGroupByKey
:
PCollection<KV<String, String>> windowedA = streamA
.apply(WithKeys.of(String v -> v))
.apply(Window.into(
Sessions.withGapDuration(Duration.standardSeconds(1))));
PCollection<KV<String, String>> windowedB = // ditto
// Set up join handles
TupleTag<String> tagA = new TupleTag<String>() {};
TupleTag<String> tagb = new TupleTag<String>() {};
KeyedPCollectionTuple joinInput =
KeyedPCollectionTuple
.of(tagA, windowedA)
.and(tagB, windowedB);
PCollection<String> result = joinInput
// Group streams together by shared key
.apply(CoGroupByKey.create())
// Eliminate all but 1-to-1 matches
.apply(Filter.by(
KV<String, CoGbkResult> joined ->
Iterables.size(joined.getValue().getAll(tagA)) == 1
&& Iterables.size(joined.getValue().getAll(tagB)) == 1))
// The key is all we care about
.apply(Keys.create());
集合result
包含具有近同步匹配但在一秒内没有重复的字符串。您的真实用例可能需要进行一些调整。
如果你想分别对两个流进行重复数据删除,那就稍微复杂一些,但不要太多。您需要为每个流单独进行会话和GroupByKey
,然后根据您希望窗口连接输出的方式重新窗口。