基於Mesos和Docker的分佈式計算平臺

基於Mesos和Docker的分佈式計算平臺

針對“互聯網+”時代的業務增長、變化速度及大規模計算的需求,廉價的、高可擴展的分佈式x86集羣已成爲標準解決方案,如Google已經在幾千萬臺服務器上部署分佈式系統。Docker及其相關技術的出現和發展,又給大規模集羣管理帶來了新的想象空間。如何將二者進行有效地結合?本文將介紹數人科技基於Mesos和Docker的分佈式計算平臺的實踐。

分佈式系統設計準則

可伸縮性

首先分佈式系統一定是大規模的系統,有很好的Scalability。出於成本的考慮,很多大規模的分佈式系統一般採用廉價的PC服務器,而不是大型的高性能服務器。

沒有單點失效

廉價的PC服務器在大規模使用中經常會遇到各種各樣的問題,PC服務器的硬件不可能是高可靠的,比如Google的數據中心每天都會有大量的硬盤失效,所以分佈式系統一定要對硬件容錯,保證沒有任何的單點失效。在這種很不穩定、很不可靠的硬件計算環境下,搭建一個分佈式系統提供高可靠服務,必須要通過軟件來容錯。分佈式系統針對不允許有單點失效的要求有兩方面的設計考慮,一種是服務類的企業級應用,每個服務後臺實例都要有多個副本,一兩臺硬件故障不至於影響所有服務實例;另外一種數據存儲的應用,每份數據也必須要有多個備份,保證即使某幾個硬件壞掉了數據也不會丟失。

高可靠性

除了單點失效,還要保證高可靠性。在分佈式環境下,針對企業級服務應用,要做負載均衡和服務發現來保證高可靠性;針對數據服務,爲了做到高可靠性,首先要按照某種算法來把整體數據分片(因爲一臺服務器裝不下),然後按照同樣的算法來進行分片查找。

數據本地性

再一個分佈式設計理念是數據本地性,因爲網絡通信開銷是分佈式系統的瓶頸,要減少網絡開銷,應當讓計算任務去找數據,而不是讓數據去找計算。

分佈式系統與Linux操作系統的比較

由於縱向拓展可優化空間太小(單臺服務器的性能上限很明顯),分佈式系統強調橫向擴展、橫向優化,當分佈式集羣計算資源不足時,就要往集羣裏面添加服務器,來不停地提升分佈式集羣的計算能力。分佈式系統要做到統一管理集羣的所有服務器,屏蔽底層管理細節,諸如容錯、調度、通信等,讓開發人員覺得分佈式集羣在邏輯上是一臺服務器。

和單機Linux操作系統相比,雖然分佈式系統還沒有成熟到成爲“分佈式操作系統”,但它和單機Linux一樣要解決五大類操作系統必需的功能,即資源分配、進程管理、任務調度、進程間通信(IPC)和文件系統,可分別由Mesos、Docker、Marathon/Chronos、RabbitMQ和HDFS/Ceph來解決,對應於Linux下的Linux Kernel、Linux Kernel、init.d/cron、Pipe/Socket和ext4,如圖1所示。


圖1 分佈式系統與Linux操作系統的比較 

基於Mesos的分佈式計算平臺

Mesos資源分配原理

目前我們的Mesos集羣部署在公有云服務上,用100多臺虛擬機組成Mesos集羣。Mesos不要求計算節點是物理服務器還是虛擬服務器,只要是Linux操作系統就可以。Mesos可以理解成一個分佈式的Kernel,只分配集羣計算資源,不負責任務調度。基於Mesos之上可以運行不同的分佈式計算平臺,如Spark、Storm、Hadoop、Marathon和Chronos等。Spark、Storm和Hadoop這樣的計算平臺有任務調度功能,可以直接使用Mesos SDK跟Mesos請求資源,然後自行調度計算任務,並對硬件容錯。Marathon針對服務型分佈式應用提供任務調度,比如企業網站等這類需要長時間運行的服務。通常網站應用程序沒有任務調度和容錯能力,因爲網站程序不太會處理某個後臺實例掛掉以後要在哪臺機器上重新恢復等這類複雜問題。這類沒有任務調度能力的服務型分佈式應用,可以由Marathon來負責調度。比如,Marathon調度執行了網站服務的一百個後臺實例,如果某個實例掛掉了,Marathon會在其他服務器上把這個實例恢復起來。Chronos是針對分佈式批處理應用提供任務調度,比如定期處理日誌或者定期調Hadoop等離線任務。

Mesos最大的好處是能夠對分佈式集羣做細粒度資源分配。如圖2所示,左邊是粗粒的資源分配,右邊是細粒的資源分配。


圖2 Mesos資源調度的兩種方式

圖2左邊有三個集羣,每個集羣三臺服務器,分別裝三種分佈式計算平臺,比如上面裝三臺Hadoop,中間三臺是Spark,下面三臺是Storm,三個不同的框架分別進行管理。右邊是Mesos集羣統一管理9臺服務器,所有來自Spark、Hadoop或Storm的任務都在9臺服務器上混合運行。Mesos首先提高了資源冗餘率。粗粒資源管理肯定帶來一定的浪費,細粒的資源提高資源管理能力。Hadoop機器很清閒,Spark沒有安裝,但Mesos可以只要任何一個調度馬上響應。最後一個還有數據穩定性,因爲所有9臺都被Mesos統一管理,假如說裝的Hadoop,Mesos會集羣調度。這個計算資源都不共享,存儲之間也不好共享。如果這上面跑了Spark做網絡數據遷移,顯然很影響速度。然後資源分配的方法就是resource offers,是在窗口的可調度的資源自己去選,Mesos是Spark或者是Hadoop等等。這種方法,Mesos的分配邏輯就很簡單,只要不停地報告哪些是可用資源就可以了。Mesos資源分配方法也有一個潛在的缺點,就是無中心化的分配方式,所以有可能不會帶來全局最優的方式。但這個數據資源缺點對目前來講並不是很嚴重。現在一個計算中心資源貢獻率很難達到50%,絕大部分計算中心都是很閒的狀態。

Mesos資源分配示例

下面具體舉例說明怎麼用Mesos資源分配。如圖3所示,中間是Mesos Master,下面是Mesos Slave,上面是Spark和Hadoop運行在Mesos之上。Mesos Master把可用資源報告給Spark或Hadoop。假定Hadoop有一個任務想運行,Hadoop從Mesos Master上報的可用資源中選擇某個Mesos Slave節點,然後這個任務就會在這個Mesos Slave節點上執行,這是任務完成一次資源分配,接下來Mesos Master繼續進行資源分配。


圖3 Mesos資源分配示例

任務調度

Mesos只做一件事情,就是分佈式集羣資源分配,不管任務調度。Marathon和Chonos是基於Mesos來做任務調度。如圖4所示,Mesos集羣混合運行來自Marathon和Chronos的不同類型的任務。Marathon和Chonos基於Mesos做任務調度時,一定是動態調度,也就是每個任務在執行之前是不知道它將來在哪一臺服務器上執行和綁定哪一個端口。如圖5所示,9臺服務器組成的Mesos集羣上混合運行各種Marathon調度的任務,中間一臺服務器壞掉以後,這臺服務器上的兩個任務就受影響,然後Marathon把這兩個任務遷移到其他服務器上,這就是動態任務調度帶來的好處,非常容易實現容錯。


圖4 Mesos集羣運行不同類型的任務


圖5 Marathon動態任務調度

爲了減少硬件故障對應用服務的影響,應用程序要儘量做到無狀態。無狀態的好處是在程序受到影響時不需要進行任何恢復,這樣這個程序只要重新調度起來就可以。無狀態要求把狀態數據放到存儲服務器或者是消息隊列裏面,這樣的好處是容錯時恢復起來會變得很方便。

服務類的高可靠性

對於服務類型的任務,分佈式環境保證服務的高可靠性,這需要負載均衡和服務發現。在分佈式環境下做負載均衡有一個難點就是後臺這些實例有可能發生動態變化,比如說某一個節點壞掉了,這個節點上的實例會受到影響,然後遷移到其他節點上。然而傳統負載均衡器的後臺實例地址端口都是靜態的。所以在分佈式環境下,爲了做負載均衡一定要做服務發現。比如,某個服務之前有四個事例,現在新添加了兩個實例,需要告訴負載均衡器新增加的實例的地址和端口。服務發現的過程是由幾個模塊配合完成,比如說Marathon給某個服務增加了新的實例,把新調度的實例地址端口寫到Zookeeper,然後Bamboo把Zookeeper裏存放的該服務新的實例的地址端口信息告訴負載均衡器,這樣負載均衡器就知道新的實例地址端口,完成了服務發現。

數據類的高可靠性

對於服務類型的應用,分佈式系統用負載均衡器和服務發現來保證高可靠性的服務。對於數據類型的應用,分佈式系統同樣要保證高可靠的數據服務。首先要做數據分片,一臺服務器存不下所有數據就分成多份來存,但對數據進行分片必須按照某個規則來進行分片,後面查找時要按照同樣的規則來進行分片查找,就是一致性。假定最原始的方案我們用Hash計算做成方法,在線性空間上分了三份以後,我要在數據分成三塊機器來存,三臺機器都存滿了時,再把數據進行分配的時候不再把它分配到直線線性空間上,而是把它分配到環狀空間上,把起點和終點連接起來,連成一個數據環,如圖6所示,這樣相應的數據點就放在這一塊。如果要添加一個新的數據中心就在環上新切出來這塊,這樣很方便,切出來這一部分代表這一部分數據都應該放到新的芯片上,所以把原來子數據分片挪到嵌入式的分片上。

圖6 數據分片

還有可能刪除數據,我們把黃色的數據放到紅色的數據上,這是環的好處。實際爲了做到高可靠性,任何一個數據可能假定映射到黃色部分以後,這些黃色的部分只要映射到任何一個黃色的區域都會存在同一片機器上,同一片機器底層會有多個副本和做數據的備份,這是實際數據分片的一個實例。這是怎麼做數據的高可靠性。這些數據分片,還有負載均衡,都是爲了對應分佈式分片硬件帶來的不可靠和失效,這是我們用分佈式系統最大的特點。

基於Docker的分佈式計算平臺

Docker工作流

我們主要用Docker來做分佈式環境下的進程管理。Docker工作流如圖7所示,我們不僅把Docker應用到生產階段,也應用到開發階段,所以我們每天編輯Dockerfile,提升Docker Images,測試上線,發Docker鏡像,在我們內部私有Docker regis裏面,再調到我們Docker集羣生產環境裏面,這和其他的Docker工作流沒有什麼區別。

圖7 Docker工作流

在Mesos提交Docker任務

因爲Mesos和Docker已經是無縫結合起來。通過Marathon和Chronos提交服務型應用和批處理型應用。Marathon和Chronos通過RESTful的方式提交任務,用JSON腳本設定應用的後臺實例個數、應用的參數、以及Docker Images的路徑等等。

分佈式環境下的進程通信

在分佈式環境下應用服務之間通信,是用分佈式消息隊列來做,我們用的是RabbitMQ。RabbitMQ也是一個分佈式系統,它也要保證高可靠性、解決容錯的問題。首先RabbitMQ也有集羣,如圖8所示,六個節點組成了一個RabbitMQ的集羣,每個節點之間是互爲備份的關係,任何一個壞掉,其他五個還可以提供服務,通過冗餘來保證RabbitMQ的高可靠性。


圖8 RabbitMQ集羣

其次,RabbitMQ也有數據分片機制。因爲消息隊列有可能很長,長到所有的消息不可能都放到一個節點上,這時就要用分片,把很長的消息隊列分爲幾段,分別放到不同的節點上。如圖9所示是RabbitMQ的聯盟機制,把一個消息隊列打成兩段,一段放在上游一段放在下游,假定下游消息隊列的消息被消費完了就自動把上游消息隊列裏的消息移到下游,這樣一個消息隊列變成非常長的時候也不怕,分片到多個節點上即可。


圖9 消息隊列分片

分佈式文件系統

最後講一下分佈式文件系統HDFS和Ceph。Hadoop文件系統HDFS,如圖10所示,每個數據塊有三個備份,必須放在不同的服務器上,而且三個備份裏面每個機架最多放兩份,這麼做也是爲了容錯。Ceph是另一種流行的開源分佈式文件系統。Ceph把網絡存儲設備抽象成一張邏輯硬盤,然後“掛載”到分佈式集羣的每臺服務器上,原理上非常像是Linux操作系統Mount一塊物理硬盤。這樣一來,用戶程序訪問Ceph的文件系統就跟訪問Linux本地路徑一樣,非常方便。


圖10 分佈式文件系統

分佈式環境下的監控

分佈式環境下,程序不是運行在本地,而是在集羣上面,沒有監控就等於程序運行在黑盒子下,無法調優,必須要有監控。分佈式環境下的監控分爲兩個部分,一是性能監控,另一個是報警。性能監控要知道每個應用程序運行狀態是什麼樣,即每一個應用程序佔了多少CPU內存、服務的請求處理延遲等。我們是用Graphite來做應用程序性能監控;還有其他系統,比如MongoDB、Hadoop等開源系統,我們用Ganglia來做性能監控,比如CPU內存硬盤的使用情況等。報警是要在關鍵服務出現故障時,通知開發運維人員及時排解故障,我們用Zabbix來做報警。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章