溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Apache Flink 誤用的是示例分析

發(fā)布時(shí)間:2021-12-27 09:40:09 來(lái)源:億速云 閱讀:160 作者:柒染 欄目:大數(shù)據(jù)

Apache Flink 誤用的是示例分析,針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。

摘要: 下面根據(jù) Flink Forward 全球在線會(huì)議 · 中文精華版整理而成, 圍繞著項(xiàng)目的 開(kāi)始、需求分析、開(kāi)發(fā), 以及測(cè)試、上線、運(yùn)維整個(gè)生命周期展開(kāi),介紹了 Apache Flink 實(shí)踐中的一些典型誤用情況,并給出了相應(yīng)的更優(yōu)實(shí)踐方案。                    
                 
Flink 實(shí)踐中最首當(dāng)其沖的誤用就是不按迭代開(kāi)發(fā)的過(guò)程操作。  


1. 項(xiàng)目開(kāi)始


在開(kāi)始開(kāi)發(fā)前,我們需要選擇正確的切入方式,以下幾種往往是最糟糕的開(kāi)始:

    a) 從一個(gè)具有挑戰(zhàn)性的用例開(kāi)始(端對(duì)端的 Exactly-once、大狀態(tài)、復(fù)雜的業(yè)務(wù)邏輯、強(qiáng)實(shí)時(shí)SLA的組合)       
    b) 之前沒(méi)有流處理經(jīng)驗(yàn)       
    c) 不對(duì)團(tuán)隊(duì)做相關(guān)的培訓(xùn)       
    d) 不利用社區(qū)

在開(kāi)發(fā)的過(guò)程中,其實(shí)要認(rèn)認(rèn)真真的來(lái)規(guī)劃我們的切入點(diǎn),首先,要從簡(jiǎn)單的任務(wù)開(kāi)始循序漸進(jìn)。要有一定的大數(shù)據(jù)和流處理的知識(shí)積累,盡量參加一些培訓(xùn),也要利用好社區(qū)資源?;谶@樣的想法,我們就能很快找到切入點(diǎn)。

怎么樣去做?社區(qū)提供了很多的培訓(xùn),包括 Flink Forward 和 Vererica 網(wǎng)站上有各種培訓(xùn)課程,大家可以去看。同時(shí),可以充分利用社區(qū)。社區(qū)還建立了中文的郵件列表,大家可以充分利用中文郵件列表來(lái)解決手頭的疑難雜癥。另外,Stack Overflow 也是個(gè)提問(wèn)的好地方,但在提問(wèn)前盡量去看一看已有的提問(wèn),做到心中有數(shù)。

  • 郵件列表:

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

  • Stack Overflow:

    www.stackoverflow.com


2. 設(shè)計(jì)分析


方案設(shè)計(jì)中的一些常見(jiàn)錯(cuò)誤思維,往往是由于沒(méi)有充分思考需求導(dǎo)致的,比如:

    a) 不考慮數(shù)據(jù)一致性和交付保證       
    b) 不考慮業(yè)務(wù)升級(jí)和應(yīng)用改進(jìn)       
    c) 不考慮業(yè)務(wù)規(guī)模問(wèn)題       
    d) 不深入思考實(shí)際業(yè)務(wù)需求
我們要認(rèn)真分析需求,同時(shí)認(rèn)真考慮實(shí)際交付情況。提到一致性和交付保障,其實(shí)可以通過(guò)幾個(gè)問(wèn)題來(lái)引導(dǎo)大家完成這件事,如下圖所示:

Apache Flink 誤用的是示例分析

