Flink1.10Container環(huán)境怎么配置

這篇文章主要介紹“Flink 1.10Container環(huán)境怎么配置”,在日常操作中,相信很多人在Flink 1.10Container環(huán)境怎么配置問題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”Flink 1.10Container環(huán)境怎么配置”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!

公司主營(yíng)業(yè)務(wù):網(wǎng)站設(shè)計(jì)、做網(wǎng)站、移動(dòng)網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。成都創(chuàng)新互聯(lián)是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來驚喜。成都創(chuàng)新互聯(lián)推出祥云免費(fèi)做網(wǎng)站回饋大家。

容器管理系統(tǒng)的演變


首先是以一個(gè) Kubernetes 非內(nèi)核開發(fā)人員的角度去探討其和 YARN 之間的關(guān)系。眾所周知,Apache Hadoop YARN 可能是在國(guó)內(nèi)用途最廣的一個(gè)調(diào)度系統(tǒng),主要原因在于 Hadoop HDFS 在國(guó)內(nèi)或者是在整個(gè)大數(shù)據(jù)業(yè)界,是一個(gè)使用最廣泛的存儲(chǔ)系統(tǒng)。  因此,  基于其上的 YARN 也自然而然成為了一個(gè)廣為使用的一個(gè)調(diào)度系統(tǒng),包括早期的 Hadoop MapReduce。  隨著 YARN 2.0 之后 Framework 的開放,Spark on YARN 以及 Flink on YARN 也可以在 YARN 上進(jìn)行調(diào)度。

當(dāng)然 YARN 本身也存在一定的局限性。

  • 如資源隔離,因?yàn)?YARN 是以 Java 為基礎(chǔ)開發(fā)的,所以它很多資源方面的隔離有一些受限。

  • 另外對(duì) GPU 支持不夠,當(dāng)然現(xiàn)在的 YARN 3.0 已經(jīng)對(duì) GPU 的調(diào)度和管理有一定支持,但之前版本對(duì)GPU 支持不是很好。


所以在 Apache 基金會(huì)之外,CNCF 基金會(huì)基于 Native Cloud 調(diào)度的 Kubernetes 出現(xiàn)了。

從開發(fā)人員角度來看,我認(rèn)為 Kubernetes 是更像一個(gè)操作系統(tǒng),可以做非常多的事情。當(dāng)然這也意味著 Kubernetes 更復(fù)雜、學(xué)習(xí)曲線比較陡峭,你需要理解很多定義和概念。相比之下,YARN 主要管理資源調(diào)度部分,對(duì)整個(gè)操作系統(tǒng)而言,它體量要小很多。當(dāng)然,不可置否,它也是一個(gè)大數(shù)據(jù)生態(tài)的先驅(qū)。接下來我會(huì)將焦點(diǎn)放在 Kubernetes 上面,探討從 YARN 的 Container 向 Kubernetes 的 Container(或者 POD)的演變過程中,我們總結(jié)的經(jīng)驗(yàn)和教訓(xùn)。

Flink on K8S intro


 

部署集群


Flink 1.10Container環(huán)境怎么配置


上圖展示了 Flink Standalone Session on K8S 上調(diào)度流程圖,藍(lán)色虛線框內(nèi)是運(yùn)行在 Kubernetes 集群內(nèi)部組件,灰色框的是 Kubernetes 原生所提供的命令或組件,包括 kubectl 和 K8S Master。左側(cè)羅列了   Flink 官方文檔  上提供的5個(gè) yaml 文件,可以用來在 K8S 上部署最簡(jiǎn)單的 Flink Standalone Session 集群。

啟動(dòng)集群所需要執(zhí)行的 kubectl 命令如下:

  
    
  
  
  kubectl create -f flink-configuration-configmap.yamlkubectl create -f jobmanager-service.yamlkubectl create -f jobmanager-deployment.yamlkubectl create -f taskmanager-deployment.yaml

  • 首先,它會(huì)向 K8S Master 申請(qǐng)創(chuàng)建 Flink ConfigMap,在 ConfigMap 中提供了 Flink 集群運(yùn)行所需要的配置,如:flink-conf.yaml 和 log4j.properties;
  • 其次,創(chuàng)建 Flink JobManager 的 service,通過 service 來打通 TaskManager 和 JobManager之間的聯(lián)通性;
  • 然后,創(chuàng)建 Flink Jobmanager 的 Deployment,用來啟動(dòng) JobMaster,包含的組件有 Dispatcher 和 Resource manager。
  • 最后,創(chuàng)建 Flink TaskManager 的 Deployment,用來啟動(dòng) TaskManager,因?yàn)?Flink 官方 taskmanager-deployment.yaml 示例中指定了2個(gè)副本,所以圖中展示了2個(gè) TM 節(jié)點(diǎn)。

