Apache Flink 誤用之痛

整理:lyee(Flink 社區志願者)
git


摘要: 本文根據 Flink Forward 全球在線會議 · 中文精華版整理而成, 圍繞着項目的 開始、需求分析、開發, 以及測試、上線、運維整個生命週期展開,介紹了 Apache Flink 實踐中的一些典型誤用狀況,並給出了相應的更優實踐方案。

Flink 實踐中最首當其衝的誤用就是不按迭代開發的過程操做。最佳實踐應該遵循迭代開發的步驟進行,包含如下幾個階段:

  1. 項目開始
  2. 涉及分析
  3. 開發
  4. 測試
  5. 上線
  6. 維護

Tips: 點擊「 閱讀原文 」可查看更多 Flink 社區最新動態~


1. 項目開始github


在開始開發前,咱們須要選擇正確的切入方式,如下幾種每每是最糟糕的開始:

    a) 從一個具備挑戰性的用例開始(端對端的 Exactly-once、大狀態、複雜的業務邏輯、強實時SLA的組合)    b) 以前沒有流處理經驗  c) 不對團隊作相關的培訓  d) 不利用社區

在開發的過程當中,其實要認認真真的來規劃咱們的切入點,首先,要從簡單的任務開始按部就班。要有必定的大數據和流處理的知識積累,儘可能參加一些培訓,也要利用好社區資源。基於這樣的想法,咱們就能很快找到切入點。

怎麼樣去作?社區提供了不少的培訓,包括 Flink Forward 和 Vererica 網站上有各類培訓課程,你們能夠去看。同時,能夠充分利用社區。社區還創建了中文的郵件列表,你們能夠充分利用中文郵件列表來解決手頭的疑難雜症。另外,Stack Overflow 也是個提問的好地方,但在提問前儘可能去看一看已有的提問,作到心中有數。

  • 郵件列表:apache

    user@flink.apache.com/user-zh@flink.apache.org swift

  • Stack Overflow:windows

    www.stackoverflow.com後端


2. 設計分析安全


方案設計中的一些常見錯誤思惟,每每是因爲沒有充分思考需求致使的,好比:

    a) 不考慮數據一致性和交付保證    b) 不考慮業務升級和應用改進  c) 不考慮業務規模問題  d) 不深刻思考實際業務需求
   

咱們要認真分析需求,同時認真考慮實際交付狀況。提到一致性和交付保障,其實能夠經過幾個問題來引導你們完成這件事,以下圖所示:


第1個問題,是否在意數據的丟失?

果不在意,你能夠沒有 Checkpoint。

第2個問題,是否在意結果的正確性?

在不少的場景裏面,咱們很是關注結果的正確性,好比金融領域,可是另一些場景好比監控或其餘簡單的使用場景僅須要一個概要的數據統計。若是不在意結果的正確性, 能夠考慮用 at-least-once 的模式配置並使用可回放的數據源。相反,若是 結果的準確性十分重要,且下游不關心重複記錄,那麼僅需設置 exactly-once 模式並使用可回放的數據源。 若是下游要求數據不能重複,哪怕數據正確也只能發送一次,這種時候就對 sink 有更進一步的限制,在 exactly-once 的模式下,使用可回放的數據源,而且 sink 須要支持事務。

帶着這樣的思惟方式分析業務,才能很是清晰地知道,怎麼去使用 Flink,進而避免一些糟糕的事情發生。

完成分析以後,最終目的是什麼? 咱們爲何要有這種選擇,而不是一上來就選一個最好的方案?

由於世界上永遠沒有「最好」,這裏的核心因素就是延遲,要根據業務的延遲和準確性需求來均衡去作選擇。

當需求都分析好以後,還須要去思考應用是否須要升級。從一個正常的 Flink 做業來說,咱們有幾個問題要考慮。第一個,Flink 做業通常都有狀態讀取,作升級時須要有 savepoint 機制來保障,將狀態存儲保留在遠端,再恢復到新的做業上去。不少場景下都會有升級的需求,這簡單列了幾點:

a 升級集羣版本   b 業務 bug 的修復c 業務邏輯(拓撲)的變動

在比較複雜的場景下,做業會有拓撲的變化,以下圖:


此處須要添加一個算子,去掉一個 sink 。對於這樣的變化,咱們要考慮狀態的恢復。當 Flink 發現新做業有節點沒了,對應的狀態沒法恢復,就會拋出異常致使升級失敗。這時候可使用參數 --allowNonRestoreState 來忽略此類問題。

另外新做業中還有新建的節點,這個節點就用空狀態去初始化便可。除此以外,還須要注意,爲了保證做業成功啓動而且狀態恢復不受影響,咱們應該爲算子設置 StreamAPI 中的 uid 。固然,若是狀態的結構發生了變化,Avro Types 和 POJO 的類型都是支持的,Kryo 是不支持的。最後建議全部 key 的類型儘可能不要修改,由於這會涉及 shuffle 和 狀態的正確性。

資源的使用狀況也是必需要考慮的因素之一,下面是一個評估內存和網絡 IO 使用的思路。這裏咱們假設使用的是 Fs State,全部運行時狀態都在內存中。不恰當的資源配置可能會形成 OOM 等嚴重的問題。


完成資源評估後,還須要考慮事件時間和亂序問題。下面是一個具體的例子:


在這個例子中選擇哪一種時間窗口、什麼時候觸發計算,僅憑一句話的需求是沒法描述清楚的。只有根據流處理的特性結合實際的業務去認真分析需求,才能將 Flink 技術進行恰當的運用。

還須要注意,Flink 是流批統一的計算引擎,不是全部的業務都能用流處理或者都能用批處理來實現,須要分析本身的場景適合用哪一種方式來實現。

3. 開發微信



3.1 API 的選擇

在 DataStream API 和 Table API/SQL 的選擇上,若是有強烈的需求控制狀態和每條狀態到來的行爲,要使用 DataStream API;若是是簡單的數據提取和關係代數的運算,能夠選擇 Table API/SQL。在一些場景下,只能選擇 DataStream API:

a) 在升級過程當中要改變狀態b) 不能丟失遲到的數據c) 在運行時更改程序的行爲


3.2 數據類型網絡


在開發過程當中,關於數據類型,有兩種誤用場景:

  
    
  
  
  
   
   
            
   
   

  
    
  
  
  
   
   
            
   
   

a) 使用深度嵌套的複雜數據類型b) KeySelector 中使用任意類型
正確的作法是選擇儘量簡單的狀態類型,在 KeySelector 中不使用 Flink 不能自動識別的類型。


3.3 序列化併發


數據類型越簡單越好,基於序列化成本的考慮,儘可能使用 POJO 和 Avro SpecificRecords。也鼓勵你們開發完使用 IDE 的工具本地調試一下,看一下性能瓶頸在哪。

序列化器
Opts/s
PojoSeriallizer
813
Kryo
294
Avro(Reflect API)
114
Avro(SpecificRecord API)
632

圖5中是一種效率較低的處理過程,咱們應該先進行過濾和投影操做,防止不須要的數據進行多餘的處理。




3.4 併發性


兩種誤用場景及相應容易形成的問題:

  • 任務之間共享靜態變量


容易引發 bug;容易形成死鎖和競爭問題;帶來額外的同步開銷。

  • 在用戶函數中生成線程


檢查點變得複雜易錯。

對於想用線程的狀況,若是是須要加速做業,能夠調整並行度和資源,使用異步IO;若是是須要一些定時任務的觸發,可使用 Flink 自帶的 Timer 定時調度任務。


3.5 窗口


儘可能避免像圖6這樣自定義 Window,使用 KeyedProcessFunction 可使得實現更加簡單和穩定。


另外,也要避免圖7中的這種滑動窗口,在圖7中每一個記錄被50萬個窗口計算,不管是計算資源仍是業務延遲都會很是糟糕。


3.6 可查詢狀態

Queryable State 目前還在不斷的完善中,能夠用於監控和查詢,但在實際投產時仍是有一些問題須要注意的,好比對於線程安全訪問,RocksDB 狀態後端是支持的,而 FS 狀態後端是不支持的,另外還有性能和一致性保障等問題須要注意。

3.7 DataStream API 的應用

