我正在构建一个Apache Beam(v2.0)管道,以便在Google Cloud Dataflow中运行。预期的流程是:
sessionId
属性。KV<String, String>
,其中键为sessionId
,值为整个JSON对象。以下是管道代码:
Pipeline pipeline = Pipeline.create(options);
pipeline.apply(PubsubIO
.readStrings()
.fromSubscription(options.getSubscription()))
.apply("AddKeyFn", ParDo.of(new DoFn<String, KV<String, String>>() {
@ProcessElement
public void processElement(ProcessContext c) {
Gson gson = new Gson();
String key = (String) gson.fromJson(c.element(), HashMap.class).get("sessionId");
KV<String, String> kv = KV.of(key, c.element());
c.output(kv);
}
}))
.apply(Window.<KV<String, String>>into(Sessions.withGapDuration(Duration.standardSeconds(2))))
.apply("PrintFn", ParDo.of(new DoFn<KV<String, String>, Void>() {
@ProcessElement
public void processElement(ProcessContext c) {
System.out.println("****");
System.out.println(c.element());
System.out.println(c.timestamp());
}
}));
return pipeline.run();
我希望Window函数在每次会话结束时为每个会话(基于密钥)发出结果。出于测试目的,我使用pub / sub仿真器,只是随机发送数据。
因此,例如,如果将以下数据发送到pub / sub:
{"sessionId": "2", "data": "data9583", "timestamp": 1507293681}
{"sessionId": "3", "data": "data5220", "timestamp": 1507293683}
{"sessionId": "6", "data": "data2998", "timestamp": 1507293684}
{"sessionId": "3", "data": "data3820", "timestamp": 1507293684}
{"sessionId": "6", "data": "data5728", "timestamp": 1507293685}
{"sessionId": "6", "data": "data7173", "timestamp": 1507293686}
{"sessionId": "4", "data": "data8800", "timestamp": 1507293687}
Window函数应发出以下内容:
sessionId=2
sessionId=3
sessionId=6
sessionId=4
这里的想法是:
{gapDuration}
KV<String, String>
传递到Window函数中)上面的窗口函数直接来自Beam documentation。
我实际看到的是:
{gapDuration}
发出窗口值得注意的是,如果我添加一个自定义CombineFn
(它只是将JSON对象转换为一个JSON对象数组),那么CombineFn
和都没有。到PrintFn
(我在CombineFn
中添加了一个打印声明。)
我假设触发与此有关,但似乎找不到任何有用的东西让我朝着正确的方向(有一些令人惊讶的少量示例代码用于Beam,特别是2.0。
我的问题:
资源我一直没有成功:
答案 0 :(得分:3)
首先,需要在窗口之间合并元素的窗口函数需要应用聚合操作,例如GroupByKey或Combine。这在Windowing Basics下的Beam编程指南中进行了讨论。
其次,PubSub默认情况下(正如您所使用的)将根据元素的发布时间为元素分配时间戳。由于您有明确的时间戳字段,因此您可能希望查看使用时间戳属性发布这些元素,并使用withTimestampAttribute
method读取它们。这将使用您发布的timestamp属性作为时间戳。