另外,還有一個(gè)可選操作是創(chuàng)建 JobManager REST service,這樣用戶就可以通過REST service 來提交作業(yè)。

以上就是 Flink Standalone Session 集群的概念圖。

 

作業(yè)提交


下圖展示了使用 Flink client 向該 Standalone Session 集群提交作業(yè)的流程細(xì)節(jié)。

Flink 1.10Container環(huán)境怎么配置


使用 Flink client 提交作業(yè)的命令是:

./bin/flink run -m : ./examples/streaming/WordCount.jar

其中 -m 所需的參數(shù) public-node-IP 和 node-port 正是通過 jobmanager-service.yaml 所暴露 REST service 的 IP 和端口。執(zhí)行該命令就可以向集群提交一個(gè) Streaming WordCount 作業(yè)。此流程與 Flink Standalone 集群所運(yùn)行的環(huán)境無關(guān),無論是運(yùn)行在 K8S 之上,還是運(yùn)行在物理機(jī)之上,提交作業(yè)的流程是一致的。

Standalone Session on K8S 的優(yōu)缺點(diǎn):

  • 優(yōu)點(diǎn)是無需修改 Flink 源碼,僅僅只需預(yù)先定義一些yaml 文件,集群就可以啟動(dòng),互相之間的通信完全不經(jīng)過 K8S Master;

  • 缺點(diǎn)是資源需要預(yù)先申請(qǐng)無法動(dòng)態(tài)調(diào)整,而 Flink on YARN 是可以在提交作業(yè)時(shí)聲明集群所需的 JM 和 TM 的資源。


因此社區(qū)在 Flink 1.10 進(jìn)程中,也是我們阿里負(fù)責(zé)調(diào)度的同學(xué),貢獻(xiàn)的整個(gè) native 計(jì)算模式的Flink on K8S,也是我們過去一年在實(shí)戰(zhàn)中所總結(jié)出來的   Native Kubernetes  。

Flink 1.10Container環(huán)境怎么配置


它最大的區(qū)別就是當(dāng)用戶通過 Flink client 提交作業(yè)時(shí),整個(gè)集群的 JobMaster 通過 K8sResourceManager 向 K8S Master 動(dòng)態(tài)申請(qǐng)資源去創(chuàng)建運(yùn)行 TaskManager 的 POD,然后 TaskManager 再與 JobMaster 互相之間通信。有關(guān) Native Kubernetes的細(xì)節(jié)請(qǐng)參考王陽(yáng)所分享的《  Running Flink on Kubernetes natively  》。

總而言之,我們可以像使用 YARN 一樣的去使用 K8S,相關(guān)的配置項(xiàng)也盡量做到與 YARN 類似。不過為了方便講解,接下來我會(huì)使用 Standalone Session集群來展示,而下文介紹的部分功能,在 Flink 1.10 還未實(shí)現(xiàn),預(yù)計(jì)在 Flink 1.11 完成。

Flink on K8S 實(shí)戰(zhàn)分享


 

   

日志搜集


當(dāng)我們?cè)?Flink on K8S 上運(yùn)行一個(gè)作業(yè),有一個(gè)功能性問題無法回避,就是日志。如果是運(yùn)行在 YARN 上,YARN 會(huì)幫我們做這件事,例如在 Container 運(yùn)行完成時(shí),YARN 會(huì)把日志收集起來傳到 HDFS,供后期查看。但是 K8S 并未提供日志搜集與存儲(chǔ),所以我們可以有很多選擇去做日志(收集、展示)的事情。尤其是當(dāng)作業(yè)因?yàn)楫惓?dǎo)致 POD 退出,POD 退出后日志會(huì)丟失,這將導(dǎo)致異常排查變得非常困難。

如果是 YARN,我們可以用命令 yarn logs -applicationId <applicationId> 來查看相關(guān)日志。但是在 K8S 上怎么辦?

目前我們比較常見的做法是使用 fluentd 來搜集日志,且已經(jīng)在部分用戶生產(chǎn)環(huán)境有所應(yīng)用。

Flink 1.10Container環(huán)境怎么配置