對圖8這種場景,可使用 DataStreamUtils#reinterpretAsKeyedStream 這個方法,避免面對相同的 key 進行屢次 shuffle 。


對圖9這種場景,應該把一些初始化的邏輯寫在 RichFunction 的 open 方法裏。


4. 測試


除了系統測試和 UDF 的單元測試,還應該作 Mini Cluster 測試,在本機運行一個 Mini Cluster 把端到端的業務跑起來,能夠及早地發現一些問題。

還有 Harness 測試,它能夠精準地幫助完成有狀態的任務測試。它能夠精準的控制 watermark、元素的 event time 等。能夠參考:

https://github.com/knaufk/flink-testing-pyramid


5. 上線


不少場景會致使業務抖動,一種是實際業務自己就有抖動,其餘的好比 Timer、CP 的對齊、GC 等正常現象的發生,還有追數據的場景,開始和追平的時候狀態是不同的,這種狀況下也不用擔憂,有意識地識別這種情況,進而判斷這種是正常仍是非預期情況。

在線上監控時要注意,metrics 過多會對 JVM 形成很大壓力,上報的頻率不要選擇  subtask,這對資源的開銷是很高的。

配置時要注意,一開始儘可能不用 RocksDB 狀態後端,FS 狀態後端的部署成本低速度也更快。少用網絡的文件系統。SlotSharingGroups 的配置儘可能使用默認的,避免引起欠機制的破壞,致使資源浪費。


6. 維護


像 Flink 這樣快節奏的項目,每一個版本都有不少 bug 被修復,及時升級也很重要。

7.PyFlink/SQL/TableAPI 的補充


  1. 使用 TableEnvironment 仍是 StreamTableEnvironment?推薦 TableEnvironment 。(分段優化)

  2. State TTL 未設置,致使 State 無限增加,或者 State TTL 設置不結合業務需求,致使數據正確性問題。

  • 不支持做業升級,例如增長一個 COUNT SUM 會致使做業 state 不兼容。

  • 解析 JSON 時,重複調度 UDF,嚴重影響性能,建議替換成 UDTF。

  • 多流 JOIN 的時候,先作小表 JOIN,再作大表 JOIN。目前,Flink 尚未表的 meta 信息,無法在 plan 優化時自動作 join reorder。


做者簡介:

本文由  Konstantin Knauf 分享 孫金城進行中文解說。

孫金城(金竹,Apache Member, 阿里巴巴高級技術專家。 2011 年加入阿里,9 年的阿里工做中,主導過不少內部核心系統,如,阿里集團行爲日誌,阿里郎,雲轉碼,文檔轉換等。 在 2016 年初開始瞭解 Apache Flink 社區,由初期的參與社區開發到後來逐漸主導具體模塊的開發,到負責 Apache Flink Python API(PyFlink) 的建設。   目前是 PMC member of Apache Flink and ALC(Beijing), 以及 Committer for Apache Flink, Apache Beam and Apache IoTDB。


# 如何提早了解 Flink 1.11 新版功能特性?#

   機會來了 !

6月14日,阿里巴巴計算平臺事業部與阿里雲開發者社區共同舉辦的 大數據+AI Meetup 系列第一季即將重磅開啓 ,這次 Meetup 邀請了來自阿里巴巴、Databricks、快手、網易雲音樂的7位技術專家,集中解讀大數據當前熱門話題!

其中,Apache Flink Committer,阿里巴巴技術專家李勁鬆(之信)將現場分享Flink 1.11 Table&SQL 深度解讀,還有快手春晚項目的獨家實踐、網易雲音樂 Flink + Kafka 的生產落地等。點擊「 閱讀原文 」便可預定報名~

▼ 活動亮點 


> 超豪華嘉賓陣容!多位資深技術專家在線分享對行業趨勢的洞察!

> 極豐富乾貨分享!集結大數據熱門議題,次看完:數據處理、數倉、數據湖、AI 等技術實踐與生產應用落地。

> 多種獎品拿到手軟!直播間已準備超多精美禮品,現場送送送!預定直播並參與互動即有機會領走哦。




點擊「 閱讀原文 」便可預定報名!

本文分享自微信公衆號 - Flink 中文社區(gh_5efd76d10a8d)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索