第1個(gè)問(wèn)題,是否在乎數(shù)據(jù)的丟失?

 如  果不在乎,你可以沒(méi)有 Checkpoint。

 第2個(gè)問(wèn)題,是否在乎結(jié)果的正確性?

 在很多的場(chǎng)景里面,我們非常關(guān)注結(jié)果的正確性,比如金融領(lǐng)域,但是另外一些場(chǎng)景比如監(jiān)控或其他簡(jiǎn)單的使用場(chǎng)景僅需要一個(gè)概要的數(shù)據(jù)統(tǒng)計(jì)。如果不在乎結(jié)果的正確性,  可以考慮用 at-least-once 的模式配置并使用可回放的數(shù)據(jù)源。相反,如果  結(jié)果的準(zhǔn)確性十分重要,且下游不關(guān)心重復(fù)記錄,那么僅需設(shè)置 exactly-once 模式并使用可回放的數(shù)據(jù)源。  如果下游要求數(shù)據(jù)不能重復(fù),哪怕數(shù)據(jù)正確也只能發(fā)送一次,這種時(shí)候就對(duì) sink 有更進(jìn)一步的限制,在 exactly-once 的模式下,使用可回放的數(shù)據(jù)源,并且 sink 需要支持事務(wù)。

帶著這樣的思維方式分析業(yè)務(wù),才能非常清晰地知道,怎么去使用 Flink,進(jìn)而避免一些糟糕的事情發(fā)生。

完成分析之后,最終目的是什么?  我們?yōu)槭裁匆羞@種選擇,而不是一上來(lái)就選一個(gè)最好的方案?

 因?yàn)槭澜缟嫌肋h(yuǎn)沒(méi)有“最好”,這里的核心因素就是延遲,要根據(jù)業(yè)務(wù)的延遲和準(zhǔn)確性需求來(lái)均衡去做選擇。

當(dāng)需求都分析好之后,還需要去思考應(yīng)用是否需要升級(jí)。從一個(gè)正常的 Flink 作業(yè)來(lái)講,我們有幾個(gè)問(wèn)題要考慮。第一個(gè),F(xiàn)link 作業(yè)一般都有狀態(tài)讀取,做升級(jí)時(shí)需要有 savepoint 機(jī)制來(lái)保障,將狀態(tài)存儲(chǔ)保留在遠(yuǎn)端,再恢復(fù)到新的作業(yè)上去。很多場(chǎng)景下都會(huì)有升級(jí)的需求,這簡(jiǎn)單列了幾點(diǎn):

a 升級(jí)集群版本   
b 業(yè)務(wù) bug 的修復(fù)
c 業(yè)務(wù)邏輯(拓?fù)洌┑淖兏?/pre> 
 

在比較復(fù)雜的場(chǎng)景下,作業(yè)會(huì)有拓?fù)涞淖兓?,如下圖:

Apache Flink 誤用的是示例分析

此處需要添加一個(gè)算子,去掉一個(gè) sink 。對(duì)于這樣的變化,我們要考慮狀態(tài)的恢復(fù)。當(dāng) Flink 發(fā)現(xiàn)新作業(yè)有節(jié)點(diǎn)沒(méi)了,對(duì)應(yīng)的狀態(tài)無(wú)法恢復(fù),就會(huì)拋出異常導(dǎo)致升級(jí)失敗。這時(shí)候可以使用參數(shù) --allowNonRestoreState 來(lái)忽略此類問(wèn)題。

另外新作業(yè)中還有新建的節(jié)點(diǎn),這個(gè)節(jié)點(diǎn)就用空狀態(tài)去初始化即可。除此之外,還需要注意,為了保證作業(yè)成功啟動(dòng)并且狀態(tài)恢復(fù)不受影響,我們應(yīng)該為算子設(shè)置 StreamAPI 中的 uid 。當(dāng)然,如果狀態(tài)的結(jié)構(gòu)發(fā)生了變化,Avro Types 和 POJO 的類型都是支持的,Kryo 是不支持的。最后建議所有 key 的類型盡量不要修改,因?yàn)檫@會(huì)涉及 shuffle 和 狀態(tài)的正確性。

資源的使用情況也是必須要考慮的因素之一,下面是一個(gè)評(píng)估內(nèi)存和網(wǎng)絡(luò) IO 使用的思路。這里我們假設(shè)使用的是 Fs State,所有運(yùn)行時(shí)狀態(tài)都在內(nèi)存中。不恰當(dāng)?shù)馁Y源配置可能會(huì)造成 OOM 等嚴(yán)重的問(wèn)題。

Apache Flink 誤用的是示例分析