fluentd 也是一個(gè) CNCF 項(xiàng)目,通過配置一些規(guī)則,比如正則匹配,就可以將 logs 目錄下的*.log 、*.out 及 *.gc 日志定期的上傳到 HDFS 或者是其他分布存儲(chǔ)文件系統(tǒng),以此來解決我們的日志收集功能。這也意味著在整個(gè) POD 的里面,除了 TM 或 JM 之外,我們需要再啟動(dòng)一個(gè)運(yùn)行著 fluentd 進(jìn)程的 Container(sidecar)。

當(dāng)然,還有其他辦法,比如一個(gè)不需要再增加 Container 的方式:我們可以使用  logback-elasticsearch-appender   將日志發(fā)到 Elasticsearch。其實(shí)現(xiàn)原理是通過Elasticsearch REST API 支持的 scoket stream 方式,將日志直接寫入Elasticsearch。

相比于之前的 fluentd 來說,優(yōu)點(diǎn)是不需要另啟一個(gè) Container 來專門收集日志,缺點(diǎn)是無法搜集非 log4j 日志,比如 System.out、System.err 打印的日志,尤其是作業(yè)發(fā)生 core dump,或者發(fā)生 crash 時(shí),相關(guān)日志會(huì)直接刷到System.out、System.err 里面。  從這個(gè)角度來看使用 logback-elasticsearch-appender 寫入 Elasticsearch 的方案也不是那么完美了。  相比之下,fluentd 可以自由地配置各式各樣的策略來搜集所需要的日志信息。  

 

Metrics


日志可以幫助我們觀察整個(gè)作業(yè)運(yùn)行的情況,尤其是在出問題之后,幫助我們回溯場(chǎng)景,進(jìn)行一些排查分析。另外一個(gè)老生常談也非常重要的問題就是 Metrics 和監(jiān)控。業(yè)界已經(jīng)有很多種監(jiān)控系統(tǒng)解決方案,比如在阿里內(nèi)部使用比較多的 Druid、開源InfluxDB 或者商用集群版 InfluxDB、CNCF 的 Prometheus 或者 Uber 開源的 M3 等等。

然后我們這里直接拿 Prometheus 進(jìn)行討論,因?yàn)?Prometheus 與 Kubernetes 均屬于 CNCF 項(xiàng)目,在指標(biāo)采集領(lǐng)域具備先天優(yōu)勢(shì),從某種程度上來說Prometheus 是 Kubernetes 的一個(gè)標(biāo)配監(jiān)控采集系統(tǒng)。Prometheus 可以實(shí)現(xiàn)功能很多,不僅可以去做報(bào)警,也可以定一些規(guī)則做定期的多精度管理。

Flink 1.10Container環(huán)境怎么配置


但是我們?cè)趯?shí)際生產(chǎn)中發(fā)現(xiàn)一個(gè)問題,Prometheus 的水平拓展支持不夠好。大家可以看到上圖右側(cè)部分,Prometheus 所謂的聯(lián)邦分布式架構(gòu)其實(shí)就是多層結(jié)構(gòu),一層套一層,然后它上面節(jié)點(diǎn)負(fù)責(zé)路由轉(zhuǎn)發(fā)去下一層查詢結(jié)果。很明顯,無論部署多少層,越往上的節(jié)點(diǎn)越容易成為性能瓶頸,而且整個(gè)集群的部署也很麻煩。從我們接觸到的用戶來說,在規(guī)模不是很大的時(shí)候,單點(diǎn)的 Prometheus 就可以承擔(dān)絕大部分的監(jiān)控壓力,但是一旦用戶規(guī)模很大,比如幾百個(gè)節(jié)點(diǎn)的 Flink 集群,我們就會(huì)發(fā)現(xiàn)單點(diǎn) Prometheus 會(huì)成了一個(gè)非常大的性能瓶頸,無法滿足監(jiān)控需求。

我們?cè)趺醋龅侥兀?/section>

Flink 1.10Container環(huán)境怎么配置


我們首先對(duì)不同 Flink 作業(yè)的 metrics 做了一致性哈希,當(dāng)然肯定不會(huì)是一個(gè)作業(yè)的metrics 只發(fā)了一個(gè) Prometheus,而是面向作業(yè)里面不同 scope 的 metrics,F(xiàn)link的 metrics 力度從大到小分別是:

  • JobManager/TaskManager metrics
  • Job metrics(checkpoint次數(shù)、size和fail次數(shù))
  • task metrics
  • operator metrics(每秒處理多少條record、receive的bytes數(shù)目)。

