摘要:反壓是 Flink 應用運維中常見的問題,它不僅意味着性能瓶頸還可能導致作業的不穩定性。
反壓(backpressure)是實時計算應用開發中,特別是流式計算中,十分常見的問題。反壓意味着數據管道中某個節點成為瓶頸,處理速率跟不上上游發送數據的速率,而需要對上游進行限速。
問題場景
客戶作業場景如下圖所示,從DMS kafka通過DLI Flink將業務數據實時清洗存儲到DWS。
其中,DMS Kafka 目標Topic 6個分區,DLI Flink作業配置taskmanager數量為12,並發數為1。
問題現象
客戶在DLI服務共有三個相同規格的隊列,該作業在其中003號隊列上運行正常,在001和002號隊列上都存在嚴重的反壓導致數據處理緩慢。作業列表顯示如下圖,可以看到Sink反壓狀態正常,Souce和Map反壓狀態為HIGH。
問題分析
根據反壓情況分析,該作業的性能瓶頸在Sink,由於Sink處理數據緩慢導致上游反壓嚴重。
該作業所定義的Sink類型為DwsCsvSink,該Sink的工作原理如下圖所示:Sink將結果數據分片寫入到OBS,每一分片寫入完成后,調用DWS insert select sql將obs路徑下該分片數據load到dws。
因此性能瓶頸出現在分片數據寫入到OBS這一步。但問題來了,寫同一個桶,為什么在不同隊列上的表現不一致?
為此,我們排查了各個隊列的CPU、內存和網絡帶寬情況,結果顯示負載都很低。
這種情況下,只能繼續分析FlinkUI和TaskManager日志。
數據傾斜?
然后我們在FlinkUI任務情況頁面,看到如下情況:Map階段的12個TaskManager並不是所有反壓都很嚴重,而是只有一半是HIGH狀態,難道有數據傾斜導致分配到不同TaskManager的數據不均勻?
然后看Source subTask詳情,發現有兩個TaskManager讀取的數據量是其他幾個的幾十倍,這說明源端Kafka分區流入的數據量不均勻。難道就是這么簡單的問題?
很不幸並不是,通過進一步分析源端數據我們發現Kafka 6個分區數據流入記錄數相差並不大。這兩個Task只是多消費了部分存量數據,接收數據增長的速度各TaskManager保持一致。
時鍾同步
進一步分析TaskManager日志,我們發現單個分片數據寫入OBS竟然耗費3min以上。這非常異常,要知道單個分片數據才500000條而已。
進一步通過分析代碼發現如下問題:在寫OBS數據時,其中一個taskmanager寫分片目錄后獲取該目錄的最后修改時間,作為處理該分片的開始時間,該時間為OBS服務端的時間。
后續其他taskmanager向該分片目錄寫數據時,會獲取本地時間與分片開始時間對比,間隔大於所規定的轉儲周期才會寫分片數據。
如果集群節點NTP時間與OBS服務端不同步,本地時間晚於OBS服務端時間,則會造成寫入OBS等待。
后續排查集群節點,發現6個節點中一半時間同步有問題,這也和只有一半taskmanager反壓嚴重的現象相對應。
問題修復
在集群節點上執行如下命令,強制時間同步。
systemctl stop ntp
ntpdate ntp.myhuaweicloud.com
systemctl start ntp
systemctl status ntp
date
NTP同步后,作業反壓很快消失,故障恢復。
本文分享自華為雲社區《一個Flink作業反壓的問題分析》,原文作者:Yunz Bao 。