完成資源評(píng)估后,還需要考慮事件時(shí)間和亂序問(wèn)題。下面是一個(gè)具體的例子:

Apache Flink 誤用的是示例分析

在這個(gè)例子中選擇哪種時(shí)間窗口、何時(shí)觸發(fā)計(jì)算,僅憑一句話的需求是無(wú)法描述清楚的。只有根據(jù)流處理的特性結(jié)合實(shí)際的業(yè)務(wù)去認(rèn)真分析需求,才能將 Flink 技術(shù)進(jìn)行恰當(dāng)?shù)倪\(yùn)用。

還需要注意,F(xiàn)link 是流批統(tǒng)一的計(jì)算引擎,不是所有的業(yè)務(wù)都能用流處理或者都能用批處理來(lái)實(shí)現(xiàn),需要分析自己的場(chǎng)景適合用哪種方式來(lái)實(shí)現(xiàn)。  

3. 開(kāi)發(fā)



3.1 API 的選擇  

在 DataStream API 和 Table API/SQL 的選擇上,如果有強(qiáng)烈的需求控制狀態(tài)和每條狀態(tài)到來(lái)的行為,要使用 DataStream API;如果是簡(jiǎn)單的數(shù)據(jù)提取和關(guān)系代數(shù)的運(yùn)算,可以選擇 Table API/SQL。在一些場(chǎng)景下,只能選擇 DataStream API:

a) 在升級(jí)過(guò)程中要改變狀態(tài)
b) 不能丟失遲到的數(shù)據(jù)
c) 在運(yùn)行時(shí)更改程序的行為
     

3.2 數(shù)據(jù)類型


在開(kāi)發(fā)過(guò)程中,關(guān)于數(shù)據(jù)類型,有兩種誤用場(chǎng)景:


a) 使用深度嵌套的復(fù)雜數(shù)據(jù)類型b) KeySelector 中使用任意類型

正確的做法是選擇盡可能簡(jiǎn)單的狀態(tài)類型,在 KeySelector 中不使用 Flink 不能自動(dòng)識(shí)別的類型。


3.3 序列化


數(shù)據(jù)類型越簡(jiǎn)單越好,基于序列化成本的考慮,盡量使用 POJO 和 Avro SpecificRecords。也鼓勵(lì)大家開(kāi)發(fā)完使用 IDE 的工具本地調(diào)試一下,看一下性能瓶頸在哪。

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

圖5中是一種效率較低的處理過(guò)程,我們應(yīng)該先進(jìn)行過(guò)濾和投影操作,防止不需要的數(shù)據(jù)進(jìn)行多余的處理。

Apache Flink 誤用的是示例分析



3.4 并發(fā)性


兩種誤用場(chǎng)景及相應(yīng)容易造成的問(wèn)題:

  • 任務(wù)之間共享靜態(tài)變量


容易引起 bug;容易造成死鎖和競(jìng)爭(zhēng)問(wèn)題;帶來(lái)額外的同步開(kāi)銷。

  • 在用戶函數(shù)中生成線程


檢查點(diǎn)變得復(fù)雜易錯(cuò)。

對(duì)于想用線程的情況,如果是需要加速作業(yè),可以調(diào)整并行度和資源,使用異步IO;如果是需要一些定時(shí)任務(wù)的觸發(fā),可以使用 Flink 自帶的 Timer 定時(shí)調(diào)度任務(wù)。


3.5 窗口


盡量避免像圖6這樣自定義 Window,使用 KeyedProcessFunction 可以使得實(shí)現(xiàn)更加簡(jiǎn)單和穩(wěn)定。

Apache Flink 誤用的是示例分析

另外,也要避免圖7中的這種滑動(dòng)窗口,在圖7中每個(gè)記錄被50萬(wàn)個(gè)窗口計(jì)算,無(wú)論是計(jì)算資源還是業(yè)務(wù)延遲都會(huì)非常糟糕。

Apache Flink 誤用的是示例分析

3.6 可查詢狀態(tài)  

