溫馨提示×

溫馨提示×

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

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

解決Flink反壓的方法有哪些?

發(fā)布時間:2020-05-27 11:50:14 來源:億速云 閱讀:1823 作者:鴿子 欄目:開發(fā)技術(shù)

要解決反壓首先要做的是定位到造成反壓的節(jié)點,這主要有兩種辦法:

  1. 通過 Flink Web UI 自帶的反壓監(jiān)控面板;
  2. 通過 Flink Task Metrics。

前者比較容易上手,適合簡單分析,后者則提供了更加豐富的信息,適合用于監(jiān)控系統(tǒng)。因為反壓會向上游傳導(dǎo),這兩種方式都要求我們從 Source 節(jié)點到 Sink 的逐一排查,直到找到造成反壓的根源原因[4]。下面分別介紹這兩種辦法。

反壓監(jiān)控面板

Flink Web UI 的反壓監(jiān)控提供了 SubTask 級別的反壓監(jiān)控,原理是通過周期性對 Task 線程的棧信息采樣,得到線程被阻塞在請求 Buffer(意味著被下游隊列阻塞)的頻率來判斷該節(jié)點是否處于反壓狀態(tài)。默認配置下,這個頻率在 0.1 以下則為 OK,0.1 至 0.5 為 LOW,而超過 0.5 則為 HIGH。

如果處于反壓狀態(tài),那么有兩種可能性:

  1. 該節(jié)點的發(fā)送速率跟不上它的產(chǎn)生數(shù)據(jù)速率。這一般會發(fā)生在一條輸入多條輸出的 Operator(比如 flatmap)。
  2. 下游的節(jié)點接受速率較慢,通過反壓機制限制了該節(jié)點的發(fā)送速率。

如果是第一種狀況,那么該節(jié)點則為反壓的根源節(jié)點,它是從 Source Task 到 Sink Task 的第一個出現(xiàn)反壓的節(jié)點。如果是第二種情況,則需要繼續(xù)排查下游節(jié)點。

值得注意的是,反壓的根源節(jié)點并不一定會在反壓面板體現(xiàn)出高反壓,因為反壓面板監(jiān)控的是發(fā)送端,如果某個節(jié)點是性能瓶頸并不會導(dǎo)致它本身出現(xiàn)高反壓,而是導(dǎo)致它的上游出現(xiàn)高反壓??傮w來看,如果我們找到第一個出現(xiàn)反壓的節(jié)點,那么反壓根源要么是就這個節(jié)點,要么是它緊接著的下游節(jié)點。

那么如果區(qū)分這兩種狀態(tài)呢?很遺憾只通過反壓面板是無法直接判斷的,我們還需要結(jié)合 Metrics 或者其他監(jiān)控手段來定位。此外如果作業(yè)的節(jié)點數(shù)很多或者并行度很大,由于要采集所有 Task 的棧信息,反壓面板的壓力也會很大甚至不可用。

Task Metrics

Flink 提供的 Task Metrics 是更好的反壓監(jiān)控手段,但也要求更加豐富的背景知識。

首先我們簡單回顧下 Flink 1.5 以后的網(wǎng)路棧,熟悉的讀者可以直接跳過。

TaskManager 傳輸數(shù)據(jù)時,不同的 TaskManager 上的兩個 Subtask 間通常根據(jù) key 的數(shù)量有多個 Channel,這些 Channel 會復(fù)用同一個 TaskManager 級別的 TCP 鏈接,并且共享接收端 Subtask 級別的 Buffer Pool。

在接收端,每個 Channel 在初始階段會被分配固定數(shù)量的 Exclusive Buffer,這些 Buffer 會被用于存儲接受到的數(shù)據(jù),交給 Operator 使用后再次被釋放。Channel 接收端空閑的 Buffer 數(shù)量稱為 Credit,Credit 會被定時同步給發(fā)送端被后者用于決定發(fā)送多少個 Buffer 的數(shù)據(jù)。

在流量較大時,Channel 的 Exclusive Buffer 可能會被寫滿,此時 Flink 會向 Buffer Pool 申請剩余的 Floating Buffer。這些 Floating Buffer 屬于備用 Buffer,哪個 Channel 需要就去哪里。而在 Channel 發(fā)送端,一個 Subtask 所有的 Channel 會共享同一個 Buffer Pool,這邊就沒有區(qū)分 Exclusive Buffer 和 Floating Buffer。

我們在監(jiān)控反壓時會用到的 Metrics 主要和 Channel 接受端的 Buffer 使用率有關(guān),最為有用的是以下幾個 Metrics:

Metris

描述

outPoolUsage

發(fā)送端 Buffer 的使用率

inPoolUsage

接收端 Buffer 的使用率

floatingBuffersUsage(1.9 以上)

接收端 Floating Buffer 的使用率

exclusiveBuffersUsage (1.9 以上)

接收端 Exclusive Buffer 的使用率

其中 inPoolUsage 等于 floatingBuffersUsage 與 exclusiveBuffersUsage 的總和。

