分享一個Flink checkpoint失敗的問題和解決辦法

本文來自: PerfMa技術社區

PerfMa(笨馬網絡)官網node

接觸Flink一段時間了,遇到了一些問題,其中有一個checkpoint失敗致使做業重啓的問題,遇到了不少次,重啓以後通常也能恢復正常,沒有太在乎,最近2天有同事又頻繁遇到,這裏記錄一下解決方案和分析過程。web

咱們的flink測試環境有3個節點,部署架構是每一個flink節點上部署一個HDFS的DataNode節點,hdfs用於flink的checkpoint和savepointapache

現象

image.png

看日誌是說有個3個datanode活着,文件副本是1,可是寫文件失敗網絡

There are 3 datanode(s) running and no node(s) are excluded

網上搜了一下這種報錯,沒有直接的答案,我看了下namenode的日誌,沒有更多直接的信息架構

50070 web ui上看一切正常,datanode的剩餘空間都還有不少,使用率不到10%併發

我試了一下往hdfs上put一個文件再get下來,都ok,說明hdfs服務沒有問題,datanode也是通的分佈式

日誌現象1

繼續先後翻了一下namenode的日誌,注意到有一些warning信息,
image.png
這時候懷疑塊放置策略有問題oop

按照日誌提示打開相應的的debug開關
修改學習

etc/hadoop/log4j.properties

找到測試

log4j.logger.org.apache.hadoop.fs.s3a.S3AFileSystem=WARN

照抄這個格式,在下面添加

log4j.logger.org.apache.hadoop.hdfs.server.blockmanagement.BlockPlacementPolicy=DEBUG
log4j.logger.org.apache.hadoop.hdfs.server.blockmanagement.DatanodeDescriptor=DEBUG
log4j.logger.org.apache.hadoop.net.NetworkTopology=DEBUG

重啓namenode,而後重跑flink做業

日誌現象2

image.png

這時候看到的問題是機架感知策略沒法知足,由於咱們沒有提供機架映射腳本,默認同一個機架,可是仔細想一想跟這個應該也沒有關係

由於不少生產環境的hdfs其實都不配置機架映射腳本,而且致使checkpoint失敗的問題並非一直存在,最起碼put/get文件都是正常的。

這時候開始考慮看一下hdfs的源碼了,根據上面的日誌調用棧,先看到BlockPlacementPolicyDefault以及相關的DatanodeDescriptor

這些源碼大體的意思是當給一個塊選擇一個datanode的時候,要對這個datanode進行一些檢查,好比看下剩餘空間,看下繁忙程度

當咱們的問題復現的時候,觀察日誌會發現一些與此相關的關鍵信息

image.png

image.png

這個日誌的意思是,存儲空間有43G,分配塊實際須要100多M,可是scheduled大小就超過43G,所以咱們認爲正常的datanode,namenode認爲它空間不足了

緣由

scheduled大小含義是什麼呢? 根據代碼能夠看到scheduled大小是塊大小跟一個計數器作乘法,計數器表明的實際上是新建文件塊數量計數器,hdfs根據這兩個參數評估可能須要的存儲空間,至關於給每一個datanode預約了必定的空間,預約的空間在文件寫入後,計算完真實的佔用空間後,還會調整回來。

瞭解這個原理以後,能夠判斷的是datanode在一段時間內被預約了太多的空間。

flink的checkpoint機制能夠參考這一篇https://www.jianshu.com/p/9c5...
大體的意思是taskmanager上的不少任務線程都會寫hdfs

看了下hdfs的目錄結構,有大量的相似uuid命名checkpoint文件,同時每一個文件都很小

image.png

當咱們的做業併發較大時,相應的在hdfs上就會建立更多的checkpoint文件,儘管咱們的文件大小隻有幾K,可是在每個datanode預約的空間都是128M乘以分配到的文件數量(文件很小,不超過128M),那麼43G的空間,最多預約多少文件呢?除一下也就是300多個,三個節點也就是最多900個,咱們有多個做業,總併發較大,在預留空間徹底釋放前,是很容易出現這個問題的。

以前知道hdfs不適合存儲小文件,緣由是大量小文件會致使inode消耗以及block location這些元數據增加,讓namenode內存吃緊,這個例子還代表
當blocksize設置較大,文件大小卻遠小於blocksize時,大量這種小文件會致使datanode直接"不可用"。

解決辦法

塊大小不是集羣屬性,是文件屬性,客戶端能夠設置的,flink這時候每一個taskmanager和jobmanager都是hdfs的"客戶端",根據flink文檔,咱們能夠作以下配置
一、在conf/flink-conf.yaml中指定一個hdfs的配置文件路徑

fs.hdfs.hadoopconf: /home/xxxx/flink/conf

這裏跟flink的配置文件路徑選擇同一個目錄

二、放進去2個配置文件,一個core-site.xml一個是hdfs-site.xml

core-site.xml能夠不放,若是checkpoint和savepoint指定了具體的hdfs地址的話,
image.png

hdfs-site.xml里加上blockSize配置便可,好比這裏咱們給它設置爲1M
image.png

具體塊大小如何設置,須要觀察本身的做業狀態文件大小本身靈活調整。

重啓flink集羣,提交做業便可,運行時能夠觀察下hdfs的fsimage大小,注意不要由於塊過小,小文件太多致使元數據過大。

小結

咱們已經將該問題同步到集羣自動化部署腳本中,部署時會專門添加blocksize的配置。

flink這套依賴hdfs的checkpoint方案對於輕量級的流計算場景稍顯臃腫,checkpoint的分佈式存儲不論是直接filesystem仍是rocksDB都須要hdfs,其實從checkpoint原理和數據類型考慮,es應該也是不錯的選擇,遺憾的是社區並無提供這種方案。

一塊兒來學習吧

PerfMa KO 系列課之 JVM 參數【Memory篇】

一次StackOverflowError排查,緣由居然和Dubbo有關!

相關文章
相關標籤/搜索