Google cloud dataflow googledataflow中的数据整形操作
我目前有一个流式管道处理事件,并将它们推送到名为EventsTable的BigQuery表: TransactionID EventType 1 typeA 1 typeB 1 typeB 1 typeC 2 typeA 2 typeC 3 typeA TransactionID事件类型 1 A型 1 B类 1 B类 1 C类 2 A型 2 C型 3 A型 我想将一个分支添加到我的处理管道中,并将与事务相关的数据“分组”到一个事务表中。大致上,TransactionTable中的type列中的值将是给定事务的相关eventType的计数。对于前面的示例事件,输出如下所示: TransactionID typeA typeB typeC 1 1 2 1 2 1 0 1 3 1 0 0 事务ID类型A类型B类型C 1 1 2 1 2 1 0 1 3 1 0 0 “类型”列的数量将等于系统中存在的不同eventType的数量 我试图看看如何使用数据流实现这一点,但找不到任何干净的方法。我知道PCollection是不可变的,因此我无法将传入数据存储在不断增长的PCollection结构中,该结构将对传入事件进行排队,直到出现所需的其他元素,并且我可以将它们写入第二个BigQuery表。是否有一种窗口功能允许对数据流执行此操作(如在带有到期日期的临时窗口结构中对事件进行排队)Google cloud dataflow googledataflow中的数据整形操作,google-cloud-dataflow,Google Cloud Dataflow,我目前有一个流式管道处理事件,并将它们推送到名为EventsTable的BigQuery表: TransactionID EventType 1 typeA 1 typeB 1 typeB 1 typeC 2 typeA 2 typeC 3 typeA TransactionID事件
我可能可以用批处理作业和PubSub做一些事情,但这要复杂得多。另一方面,我理解数据流并不意味着有不断增长的数据结构,数据一旦进入,就必须经过管道并退出(或被丢弃)。我错过什么了吗 一般来说,进行这种“跨多个事件聚合数据”的最简单方法是使用
CombineFn
,它允许您组合与特定键关联的所有值。这通常比将事件排队更有效,因为它只需要累积结果,而不是累积所有事件
对于您的特定情况,您可以创建一个自定义。累加器将是一个映射
。例如:
public class TypedCountCombineFn
extends CombineFn<EventType, Map<EventType, Long>, TransactionRow> {
@Override
public Map<EventType, Long> createAccumulator() {
return new HashMap<>();
}
@Override
public Map<EventType, Long> addInput(
Map<EventType, Long> accum, EventType input) {
Long count = accum.get(input);
if (count == null) { count = 0; accum.put(input, count); }
count++;
return accum;
}
@Override
public Map<EventType, Long> mergeAccumulators(
Iterable<Map<EventType, Long>> accums) {
// TODO: Sum up all the counts for similar event types
}
@Override
public TransactionRow extractOutput(Map<EventType, Long> accum) {
// TODO: Build an output row from the per-event-type accumulator
}
}
是否每个事务都有3个关联值?如果没有,您选择Value1、Value2和Value3作为列的原因是否有什么特殊之处?还有关于交易和键/值对结构的更多细节吗?我确实编辑了原始帖子,以便更清楚,并给出了更多细节。希望这有帮助!
PCollection<EventType> pc = ...;
// Globally
PCollection<TransactionRow> globalCounts = pc.apply(Combine.globally(new TypedCountCombineFn()));
// PerKey
PCollection<KV<Long, EventType>> keyedPC = pc.apply(WithKeys.of(new SerializableFunction<EventType, Long>() {
@Override
public long apply(EventType in) {
return in.getTransactionId();
}
});
PCollection<KV<Long, TransactionRow>> keyedCounts =
keyedPC.apply(Combine.perKey(new TypedCountCombineFn()));