現(xiàn)在方案是先根據(jù)不同的 scope 去做一致性哈希,發(fā)到不同的 Prometheus 上,之后再配合 Thanos (滅霸,對(duì)就是在《復(fù)仇者聯(lián)盟3》里面打完響指后去種瓜的農(nóng)夫)。我個(gè)人理解 Thanos 是一個(gè)可以支持分布式查詢 Prometheus 的增強(qiáng)組件。所以整個(gè) Prometheus 架構(gòu),演變成單個(gè) Prometheus 實(shí)例所在的 container 會(huì)搭載一個(gè) Thanos sidecar。

當(dāng)然整個(gè)架構(gòu)會(huì)導(dǎo)致一些限制,這個(gè)限制也是我們做一致性哈希的原因,是因?yàn)楫?dāng) Thanos 與 Prometheus 所搭配部署時(shí),如果有一段 metrics數(shù)據(jù),因?yàn)槟承┰驅(qū)е滤仍?Prometheus A 里面,也在 Prometheus B 里面,那么在 Thanos query 里邊它會(huì)有一定規(guī)則,對(duì)數(shù)據(jù)進(jìn)行 abandon 處理,即去掉一個(gè)以另外一個(gè)為準(zhǔn), 這會(huì)導(dǎo)致 UI 上 metrics 圖表的線是斷斷續(xù)續(xù)的,導(dǎo)致體驗(yàn)很不友好,所以我們就需要一致性哈希,并通過 Thanos 去做分布式查詢。

但是整個(gè)方案實(shí)際運(yùn)行中還是有一些性能問題,為什么 Prometheus 在很多業(yè)務(wù)級(jí) metrics 上去表現(xiàn)其實(shí)很不錯(cuò),而在 Flink 或者是這種作業(yè)級(jí)別上,它表現(xiàn)的會(huì)有一些壓力呢?其實(shí)很重要的一個(gè)原因是作業(yè) metrics 變化是非常急劇的。相比于監(jiān)控HDFS、Hbase,這些組件的指標(biāo)是有限的、維度也不高。我們用一個(gè)查詢場(chǎng)景來解釋維度的概念,例如說我們要查詢?cè)谀硞€(gè) hosts 的某個(gè) job 的某個(gè) task 上所有的 taskmanager_job_task_buffers_outPoolUsage,這些所說的查詢條件,也就是用 tag 去做查詢過濾,那么就有一個(gè)問題是 Flink 的 taskAttempId,這個(gè)是一個(gè)非常不友好的一個(gè) tag,因?yàn)樗且粋€(gè) uuid 且每當(dāng)作業(yè)發(fā)生 failover 的時(shí)候,taskAttempId 就會(huì)發(fā)生變化。

如果作業(yè)不斷 failover,然后不停地持久化新的 tag 到 Prometheus,如果 Prometheus 后面接的 DB 需要對(duì) tag 構(gòu)建一個(gè)索引的話,那么索引的壓力會(huì)非常大。例如 InfluxDB 的壓力就會(huì)非常大,可能會(huì)導(dǎo)致整個(gè)內(nèi)存  CPU 不可用,這樣的結(jié)果非??膳隆K?,我們還需要借助于社區(qū)在 report 這邊把一些高維度的 tag 過濾掉,有興趣的同學(xué)可以關(guān)注下   FLINK-15110  。

 

性能

■ 網(wǎng)絡(luò)性能

我們先介紹 network 性能。無論你用 CNI 或者 Kubernetes 的網(wǎng)絡(luò)化插件,不可避免的會(huì)出現(xiàn)網(wǎng)絡(luò)性能損耗。比較常見的 flannel,在一些測(cè)試項(xiàng)目上會(huì)有百分之30左右的性能損耗。也不是很穩(wěn)定,我們使用時(shí)發(fā)現(xiàn)作業(yè)經(jīng)常會(huì)報(bào)PartitionNotFoundException: Partition xx@host not found,也就是下游無法獲取到上游的 Partition。

Flink 1.10Container環(huán)境怎么配置

當(dāng)然,你可以在 Flink 層去增大一些網(wǎng)絡(luò)容錯(cuò)性,例如把 taskmanager.network.request-backoff.max 調(diào)到300秒,默認(rèn)是10秒,然后把a(bǔ)kka 的 timeout 調(diào)大一點(diǎn)。

還有一個(gè)讓我們特別頭疼的問題:

Flink 1.10Container環(huán)境怎么配置