分析反壓的大致思路是:如果一個 Subtask 的發(fā)送端 Buffer 占用率很高,則表明它被下游反壓限速了;如果一個 Subtask 的接受端 Buffer 占用很高,則表明它將反壓傳導(dǎo)至上游。反壓情況可以根據(jù)以下表格進行對號入座(圖片來自官網(wǎng)):

outPoolUsage 和 inPoolUsage 同為低或同為高分別表明當前 Subtask 正常或處于被下游反壓,這應(yīng)該沒有太多疑問。而比較有趣的是當 outPoolUsage 和 inPoolUsage 表現(xiàn)不同時,這可能是出于反壓傳導(dǎo)的中間狀態(tài)或者表明該 Subtask 就是反壓的根源。

如果一個 Subtask 的 outPoolUsage 是高,通常是被下游 Task 所影響,所以可以排查它本身是反壓根源的可能性。如果一個 Subtask 的 outPoolUsage 是低,但其 inPoolUsage 是高,則表明它有可能是反壓的根源。因為通常反壓會傳導(dǎo)至其上游,導(dǎo)致上游某些 Subtask 的 outPoolUsage 為高,我們可以根據(jù)這點來進一步判斷。值得注意的是,反壓有時是短暫的且影響不大,比如來自某個 Channel 的短暫網(wǎng)絡(luò)延遲或者 TaskManager 的正常 GC,這種情況下我們可以不用處理。

對于 Flink 1.9 及以上版本,除了上述的表格,我們還可以根據(jù) floatingBuffersUsage/exclusiveBuffersUsage 以及其上游 Task 的 outPoolUsage 來進行進一步的分析一個 Subtask 和其上游 Subtask 的數(shù)據(jù)傳輸。
通常來說,floatingBuffersUsage 為高則表明反壓正在傳導(dǎo)至上游,而 exclusiveBuffersUsage 則表明了反壓是否存在傾斜(floatingBuffersUsage 高、exclusiveBuffersUsage 低為有傾斜,因為少數(shù) channel 占用了大部分的 Floating Buffer)。

至此,我們已經(jīng)有比較豐富的手段定位反壓的根源是出現(xiàn)在哪個節(jié)點,但是具體的原因還沒有辦法找到。另外基于網(wǎng)絡(luò)的反壓 metrics 并不能定位到具體的 Operator,只能定位到 Task。特別是 embarrassingly parallel(易并行)的作業(yè)(所有的 Operator 會被放入一個 Task,因此只有一個節(jié)點),反壓 metrics 則派不上用場。

分析具體原因及處理


定位到反壓節(jié)點后,分析造成原因的辦法和我們分析一個普通程序的性能瓶頸的辦法是十分類似的,可能還要更簡單一點,因為我們要觀察的主要是 Task Thread。

在實踐中,很多情況下的反壓是由于數(shù)據(jù)傾斜造成的,這點我們可以通過 Web UI 各個 SubTask 的 Records Sent 和 Record Received 來確認,另外 Checkpoint detail 里不同 SubTask 的 State size 也是一個分析數(shù)據(jù)傾斜的有用指標。

此外,最常見的問題可能是用戶代碼的執(zhí)行效率問題(頻繁被阻塞或者性能問題)。最有用的辦法就是對 TaskManager 進行 CPU profile,從中我們可以分析到 Task Thread 是否跑滿一個 CPU 核:如果是的話要分析 CPU 主要花費在哪些函數(shù)里面,比如我們生產(chǎn)環(huán)境中就偶爾遇到卡在 Regex 的用戶函數(shù)(ReDoS);如果不是的話要看 Task Thread 阻塞在哪里,可能是用戶函數(shù)本身有些同步的調(diào)用,可能是 checkpoint 或者 GC 等系統(tǒng)活動導(dǎo)致的暫時系統(tǒng)暫停。

當然,性能分析的結(jié)果也可能是正常的,只是作業(yè)申請的資源不足而導(dǎo)致了反壓,這就通常要求拓展并行度。值得一提的,在未來的版本 Flink 將會直接在 WebUI 提供 JVM 的 CPU 火焰圖[5],這將大大簡化性能瓶頸的分析。

另外 TaskManager 的內(nèi)存以及 GC 問題也可能會導(dǎo)致反壓,包括 TaskManager JVM 各區(qū)內(nèi)存不合理導(dǎo)致的頻繁 Full GC 甚至失聯(lián)。推薦可以通過給 TaskManager 啟用 G1 垃圾回收器來優(yōu)化 GC,并加上 -XX:+PrintGCDetails 來打印 GC 日志的方式來觀察 GC 的問題。

總結(jié)
--

反壓是 Flink 應(yīng)用運維中常見的問題,它不僅意味著性能瓶頸還可能導(dǎo)致作業(yè)的不穩(wěn)定性。定位反壓可以從 Web UI 的反壓監(jiān)控面板和 Task Metric 兩者入手,前者方便簡單分析,后者適合深入挖掘。定位到反壓節(jié)點后我們可以通過數(shù)據(jù)分布、CPU Profile 和 GC 指標日志等手段來進一步分析反壓背后的具體原因并進行針對性的優(yōu)化。

向AI問一下細節(jié)

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

AI