iT邦幫忙

2023 iThome 鐵人賽

DAY 20
0

前面講的 windows 窗格,通常在前面都會先加上一個 key-by。Key-by 的概念是指將一個資料流按照某個屬性或函數的值分割成多個子資料流,每個子資料流包含了相同的鍵值。

我們可能會想針對資料做不同的分組。例如很經典的計算每個詞 (word) 的出現次數。為了強調 Flink Streaming 的特性,我們假設每個 word 累積達 100 個字就輸出結果一次,然後將該 word 的 count 歸零重新計數。

第一種做法,你可以全域做,自己維護一個 Map<String, Integer> 的物件,每當一筆資料進來你就查詢一次 map 然後做 count + 1。累積每100筆後就將 map 輸出。

這種做法很傳統,基本上也只存在一個窗格,畢竟任何的 word 進來你都自己判斷,然後自己塞回 map 內。基本上你也享受不到分佈計算的優點。

第二種做法,我們可以加上 key-by。這樣做的目的是為了在後續的運算中,能夠對每個鍵值進行平行處理,提高效能和容錯性。Key-by 的操作會改變資料流的分區方式,使得同一個鍵值的資料都被發送到同一個分區或運算節點上。

stream
       .keyBy(word)      
       .window(TumblingCountWindows.of(100))
			 .count()

基本上就是這麼簡單,每個 window 都會在累積 100 筆之後,輸出 count 數 (基本上就是 100 )。但是 Flink 會自動做平行運算 (有設定的話),所以每個 word 都可以被分配到不同機器計數,有效的利用平行運算功能。而且你也不必自己維護 map,因為根本上不存在。

基本上,可以理解成 Map-Reduce 的架構。所以寫 Flink 的難度有一部份在這裡,你要拆解掉過往整理一坨資料的概念,轉而想要怎麼找出相同的 key 跟適合的 windows 來處理你的資料。

但要注意的是,streaming 是假設資料是永無止盡的,所以他會盡可能的保存狀態,同時將處理完的資料給遺忘。所以你要學著斷捨離,不要試著把資料保留下來,或是設定一個 global window,會讓你的記憶體爆炸的。

另外就是,Count Window 是看個數的,某些資料型態可能會出現大量的 key 但每個 key 只有一點重覆的資料。這種情況下 Flink 會試著記住所有還沒滿足 count 數量條件的 window,也會導致記憶體被吃光。

舉例來說,我們想要統計每個使用者在一個小時內的點擊次數,並且每點擊 10 次就觸發一個 window。如果我們的資料集中有很多不同的使用者,但每個使用者只點擊了幾次,那麼 Flink 就會為每個使用者創建一個 count window,並且一直等待直到該 window 達到 10 次點擊。


上一篇
Flink Windows - Day19
下一篇
Flink 存檔跟還原機制 - Day21
系列文
用 Airflow & Flink 來開發 ETL 吧30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言