我們發(fā)現(xiàn)作業(yè)運(yùn)行過程中經(jīng)常遇到 Connection reset by peer 問題,原因是 Flink 在設(shè)計(jì)時(shí),對(duì)網(wǎng)絡(luò)的穩(wěn)定要求很高。因?yàn)橐WC Exactly once,如果數(shù)據(jù)傳輸失敗,那么 Flink 就要 fail 整個(gè) task 并重新啟動(dòng),然后我們會(huì)發(fā)現(xiàn)經(jīng)常會(huì)出現(xiàn)令人頭疼的Connection reset by peer 問題,我們有幾個(gè)的解決方案方式:

  • 不要有異構(gòu)網(wǎng)絡(luò)環(huán)境(盡量不要跨機(jī)房訪問)
  • 云服務(wù)商的機(jī)器配置網(wǎng)卡多隊(duì)列  (將實(shí)例中的網(wǎng)絡(luò)中斷分散給不同的CPU處理, 從而提升性能)
  • 選取云服務(wù)商提供的高性能網(wǎng)絡(luò)插件:例如阿里云的 Terway
  • Host network,繞開 k8s 的虛擬化網(wǎng)絡(luò)(需要一定的開發(fā)量)

第一個(gè)要排查的問題就是集群不要有異構(gòu)網(wǎng)絡(luò)環(huán)境,因?yàn)橛锌赡?Kubernetes 的宿主機(jī)在不同機(jī)房,然后跨機(jī)房訪問遇到網(wǎng)絡(luò)抖動(dòng)的時(shí)候都就會(huì)比較頭疼。然后是云服務(wù)商機(jī)器配置網(wǎng)卡多隊(duì)列,因?yàn)?ECS 虛擬機(jī),它是需要耗一定的 CPU 去做網(wǎng)絡(luò)虛擬化。那么如果網(wǎng)卡不配置成多隊(duì)列的話,有可能網(wǎng)卡只用了1到2個(gè) core,然后虛擬化會(huì)把這2個(gè) core 用光,用光的話會(huì)導(dǎo)致丟包,也就會(huì)遇到這種比較頭疼的Connection reset by peer 問題。

還有一種方案是選取云服務(wù)商提供的高性能網(wǎng)絡(luò)插件,當(dāng)然這需要云服務(wù)商支持,比如阿里云的 Terway,Terway 對(duì)外描述是可以支持與 host network 一樣的性能,而不是像 flannel 會(huì)帶來一定的性能損耗。

最后一種,如果無法使用 Terway,我們可以用 host network 來繞開 K8S 虛擬化網(wǎng)絡(luò)。不過這種方案首先是對(duì) Flink 有一些開發(fā)工作,其次是如果你已經(jīng)使用了Kubernetes,卻還要使用 host network,從某種意義上來說,有一點(diǎn)奇怪,很不符合 K8S style。當(dāng)然我們也在一些無法用 Terway 的機(jī)器,然后又遇到這個(gè)頭疼的問題是,也提供了相應(yīng)工程,部署時(shí)采用 host network,而不是使用 overlay 的flannel 方案。

■ 磁盤性能

接下來談磁盤性能,前文提到過:所有虛擬化的東西都會(huì)帶來一些性能損耗。對(duì)于 RocksDB 需要讀寫本地磁盤的場(chǎng)景,就很頭疼,因?yàn)?overlay 的 file system 會(huì)有大概30%的性能損耗。

Flink 1.10Container環(huán)境怎么配置


那怎么辦呢?我們選擇一種方式,就是使用 hostPath。簡(jiǎn)單來說,POD 可以訪問到宿主機(jī)的物理盤。上圖右側(cè)部分就定義了 hostPath,當(dāng)然需要預(yù)先保證 Flink 鏡像的用戶是具備訪問宿主機(jī)目錄權(quán)限,所以最好把這里目錄改成 777 或者 775。

大家如果想用這個(gè)功能的話,可以查看   Flink-15656  ,它提供一個(gè) POD 的 template,意味著你可以自行調(diào)整。因?yàn)槲覀冎?K8S 的功能特別多,特別繁雜,F(xiàn)link 不可能為了每一個(gè)功能都去做個(gè)適配。你可以在 template 里面,比如定義 hostPath,然后你所寫 POD 的就可以基于這個(gè)模板下面的 hostPath 就可以去訪問目錄了。

 

OOM killed


OOM killed 也是個(gè)比較頭疼的問題。因?yàn)樵谌萜鳝h(huán)境下,部署服務(wù)的時(shí)候,我們需要預(yù)先設(shè)置 POD 所需 memory 和 CPU 的資源,然后 Kubernetes 會(huì)指定配置去相關(guān) node (宿主機(jī))上面申請(qǐng)調(diào)度資源。申請(qǐng)資源除了要設(shè)置 request 之外,還有會(huì)設(shè)置 limit——一般都會(huì)打開 limit——它會(huì)對(duì)申請(qǐng)的 memory 和 CPU 進(jìn)行限制。

比如說 node 的物理內(nèi)存是 64G,然后申請(qǐng)運(yùn)行8個(gè)8G內(nèi)存的 POD,看著好像沒有問題,但是如果對(duì)這8個(gè) POD的沒有任何 limit的話,假如每個(gè)用到10G,那么就會(huì)導(dǎo)致 POD 之間出現(xiàn)資源競(jìng)爭(zhēng),現(xiàn)象是一個(gè) POD 運(yùn)行正常另外一個(gè) POD 忽然被 Kill,所以就要做一個(gè)memory limit。memory limit 帶來的問題是:POD 莫名其妙退出,然后查看 Kubernetes 的 event 發(fā)現(xiàn)是因?yàn)?POD 被 OOM killed 了。我相信如果用過Kubernetes 的同學(xué)肯定遇到過相關(guān)問題。

我們是怎么排查的呢?

Flink 1.10Container環(huán)境怎么配置


第一個(gè)是我們可以在 JVM 端開啟 native 內(nèi)存追蹤,可以定期去查看,但這只能看到 JVM 所申請(qǐng)的 native 內(nèi)存,包括如 Metaspace,非 JVM 就無法分析了;還有一個(gè)就是萬能的 Jemalloc 和 jeprof 去做定期 dump 內(nèi)存進(jìn)行分析。

老實(shí)說第2個(gè)功能我們可能用的比較少,因?yàn)槲覀円郧霸?YARN 上面會(huì)這樣用,就是說發(fā)現(xiàn)有的作業(yè)內(nèi)存很大,因?yàn)?JVM 對(duì)最大內(nèi)存會(huì)做限制,所以肯定是 native 這邊出的問題,那么到底是哪個(gè) native 出問題,就可以 Jemalloc+jeprof 作內(nèi)存分析。比如我們之前遇到過用戶自己去解析 config 文件,結(jié)果每次都要解壓一下,最后把內(nèi)存撐爆了。

當(dāng)然這是一種引起 OOM 的場(chǎng)景,但更多的可能是 RocksDB 引發(fā) OOM,當(dāng)然如果是使用了 RocksDB 這種省 native 內(nèi)存的 state backend。所以我們?cè)?Flink 1.10 做了一個(gè)功能貢獻(xiàn)給社區(qū),就是對(duì) RocksDB 的 memory 進(jìn)行管理,由參數(shù)state.backend.rocksdb.memory.managed 控制是否進(jìn)行管理,默認(rèn)是開啟。
我們下面這個(gè)圖是什么呢?

Flink 1.10Container環(huán)境怎么配置


是在 RocksDB 沒有使用 memory 控制,這里一共定了4個(gè) state,分別是 value、list、map 和 window,大家可以看到最頂端的線是 block cache usage 加上RocksDB 的 write buffer 就構(gòu)成了 RocksDB 當(dāng)前所使用總內(nèi)存的大小。大家看到這4個(gè)加起來的話差不多超過400M了。

原因是 Flink 目前的 RocksDB 對(duì) state 數(shù)沒有限制,一個(gè) state 的就是一個(gè) Column Family,而 Column Family 就會(huì)額外獨(dú)占所用的 write buffer 和 block cache。默認(rèn)情況下,一個(gè) Column Family 最多擁有2個(gè)64MB write buffer 和一個(gè) 8MB block cache,大家可以算一算,一個(gè) state 就是136MB,四個(gè) state 就是544MB。

如果我們開啟了 state.backend.rocksdb.memory.managed,我們會(huì)看到4個(gè) state所使用的 block cache 折線走勢(shì)基本一致:

Flink 1.10Container環(huán)境怎么配置


為什么呢?是因?yàn)閷?shí)現(xiàn)了 cache share 功能。就是說,我們?cè)谝粋€(gè) state 里面我們先創(chuàng)建一個(gè) LRU cache,之后無論是什么情景都會(huì)從 LRU cache 里面去做內(nèi)存的分發(fā)和調(diào)度,然后借助 LRU cache,最近最少被用的內(nèi)存會(huì)被釋放掉。所以在 Flink 1.10之后,我們說開啟 state.backend.rocksdb.memory.managed 可以解決大部分問題。

Flink 1.10Container環(huán)境怎么配置


但是,當(dāng)然萬事都有但是,我們開發(fā)過程中發(fā)現(xiàn):RocksDB cache share 的功能做的不是特別好。這涉及到一些實(shí)現(xiàn)原理細(xì)節(jié),比如沒法去做 strict cache,如果你開啟的話可能會(huì)碰到奇怪的NPE問題,所以說在某些特定場(chǎng)景下可能做的不是很好。這時(shí)你可能就要適當(dāng)增大taskmanager.memory.task.off-heap.size 以提供更多的緩沖空間。

當(dāng)然我們首先要知道它大概用多少內(nèi)存空間。剛才我們展示的內(nèi)存監(jiān)控圖里面,是需要打開參數(shù) state.backend.rocksdb.metrics.block-cache-usage:true,打開之后,我們可以在 metrics 監(jiān)控上面去獲取到相關(guān)的指標(biāo),觀察一下大概超用到多少。比如說1GB一個(gè) state TM 默認(rèn)的 manager 是 294MB。

所以說你發(fā)現(xiàn)比如說你可能超過很多,比如說偶爾會(huì)到300MB,或者310MB,你這時(shí)候就可以考慮配置參數(shù)taskmanager.memory.task.off-heap.size (默認(rèn)是0)來再增加一部分內(nèi)存,比如說再加64MB,表示在 Flink 所申請(qǐng)的 off-heap 里面再額外開辟出來一塊空間,給RocksDB 做一段 Buffer,以免他被 OOM killed。這個(gè)是目前所能掌握的一個(gè)解決方案,但根本的解決方案可能需要跟 RocksDB 社區(qū)去一起去協(xié)同處理。

我們也希望如果有同學(xué)遇到類似問題可以跟我們進(jìn)行交流,我們也非常樂意和你一起去觀察、追蹤相關(guān)問題。

Demo


最后一部分演示使用 hostPath 的 demo,大部分 yaml 文件與社區(qū)的  示例  相同,task manager 的部署 yaml 文件需要修改,見下:

apiVersion: apps/v1kind: Deploymentmetadata:  name: flink-taskmanagerspec:  replicas: 2  selector:    matchLabels:      app: flink      component: taskmanager  template:    metadata:      labels:        app: flink        component: taskmanager    spec:      containers:      - name: taskmanager        image: reg.docker.alibaba-inc.com/chagan/flink:latest        workingDir: /opt/flink        command: ["/bin/bash", "-c", "$FLINK_HOME/bin/taskmanager.sh start; \          while :;          do            if [[ -f $(find log -name '*taskmanager*.log' -print -quit) ]];              then tail -f -n +1 log/*taskmanager*.log;            fi;          done"]        ports:        - containerPort: 6122          name: rpc        livenessProbe:          tcpSocket:            port: 6122          initialDelaySeconds: 30          periodSeconds: 60        volumeMounts:        - name: flink-config-volume          mountPath: /opt/flink/conf/        - name: state-volume          mountPath: /dump/1/state        securityContext:          runAsUser: 9999  # refers to user _flink_ from official flink image, change if necessary      volumes:      - name: flink-config-volume        configMap:          name: flink-config          items:          - key: flink-conf.yaml            path: flink-conf.yaml          - key: log4j.properties            path: log4j.properties      - name: state-volume        hostPath:          path: /dump/1/state          type: DirectoryOrCreate

Q&A 問答


1、Flink 如何在 K8S 的 POD 中與 HDFS 交互?  

其與 HDFS 交互很簡(jiǎn)單,只要把相關(guān)依賴打到鏡像里面就行了。就是說你把 flink-shaded-hadoop-2-uber-{hadoopVersion}-{flinkVersion}.jar 放到 flink-home/lib目錄下,然后把一些 hadoop 的配置比如 hdfs-site.xml、 core-site.xml 等放到可以訪問的目錄下,F(xiàn)link 自然而然就可以訪問了。這其實(shí)和在一個(gè)非 HDFS 集群的節(jié)點(diǎn)上,要去訪問 HDFS 是一樣的。

2、Flink on K8S 怎么保證 HA?  

其實(shí) Flink 集群的 HA 與是否運(yùn)行在 K8S 之上沒什么關(guān)系,社區(qū)版的 Flink 集群 HA需要 ZooKeeper 參與。HA 需要 ZooKeeper 去實(shí)現(xiàn) checkpoint Id counter、需要ZooKeeper 去實(shí)現(xiàn) checkpoint stop、還包括 streaming graph 的 stop,所以說HA 的核心就變成如何在 Flink on K8S 的集群之上,提供 ZooKeeper 的服務(wù),ZooKeeper 集群可以部署在 K8S 上或者物理機(jī)上。同時(shí)社區(qū)也有嘗試在 K8S 里面借用 etcd 去支持提供一套 HA 方案,目前真正工業(yè)級(jí)的 HA,暫時(shí)只有 zookeeper 這一種實(shí)現(xiàn)。

3、Flink on K8S 和 Flink on YARN,哪個(gè)方案更優(yōu)?怎樣選擇?  

Flink on YARN 是目前比較成熟的一套系統(tǒng),但是它有點(diǎn)重,不是云原生(cloud native)。在服務(wù)上云的大趨勢(shì)下,F(xiàn)link on K8S 是一個(gè)光明的未來。Flink on YARN 是一個(gè)過去非常成熟一套體系,但是它在新的需求、新的挑戰(zhàn)之下,可能缺乏一些應(yīng)對(duì)措施。例如對(duì)很多細(xì)致的 GPU 調(diào)度,pipeline 的創(chuàng)建等等,概念上沒有K8S 做得好。

如果你只是簡(jiǎn)單運(yùn)行一個(gè)作業(yè),在 Flink on YARN 上可以一直穩(wěn)定運(yùn)行下去,它也比較成熟,相比之下 Flink on K8S 夠新、夠潮、方便迭代。不過目前 Flink on K8S 已知的一些問題,比如學(xué)習(xí)曲線比較陡峭,需要一個(gè)很好的 K8S 運(yùn)維團(tuán)隊(duì)去支撐。另外,K8S 本身虛擬化帶來的性能影響,正如先前介紹的無論是磁盤,還是網(wǎng)絡(luò),很難避免一定的性能損耗,這個(gè)可能是稍微有點(diǎn)劣勢(shì)的地方,當(dāng)然相比這些劣勢(shì),虛擬化(容器化)帶來的優(yōu)點(diǎn)更明顯。

4、 /etc/hosts 文件如何配置的?我理解要跟 HDFS 交互,需要把 HDFS 節(jié)點(diǎn) IP 和 host,映射寫到 /etc/hosts 文件。  

通過通過 Volume 掛載 ConfigMap 內(nèi)容并映射到 /etc/hosts 來解決,或者無需修改 /etc/hosts 轉(zhuǎn)而依賴 CoDNS。

5、Flink on K8S 故障排查困難,你們是怎么解決的?  

首先 Flink on K8S 與 Flink on YARN 的故障排查有什么區(qū)別呢?主要是 K8S 本身可能會(huì)有問題,這就是稍微麻煩的地方。K8S 可以認(rèn)為是一個(gè)操作系統(tǒng),可能有很多復(fù)雜的組件在里面。YARN 是一個(gè)用 Java 實(shí)現(xiàn)的資源調(diào)度器,這時(shí)更多是宿主機(jī)故障導(dǎo)致集群異常。面對(duì) K8S 可能出問題,我個(gè)人感覺是相比 YARN 來說要難查一些。因?yàn)樗泻芏嘟M件,可能 DNS 解析出問題,就需要去查看 CoDNS 日志;網(wǎng)絡(luò)出問題或者是磁盤出問題你要去查看 kube event;POD 異常退出,需要去查看 event POD 退出的原因。實(shí)話實(shí)話,確實(shí)需要一定的門檻,最好是需要運(yùn)維支持。

但如果是說 Flink 故障排查,這在 K8S 或是 YARN 排查手段都一樣,

  • 查看日志,檢測(cè)是否有 exception;
  • 如果是性能就需要用 jstack,查看 CPU、調(diào)用棧卡在哪里;
  • 如果發(fā)現(xiàn)總是有 OOM 風(fēng)險(xiǎn),或者老年代總是打的很滿,或者 GC 頻繁,或者Full GC 導(dǎo)致 Stop the world,就需要 jmap 查看哪塊占內(nèi)存,分析是否存在內(nèi)存泄露

這些排查方法是與平臺(tái)是無關(guān)的,是一個(gè)放之四海而皆準(zhǔn)的排查流程。當(dāng)然需要注意POD 鏡像中可能會(huì)缺少一些 Debug 工具,所以建議大家在搭建 Flink on K8S 集群時(shí),構(gòu)建私有鏡像,在構(gòu)建的過程中安裝好相應(yīng)的 Debug 工具。

到此,關(guān)于“Flink 1.10Container環(huán)境怎么配置”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!

標(biāo)題名稱:Flink1.10Container環(huán)境怎么配置
網(wǎng)站網(wǎng)址:http://muchs.cn/article2/pidioc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供建站公司、Google、App設(shè)計(jì)、電子商務(wù)、面包屑導(dǎo)航

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

手機(jī)網(wǎng)站建設(shè)