Queryable State 目前還在不斷的完善中,可以用于監(jiān)控和查詢,但在實(shí)際投產(chǎn)時(shí)還是有一些問(wèn)題需要注意的,比如對(duì)于線程安全訪問(wèn),RocksDB 狀態(tài)后端是支持的,而 FS 狀態(tài)后端是不支持的,另外還有性能和一致性保障等問(wèn)題需要注意。

3.7 DataStream API 的應(yīng)用  

對(duì)圖8這種場(chǎng)景,可以使用 DataStreamUtils#reinterpretAsKeyedStream 這個(gè)方法,避免面對(duì)相同的 key 進(jìn)行多次 shuffle 。

Apache Flink 誤用的是示例分析

對(duì)圖9這種場(chǎng)景,應(yīng)該把一些初始化的邏輯寫(xiě)在 RichFunction 的 open 方法里。

Apache Flink 誤用的是示例分析


4. 測(cè)試

Apache Flink 誤用的是示例分析

除了系統(tǒng)測(cè)試和 UDF 的單元測(cè)試,還應(yīng)該做 Mini Cluster 測(cè)試,在本機(jī)運(yùn)行一個(gè) Mini Cluster 把端到端的業(yè)務(wù)跑起來(lái),可以及早地發(fā)現(xiàn)一些問(wèn)題。

還有 Harness 測(cè)試,它可以精準(zhǔn)地幫助完成有狀態(tài)的任務(wù)測(cè)試。它可以精準(zhǔn)的控制 watermark、元素的 event time 等。可以參考:

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


5. 上線


很多場(chǎng)景會(huì)導(dǎo)致業(yè)務(wù)抖動(dòng),一種是實(shí)際業(yè)務(wù)本身就有抖動(dòng),其他的比如 Timer、CP 的對(duì)齊、GC 等正?,F(xiàn)象的發(fā)生,還有追數(shù)據(jù)的場(chǎng)景,開(kāi)始和追平的時(shí)候狀態(tài)是不一樣的,這種情況下也不用擔(dān)心,有意識(shí)地識(shí)別這種狀況,進(jìn)而判斷這種是正常還是非預(yù)期狀況。

在線上監(jiān)控時(shí)要注意,metrics 過(guò)多會(huì)對(duì) JVM 造成很大壓力,上報(bào)的頻率不要選擇  subtask,這對(duì)資源的開(kāi)銷是很高的。

配置時(shí)要注意,一開(kāi)始盡量不用 RocksDB 狀態(tài)后端,F(xiàn)S 狀態(tài)后端的部署成本低速度也更快。少用網(wǎng)絡(luò)的文件系統(tǒng)。SlotSharingGroups 的配置盡量使用默認(rèn)的,避免引發(fā)欠機(jī)制的破壞,導(dǎo)致資源浪費(fèi)。


6. 維護(hù)


像 Flink 這樣快節(jié)奏的項(xiàng)目,每個(gè)版本都有很多 bug 被修復(fù),及時(shí)升級(jí)也很重要。

7.PyFlink/SQL/TableAPI 的補(bǔ)充


  1. 使用 TableEnvironment 還是 StreamTableEnvironment?推薦 TableEnvironment 。(分段優(yōu)化)

  2. State TTL 未設(shè)置,導(dǎo)致 State 無(wú)限增長(zhǎng),或者 State TTL 設(shè)置不結(jié)合業(yè)務(wù)需求,導(dǎo)致數(shù)據(jù)正確性問(wèn)題。

  • 不支持作業(yè)升級(jí),例如增加一個(gè) COUNT SUM 會(huì)導(dǎo)致作業(yè) state 不兼容。

  • 解析 JSON 時(shí),重復(fù)調(diào)度 UDF,嚴(yán)重影響性能,建議替換成 UDTF。

  • 多流 JOIN 的時(shí)候,先做小表 JOIN,再做大表 JOIN。目前,F(xiàn)link 還沒(méi)有表的 meta 信息,沒(méi)法在 plan 優(yōu)化時(shí)自動(dòng)做 join reorder。

關(guān)于Apache Flink 誤用的是示例分析問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開(kāi),可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識(shí)。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI