讀了此文,收獲良多,翻譯之,方便以后查看~
文章介紹了Hulu北京大數據團隊開發的Docker On YARN實現:Voidbox,一種基於Docker,運行在YARN上的DAG計算框架,已在hulu多條生產線上使用,效果明顯。
-------------------------------------------------分割線------------------------------------------------------------------------------------------------
1.設計開發Voidbox的動機
YARN是Hadoop2.0之后的使用的分布式資源管理系統,它主要負責為MapReduce、Spark等高層應用分配管理整個集群的資源。但是現在很多已存在的工作在YARN的框架都是在某個特定的環境下運行的。所以如何能夠在任意的復雜環境下支持用戶的個性化應用成為了一個難題。
Docker的出現為解決這個問題指明了方向。Docker是一種很流行的容器虛擬化技術,它提供了一種在容器中運行任意應用的方法。Docker是一個用來開發、移植、運行應用的開源平台,基於Docker技術可以把應用作為一個輕量級的容器虛擬運行在任意地方。
為了繼承Docker和YARN這兩者的優點,Hulu北京大數據團隊開發了Voidbox。Voidbox使得任意封裝在docker鏡像中的應用可以像MapReduce、Spark這樣的應用一樣運行在YARN集群中。Voidbox帶來了如下便利:
- 方便了分布式應用的創建
Voidbox解決了幾乎所有的在分布式計算系統中的問題,例如,集群發現,彈性的資源分配,任務協作,災難恢復等。利用Voidbox設計的接口,可以很方便的部署實現一個分布式應用。
- 簡化部署
通常情況下,為了適用於各種復雜的環境,我們必須創建維護各種專用的VM,這些VM一般都很大,很難部署。但是利用Voidbox,我們就可以很輕易的實現資源分配,也省去了額外的維護工作。
- 提高的集群的利用率
利用Voidbox我們可以在同一個集群上部署Spark/MR應用,也可以部署其他的Voidbox應用,提高了集群的資源利用率。
Voidbox對Docker運行過程中的容器DAG任務實現了良好的支持。Voidbox還提供了多種方法以實現在生產環境和測試環境下的應用提交,而且它還可以和Jenkins,GitLab聯合使用,利用Docker注冊器來建立起一套開發、測試、自動發行的機制。
2.Voidbox的架構
2.1YARN架構
YARN使得一個集群的多個應用動態共享集群的資源,如下圖所示是YARN的整體架構。
如上圖所示,一個client向Resource Manager提交一個job。Resource Manager根據所有應用對資源的需求來分配資源。Application Master負責一個應用內部任務的的時序安排執行。
每個模塊的功能:
-
- Resource Manager:控制集群的資源管理和作業時序。
- Node Manager:運行在集群的計算節點上,控制單個機器上的任務執行,收集執行狀態並且和Resource Manager保持心跳通信。
- Application Master:負責向YARN發送資源請求,然后把請求到的資源分配給正在運行的任務。
- Container:是一個抽象的概念,一個容器主要負責協調內存、cpu、硬盤、網絡等資源。
- HDFS:YARN集群的分布式文件系統。
2.2Voidbox架構設計
在Voidbox的架構中,YARN負責集群的資源管理,Docker是運行在操作系統之上的任務執行引擎,與Docker Registry一起協同工作。Voidbox把用戶的編程代碼翻譯成Docker的基於容器的DAG任務,這些任務根據所需申請資源並且按照DAG的方式執行。
如上圖所示,每個方塊都代表一個機器,每個機器上面都有一些執行模塊。為了使這個模型更清晰,我們把這些模塊划分成三部分,Voidbox和Docker的各個模塊的功能如下:
Voidbox模塊:
-
- Voidbox Client:通過Voidbox Client,用戶可以提交、停止一個Voidbox應用。一個Voidbox應用包含多個Docker 作業,一個Docker作業包含多個Docker任務。
- Voidbox Master:事實上,它就是YARN上的Application Master,負責向YARN申請資源,然后把資源分配給Docker作業。
- Voidbox Driver:負責一個Voidbox 應用的時序控制。Voidbox支持Docker的容器DAG任務時序,在不同的任務之間還可以插入一些其他的代碼。因此Voidbox Driver即可以控制DAG時序,也可以執行用戶代碼。
- Voidbox Proxy:YARN和Docker引擎之間的橋梁,負責把YARN的各種命令傳輸給Docker引擎。
- State Server:負責維護Docker引擎的健康狀態信息,記錄可運行任務的機器列表。
Docker模塊:
-
- Docker Registry:Docker鏡像存儲,實現Docker鏡像內部的版本控制。
- Docker Engine:Docker容器執行引擎,從Docker Registry獲得特定的Docker鏡像並且啟動一個Docker容器。
- Jenkins:和GitLab協作,當應用代碼更新之后,Jenkins將會自動測試、打包、產生Docker鏡像然后上傳給Docker Registry,完成應用的自動發行過程。
2.3Voidbox運行模型
Voidbox提供了兩種應用運行模式:yarn-cluster模式和yarn-client模式。
在yarn-cluster模式下,控制組件和資源管理組件運行在YARN集群上面。當提及Voidbox應用之后,VoidboxClient任何時候退出都不會對正在執行的應用產生影響。這種模式一般應用在生產環境下。
在yarn-client模式下,控制組件和資源管理組件運行在VoidboxClient上,其他的組件運行在集群上。用戶可以看到應用狀態的更加詳細的日志。當VoidboxClient退出之后,集群上對應的正在執行的應用也會突出。這種模式一般在調試時使用。
下面對這兩種模型實現進行一個簡單的介紹:
-
- yarn-cluster模式
如上圖所示,VoidboxMaster和VoidboxDriver都運行在集群上,VoidboxDriver負責控制邏輯,VoidboxMaster則負責資源管理。
-
- yarn-client模式
如上圖所示,VoidboxMaster是在集群中運行的,VoidboxDriver則是在VoidboxClient運行的,用戶可以在IDE中提交調試Voidbox應用。
2.4Voidbox運行過程
提交一個Voidbox應用的過程和這個Voidbox應用的生命周期如下:
用戶利用Voidbox SDK編寫一個應用並產生java代碼,然后提交給YARN集群;
當收到一Voidbox應用之后,Resource Manager將會為Voidbox Master分配資源,然后啟動它。接着Voidbox Master啟動Voidbox Driver,Voidbox Driver調用Voidbox Master的接口來啟動計算節點上的Docker任務;
Voidbox Master向Resource Manager請求資源,Resource Manager根據YARN集群的狀態分配資源。Voidbox Master啟動YARN容器上的Voidbox Proxy,並且和Docker引擎通信以啟動Docker容器。
用戶的Docker任務是運行在Docker容器內的,日志輸出在一個本地文件上。用戶通過YARN的WEB端可以看到實時的應用日志。
當所有的Docker任務都完成之后,日志將會匯總給HDFS,用戶可以通過History Server來查看一個應用的日志信息。
2.5Docker和Yarn在資源管理上的集成
YARN在集群中的主要作用是一個統一的資源管理器,主要職能就是負責所有機器的資源管理。Docker作為一個容器引擎也有類似的功能,因此如何把這兩者的資源管理功能集成到一起就顯得非常重要。
在YARN中,用戶的任務只能運行在YARN容器中,Docker容器也只能由Docker引擎管理。這樣造成的結果就是一些有Docker容器運行的程序脫離了YARN的管理,破壞了YARN的統一管理和統一時序原則,從而造成資源泄漏問題。為了使YARN能夠管理控制Docker容器,我們就需要再YARN和Docker引擎中間建立一個代理層。這樣是VoidboxProxy產生的緣由,通過VoidboxProxy,YARN可以管理Docker容器的生命周期避免資源泄漏。
為了更加清楚的了解VoidboxProxy,我們以停止Voidbox應用為例。當一個用戶需要終止Voidbox進程時,YARN將會會有應用的所有資源,此時,YARN將會向相關的機器發送終止信號。相應的Voidbox Proxy將會捕獲這個信號,然后停止Docker引擎內的Docker容器以進行資源回收。
3.容錯處理
雖然Docker已經有一些穩定的發行版本,但是由於生產環境的多樣性,在運行的過程中也肯呢過產生一些不穩定的因素,造成錯誤。我們也考慮到了Voidbox的多層容錯機會來保證Voidbox的高可用性。
- Voidbox Master的容錯處理
加入Resource Manager發現Voidbox Master崩潰,它將會通知NodeManager去回收所有屬於這個Voidbox應用的YARN容器,然后重啟Voidbox Master。
- Voidbox Proxy容錯處理
假設VoidboxMaster發現VoidboxProxy崩潰,它將會代表Voidbox Proxy回收Docker容器。
- Docker容器容錯處理
每個Voidbox應用都可以配置一個最大錯誤嘗試次數,當Docker容器崩潰時,VoidboxMaster將會根據Docker容器退出錯誤碼來進行相應處理。
4.編程模型
4.1DAG編程模型
Voidbox提供了基於容器的DAG編程模型。如下所示:
如上圖所示,這個Voidbox應用中有4個作業,每個作業可以配置它自己所需的cpu、內存、Docker鏡像和並行度等資源。Job3要等到Job1和Job2結束才能執行,Job1、Job2、和Job3是分階段執行的,用戶可以在階段之間插入自己的代碼,組后才開始執行Job4.
4.2以shell命令模式提交任務
在大多數情況下,我們都想直接運行一個單獨的Docker容器任務而不想編寫程序。因此Voidbox也提供了對shell模式描述和提交Docker容器任務。事實上,這也是DAG編程模型的一種實現。例如:
docker-submit.sh \
-docker_image centos \
-shell_command “echo Hello Voidbox” \
-container_memory 1000 \
-cpu_shares 2
上述shell腳本將會提交一個任務,運行的Docker鏡像名字叫做“centos”,執行“echo Hello Voidbox”命令,資源需求為1000MB內存,2個虛擬cpu內核。
5.Voidbox實際應用
目前我們可以在YARN集群上運行Docker、MapReduce、Spark和其他的應用。在HULU內也有很多使用Voidbox的短時任務:
- 自動測試處理
和Jenkins、GitLab以及內部的DockerRegistry協同工作,當應用代碼更新時,Jenkins將會完成自動化測試、打包程序、重新生成Docker鏡像,然后傳送給內部的DockerRegistry。
- 並行化復雜任務
測試框架一般用來測試組件的可用性。這個工程是由Puby/Java編寫,並且有很復雜的依賴關系。因此我們需要維護2層Docker鏡像,第一層鏡像是作為系統軟件的基礎鏡像層,第二層是業務層。我們發布了一個測試框架的Docker鏡像,然后使用一些時序控制軟件來有規律地啟動Voidbox應用。
人臉識別是一個錄像分析應用。這個系統是由C語言編寫並且內部含有許多圖像相關的庫。這個可以使用Voidbox來優化:首先把所有的人臉識別程序打包成一個Docker鏡像,然后編寫Voidbox應用來處理這些錄像。Voidbox解決了復雜的機器環境和並行化控制的難題。
- 建立復雜的工作流
有很多任務之間有相互依賴,例如一個任務需要首先加載用戶行為,然后分析用戶行為。這兩個任務之間有承接依賴關系,我們可以使用Voidbox容器編程很容易地解決這個問題。
6.與Yarn2.6.0的DockerContainerExecutor不同之處
DockerContainerExecutor在Yarn2.6.0版本的時候發行的,它現在還不成熟,只是一個默認執行單元之上的封裝層。同一個集群上的DockerContainerExecutor很難共存。
Voidbox特點:
- DAG編程模型;
- 可配置的容器層的容錯機制;
- 多樣化的運行模式,考率到了開發環境和生產環境;
- 與YARN集群上其他Hadoop作業分享資源;
- 圖形化的log查看工具。
7.展望
- 支持YARN的其他版本
- Voidbox Master容錯機制中,保持已經運行成功的那些任務的元信息來減少重試的開銷
- 把VoidboxMaster做成一個永久的服務以支持長時任務
- 提供對長時服務的支持