簡體   English   中英

Apache Beam:: 無法與 session window 一起使用 groupbykey 工作

[英]Apache Beam :: can't get groupbykey work with session window with java

我有一個簡單的問題。 假設我正在讀取一個 parquet 文件,該文件每行生成一個 avro GenericRecord object,如下所示。

{"name":"john", "surename":"doe", "age":40, "user_pk":"john:doe:40", "unique_attribute":"j1"}
{"name":"john", "surename":"doe", "age":40, "user_pk":"john:doe:40", "unique_attribute":"j2"}
{"name":"john", "surename":"doe", "age":40, "user_pk":"john:doe:40", "unique_attribute":"j3"}
{"name":"john", "surename":"doe", "age":40, "user_pk":"john:doe:40", "unique_attribute":"j4"}

{"name":"paul", "surename":"carl", "age":28, "user_pk":"paul:carl:28", "unique_attribute":"p1"}
{"name":"paul", "surename":"carl", "age":28, "user_pk":"paul:carl:28", "unique_attribute":"p2"}
{"name":"paul", "surename":"carl", "age":28, "user_pk":"paul:carl:28", "unique_attribute":"p3"}

該文件是故意展平的,我想取消展平它們。

  • 我們知道輸入是有序的,我想處理它們直到下一個 session 鍵,並傳遞給管道中的下一個應用,以保持 memory 要求最小,所以中間階段應該返回KV<String, Iterable<GenericRecord>>甚至更好地組合KV<String, GenericRecord>
<"john:doe:40", {"name":"john", "surename":"doe", "age":40, ["unique_attribute":"j1", ...]}>
<"paul:carl:28", {"name":"paul", "surename":"carl", "age":28, "user_pk":, ["unique_attribute":"p1", ...]}

這就是我到目前為止所得到的;

        pipeline.apply("FilePattern", FileIO.match().filepattern(PARQUET_FILE_PATTERN))
                .apply("FileReadMatches", FileIO.readMatches())
                .apply("ParquetReadFiles", ParquetIO.readFiles(schema))
                .apply("SetKeyValuePK", WithKeys.of(input -> AvroSupport.of(input).extractString("user_pk").get())).setCoder(KvCoder.of(StringUtf8Coder.of(), AvroCoder.of(schema)))
                .apply(Window.into(Sessions.withGapDuration(Duration.standardSeconds(5L)))).setCoder(KvCoder.of(StringUtf8Coder.of(), AvroCoder.of(schema)))
                .apply("SetGroupByPK", GroupByKey.create()).setCoder(KvCoder.of(StringUtf8Coder.of(), IterableCoder.of(AvroCoder.of(schema))))
...
...

我不知道是否有更好的方法,但現在我使用了Sessions.withGapDuration窗口策略。 我預計我會在每 ~5 秒內獲得一個分組元素KV<String, Iterable<GenericRecord>> element ,但是在GroupByKey之后我沒有得到任何東西,我什至不確定GroupByKey是否真的在做任何事情,但我知道memory 正在迅速增加,因此它必須等待所有項目。

所以問題是,你將如何設置一個窗口 function 允許我分組鍵。 我也嘗試過Combine.byKey ,因為它應該是GroupByKey + Windowing Function但無法實現?

我已經設法讓 groupby 工作,但不確定我是否完全理解。 我不得不添加兩個想法。 Beam 中的第一個(任何?) IO 操作不添加時間戳。

.apply("WithTimestamp", WithTimestamps.of(input -> Instant.now()))

其次,我添加了一個Triger ,因此GroupByKey實際上會被觸發。 不知道為什么它沒有首先觸發。 我相信有人對此有解釋。

.apply("SessionWindow", Window.<KV<String, GenericRecord>>into(Sessions.withGapDuration(Duration.standardSeconds(5L))).triggering(
                        AfterWatermark.pastEndOfWindow()
                                .withLateFirings(AfterProcessingTime
                                        .pastFirstElementInPane().plusDelayOf(Duration.ZERO)))
                        .withAllowedLateness(Duration.ZERO)
                        .discardingFiredPanes())

它並不完美,仍然需要等待幾分鍾才能看到GroupByKey被觸發,即使 window 只有5s ,但它最終被觸發,這是進步。

編輯:好的,看起來不需要時間戳,我假設因為 window 是基於 session 而不是基於時間的。 我也將設置更改為流式傳輸

        options.as(StreamingOptions.class)
                .setStreaming(true);

我希望這對遇到類似問題的人有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM