可以結合官方的Mobile Game 代碼閱讀本文。
在默認情況下,Apache Beam是不分窗的,也就是採用GlobalWindow,而如果同時也不設置自定義的觸發器,那麼Beam會在所有數據都收集到之後纔開始對數據進行處理。這通常只能適用於有限數據且對實時性要求不高的情況。當輸入爲無限流數據,我們可以
1)設置合適的窗口大小(根據時間戳),在窗口末端進行數據處理;
2)設置觸發器,當條件滿足時觸發,進行數據處理;
3)同時設置窗口和觸發器。
時間戳說明:Beam的數據都是保存在PCollection中。當讀入數據時,PCollection爲每個元素都自動生成一個內置的時間戳,對於無限輸入,數據的時間戳不同。而對於有限輸入,由於是同時讀入,所有的元素的時間戳都是一樣的,這時候分窗是沒有意義的(都在一個窗口)。而我們可以手動爲每個元素設置時間戳,通常採用數據中已有的時間屬性(比如日誌中一般都會帶有事件時間)。可以在DoFn中爲數據帶上時間戳,如:
@ProcessElement public void processElement(ProcessContext c) { c.outputWithTimestamp(c.element(), new Instant(XXX)); }窗口類型:
1)全局窗口
就是默認不分窗的情況。apply(Windows.<TYPE>into(new GlobalWindows()));
2)固定時間大小窗口
最常見的分窗方式,按照時間戳把數據處理窗口分爲固定長度。apply(Windows.<TYPE>into(FixedWindows.of(Duration.standardMinutes(XX))))
3)滑動窗口
需要設置2個參數,窗口大小和窗口產生週期。窗口之間有重疊,通常用於計算平均數的情況(暫沒用過)
4)會話窗口
一般用於相同key數據聚合,同一個key的數據之間時間間隔較大的會被分到不同的窗口。
水位線和超時數據:
當使用用戶自定義的時間戳時,先處理的數據並不總是時間戳較小的,有可能出現時間戳小的數據在後面才產生的情況。Beam通常會給窗口設定一個處理期限時間(圖中縱軸),當超過這個時間的數據被視爲超時數據,而這些期限時間的連線即水位線。
系統會根據實際情況進行預測生成水位線,在默認情況下不對超時數據進行處理,而我們可以通過設置觸發器對超時數據進行額外處理。
觸發器種類
1)時間時間觸發器
根據時間戳進行觸發。
.triggering(AfterWatermark.pastEndOfWindow()//水位線到達時觸發一次 .withEarlyFirings(AfterProcessingTime.pastFirstElementInPane() .plusDelayOf(FIVE_MINUTES))//水位線之前,每次觸發後第一個數據來到之後的5分鐘時再觸發 .withLateFirings(AfterProcessingTime.pastFirstElementInPane() .plusDelayOf(TEN_MINUTES)))//水位線之後,每次觸發後第一個數據來到之後的10分鐘時再觸發
以上分別對水位線上中下的3種數據進行不同的處理。需要注意的是withEarlyFirings和withLateFirings方法生成的觸發器是連續的而不是一次性的。
2)處理時間觸發器
AfterProcessingTime.pastFirstElementInPane().plusDelayOf(FIVE_MINUTES)如方法的字面意思,僅在第一個數據到達後的5分鐘時觸發一次。
3)數據驅動型觸發器
AfterPane.elementCountAtleast(XX)
當處理到XX個時觸發一次。需要注意的是當數據個數小於XX時永遠不會觸發數據處理。
4)混合觸發器
將多個觸發器混合起來,比如1)中的代碼就是3個觸發器混合。其他的還有
①Repeatedly.forever(一次性觸發器)
將一次性觸發器變爲連續型觸發器,觸發後再次等待觸發。例如與AfterProcessingTime.pastFirstElementInPane().plusDelayOf(FIVE_MINUTES)一起用可以實現每個數據到達後的5分鐘進行處理,經常用於全局窗口,可以用orFinally(觸發器)來設置停止條件。
②AfterEach.inOrder(觸發器1,觸發器2...)
當觸發器1滿足後等待觸發器2...知道所有觸發器滿足後開始數據處理。
③AfterFirst(觸發器1,觸發器2..)和AfterAll(觸發器1,觸發器2..)
這2個分別爲或,與的邏輯。
④orFinally
見①
處理方式(官方文檔解釋的很清楚了)
Accumulating Mode
If our trigger is set to .accumulatingFiredPanes
, the trigger
emits the following values each time it fires. Keep in mind that the trigger fires every time three elements arrive:
First trigger firing: [5, 8, 3]
Second trigger firing: [5, 8, 3, 15, 19, 23]
Third trigger firing: [5, 8, 3, 15, 19, 23, 9, 13, 10]
Discarding Mode
If our trigger is set to .discardingFiredPanes
, the trigger
emits the following values on each firing:
First trigger firing: [5, 8, 3]
Second trigger firing: [15, 19, 23]
Third trigger firing: [9, 13, 10]
超時數據處理
.withAllowedLateness(Duration.XXXX(XXX))
可設置允許超時多長時間的數據。