天天看點

利用 JuiceFS給Flink 容器啟動加速

作者 | 胡夢宇,知乎大資料架構開發工程師

編輯 | Linda

Flink 因為其可靠性和易用性,已經成為目前最流行的流處理架構之一,在流計算領域占據了主導地位。早在 18 年知乎就引入了 Flink,發展到現在,Flink 已經成為知乎内部最重要的元件之一,積累了 4000 多個 Flink 實時任務,每天處理 PB 級的資料。

Flink 的部署方式有多種,根據資源排程器來分類,大緻可分為 standalone、Flink on YARN、Flink on Kubernetes 等。目前知乎内部使用的部署方式是 Flink 官方提供的 native Kubernetes。談到 Kubernetes,就不得不說容器鏡像的問題,因為 Flink 任務的依賴多種多樣,如何給 Flink 打鏡像也是一個比較頭疼的問題。

Flink 鏡像及依賴處理

Flink 的任務大緻可分為兩類,第一類是 Flink SQL 任務,Flink SQL 任務的依賴大緻有以下幾種:

1.官方的 connector JAR 包,如 flink-hive-connector、flink-jdbc-connector、flink-kafka-connector 等;2.非官方或者是内部實作的 connector JAR 包;3.使用者的 UDF JAR 包,一些複雜的計算邏輯,使用者可能會自己實作 UDF。

第二類 Flink 任務是 Flink 的 jar 包任務,除了以上三種依賴,還需要依賴使用者自己寫的 Flink jar 程式包。

顯然,對于每一個 Flink 任務,它的依賴不盡相同,我們也不可能為每一個 Flink 任務單獨打一個鏡像,我們目前的處理如下:

1.将依賴進行分類,分為穩定依賴和非穩定依賴;2.穩定依賴包括元件(如 Flink、JDK 等)以及官方的 connector 包,這類依賴十分穩定,隻會在 Flink 版本更新和 bug 修複這兩種情況下進行改動,是以我們會在建構鏡像時,将這類依賴打入鏡像;3.非穩定依賴包括第三方的 connector 和使用者自己的 JAR 包。第三方的 connector 因為不是 Flink 官方維護,是以出問題需要修複的機率相對更大;使用者自己的 JAR 包對于每個任務來說都不相同,而且使用者會經常改動重新送出。對于這類不穩定的依賴,我們會動态注入,注入的方式是将依賴存入分布式檔案系統,在容器啟動的時候,利用 pre command 下載下傳進容器裡。

經過以上處理,Flink 鏡像具備了一定的動态加載依賴的能力,Flink Job 的啟動流程大緻如下:

利用 JuiceFS給Flink 容器啟動加速

檔案系統選取

HDFS 存放依賴的痛點

存放 Flink 依賴的檔案系統在之前我們一直都是選用的 HDFS, 但是在使用過程中我們遇到了以下痛點:

1.NameNode 在任務高峰期壓力過大,容器在下載下傳依賴時向 NameNode 請求檔案中繼資料會存在卡頓的情況,有些小的批任務,任務本身可能隻需要運作十幾秒,但是因為 NameNode 壓力過大,導緻下載下傳依賴可能需要幾分鐘;2.目前 Flink 叢集我們是多資料中心部署,但是 HDFS 隻有一個離線機房大叢集,這樣會存在跨資料中心拉檔案的情況,消耗專線帶寬;3.有一些特殊的 Flink 任務完全不依賴 HDFS,換句話說它既不使用 checkpoint 也不讀寫 HDFS,但是因為 Flink 容器的依賴存放在 HDFS 上,導緻這類任務依然離不開 HDFS。

使用對象存儲的痛點

後面我們将 HDFS 換成了對象存儲,解決了 HDFS 的一些痛點,但是很快我們發現了新的問題 — 對象存儲單線程下載下傳的速度慢。對象存儲下載下傳加速可選的方案一般有以下幾種:

1.使用多線程下載下傳進行分段下載下傳,但是容器的 pre command 其實隻适合執行一些比較簡單的 shell 指令,如果采用分段下載下傳,就必須對這一塊進行比較大的改造,這是一個比較大的痛點;2.給對象存儲加代理層做緩存,加速的事情由代理來做,用戶端依然可以單線程讀取。這種辦法的缺點是需要額外維護一個對象存儲的代理元件,元件的穩定性也需要有保障。

嘗試 JuiceFS

比較湊巧的是公司内部正在做 JuiceFS 的 POC, 有現成的對象存儲代理層可用,我們對其進行了一系列測試,發現 JuiceFS 完全滿足我們這個場景的需求,讓我們比較驚喜的地方有以下幾點:

1.JuiceFS 自帶 S3 gateway 完美相容 S3 對象存儲協定,能夠讓我們很快上線,無需任何改動,并且 S3 gateway 本身無狀态,擴縮容非常友善;2.JuiceFS 自帶緩存加速功能,經過測試,用 JuiceFS 代理對象存儲後,單線程讀取檔案的速度是原來的 4 倍;3.JuiceFS 提供本地檔案系統挂載的方式,後面可以嘗試依賴直接挂載進容器目錄;4.JuiceFS 可選用中繼資料與存儲分離部署的方式,存儲我們選用原來的對象存儲,雲廠商保證 11 個 9 的可用性;中繼資料我們選用分布式 KV 系統—TiKV,選用 TiKV 的原因是我們線上架構組的同僚對 TiKV 有着豐富的開發和運維經驗,SLA 能夠得到極大的保障。這樣 JuiceFS 的可用性和擴充性是非常強的。

JuiceFS 上線

JuiceFS 的上線過程分為以下階段:

1.資料遷移,我們需要将原先存儲在 HDFS 和對象存儲上的資料同步到 JuiceFS 上,因為 JuiceFS 提供了資料同步的工具,并且 Flink 的依賴也不是特别大,是以這部分工作我們很快就完成了;2.修改 Flink 鏡像拉取依賴的位址,因為 JuiceFS 相容對象存儲協定,我們隻需要在平台側修改原來的對象存儲的 endpoint 為 JuiceFS S3 gateway 的位址即可。

JuiceFS 上線後,我們 Flink 任務啟動的流程圖大緻如下:

利用 JuiceFS給Flink 容器啟動加速

相比于使用 HDFS 的方式,我們能得到一個可預期的容器啟動時間,容器下載下傳依賴的速度不會受業務高峰期的影響;相比于原生的對象存儲,容器下載下傳依賴的速度提高約 4 倍。

展 望

從開始調研 JuiceFS 到 JuiceFS 上線花費時間不到半個月,主要是因為 JuiceFS 的文檔十分完備,讓我們少走了很多彎路,其次是 JuiceFS 社群的夥伴也有問必答,是以我們的上線過程十分順利。

初步嘗試 JuiceFS 給我們帶來的收益還是比較明顯的,後續我們會考慮将 JuiceFS 應用在資料湖場景和算法模型加載的場景,讓我們資料的使用更加靈活和高效。

作者介紹:

胡夢宇,知乎大資料架構開發工程師,主要負責知乎内部大資料元件的二次開發和資料平台建設。

繼續閱讀