淺談分散式集群管理的原理,看看集群究竟是做什麼的

本文始發於個人公眾號:TechFlow,原創不易,求個關注

今天是分散式專題的第11篇文章,我們一起來聊聊分散式集群資源管理

在開始文章之前,我們先來問一個問題,為什麼是國際上是亞馬遜,中國是阿里這兩家公司雲計算搞得最好呢?這兩家公司之間有一個巨大的共同點,就是它們都是電商公司。電商公司的特點很明顯,就是流量不是固定的,往往會受到大促、節日的影響。像是中國的雙十一和美國的黑色星期五就是典型的大促。在大促的時候的流量會是平常的十倍甚至更多,這麼大的流量必須要有更多的機器去應對。但問題是如果去買這麼多機器,但是大促過了,流量下降,那麼這些機器就又用不到了,顯然就會造成浪費。

那怎麼樣才能避免浪費呢?就是搞一個大集群,把所有機器和計算資源管理起來,大促的時候就用來應對大促的流量,平時呢可以用來搞搞大數據運算或者是租給其他公司或個人,形成一定的經濟收益,總是就是不讓這些機器閑著,以免浪費

本質上來說,亞馬遜和阿里搞雲計算、雲伺服器背後的核心驅動因素之一原因都是為了解決這個問題。

集群資源管理

集群資源管理是分散式非常普遍的應用場景,可以說是無論公司大小都必然有所接觸。像是阿里雲、亞馬遜雲說起來很高大上,但是底層也離不開這個。

這個問題的背景非常簡單,無論大小公司往往都不止一套系統。但是公司的資源是有限的也是固定的,但是我們需要應用機器的場景卻是靈活的。比如今天新上線了一個系統,需要佔用幾台伺服器,明天這個系統效果不好,撤了,再把這幾台伺服器清出來。一開始的時候沒有動態管理的集群系統,都是靠運維手動操作,所以那年代的運維都練就了一手拔插網線的好本事和健碩的手部肌肉。

在大數據時代到來之前,基本上機器變更基本上都是系統上線下線的情況,這還好說。畢竟一般的公司系統變化不會特別頻繁,但是大數據時代來臨之後,臨時任務的數量大增,今天需要跑下用戶的這份數據,明天需要統計一份報表,來來回回的臨時需求,而且這些需求往往需要用到大量機器(大數據嘛,機器少算不完),總不能都靠運維人肉處理吧?也不能指望每個開發都練就運維的本事,很浪費時間也不現實。所以很自然地人們想到了開發一套系統來做這件事情。

於是集群資源管理系統應運而生,像是我們常常聽說的Yarn,Mesos,Corona等,都是做這個的。

系統架構

我們了解了資源管理系統是做什麼的了之後,就可以來看看它的架構了。

它的架構本身並不複雜,本質上這個系統只做了兩件事情,一件事情是分配,另一件事情是回收。從功能上很好理解,我們需要把任務下發到機器,當任務執行了之後,我們需要把資源回收回來從而以後分配其他的任務。但從邏輯上,要實現這兩點並不容易。

首先,我們需要知道當前所有任務的情況,比如需要多少機器,以及執行的狀態,是還沒開始,還是已經開始了,或者是已經結束了。如果是結束了,那麼需要收回機器,如果還沒開始,則需要分配機器資源。除此之外還需要知道資源的情況,哪些資源被哪些任務佔據了,哪些是空閑的,這樣才好進行分配。要做到這一點,必須要保證系統和所有機器的通訊,還需要一個程式來執行分配策略給還沒有執行的任務分配資源。我們把這些內容整理一下,就可以畫出系統架構圖了。

簡單解釋一下上圖,上面的部分就是我們的資源管理系統,下面的部分自然就是機器了。由於一台物理機的功能非常強大,所以一般我們不會直接接入系統,而是會在上面部署多個容器,相當於多個虛擬機,也就是把一台機器變成多台加入集群。所以這個過程稱為虛擬化。以前很多C++工程師是就是專門做這個的,現在docker興起,據說很多已經逐漸換成docker了。好處是如果單個或若干個容器掛了,整個物理機還活著,可以隨時重啟。還有一個原因是一般沒有那麼大的任務可以吃掉一整個物理機的資源,也是節約資源。除了容器之外,還需要一個節點管理器,負責和整個管理系統通訊。

資源收集器負責搜集這些容器當前的狀態,如果有已經執行結束的,則把它們添加進資源池當中,也就是當前可用的意思。調度策略執行器發現有新的機器可用之後會去查看任務隊列,將其中一些任務分配到這些可用的容器當中。工作隊列當中的任務可以是多種多樣的,比如spark,MapReduce等等。

不難看出這當中調度策略執行器是整個管理系統的核心,其他所有的模組都是為它服務的。詳細的分配策略涉及的細節和邏輯非常多,所以我們把具體的策略內容放到下一篇文章當中。我們只需要有個大概的認識,知道它是負責調度任務和分配執行的即可。

集群管理的優缺點

雖然我們已經有了管理系統,看起來好像牛哄哄的。但是這方面目前仍然處於摸索狀態,還遠遠沒有成熟。這些系統之間多有不同,但是原理都是類似的,本質上都是在我們的硬體資源之上抽象出一個管理系統,就好像僱傭了一個工作飛快永遠不會累的管家。我們只需要告訴他,我們當前需要做什麼,需要多少資源。至於怎麼分配,怎麼完成,統統交給他,我們再也不用操心。

這麼做和之前人肉分配相比,進步了非常多,有非常明顯的優點。我們隨便就可以列舉出好幾條。

優點

比如我們的機器利用率變高了,因為之前人工分配了資源之後資源就固定了。比如分配給A任務一台機器,但問題是A任務並不是一直滿負荷的。可能白天流量大,消耗高,但是到了晚上流量就小了,佔用的資源就少了。而B任務可能相反,白天不需要運作,到了晚上開始發力,需要大量計算(比如現在很多機器學習的大型job都是凌晨跑的)。如果是人工分配的話,我們可能需要兩台機器分別執行A和B,但顯然這是不合理的,因為我們完全可以把它們合併,讓它們互相互補。但是每天都依靠人力來做這件事情是不現實的,萬一運維哪天忘了不是完蛋了。而有了管理系統,會有個系統替我們做這件事,它會把所有資源都安排妥當,自然利用率就高了。

其次,某種程度上來說也減少了數據存儲的消耗。比如之前的用戶數據在許多系統當中用到,不同的系統需要單獨存儲一份。不然不同的team用同一份數據很容易出現責任劃分不清楚扯皮的問題,有了分散式管理系統之後,我們只需要在分散式系統當中存儲一份數據找專人維護即可,避免了重複勞動。

最後,支援多種計算框架。比如像是Yarn,mesos等集群支援眾多計算框架,無論是MapReduce也好,還是spark也罷,或者是hive等等都可以用一套系統來管理,非常靈活方便。甚至還可以支援多版本,也不會影響。

不足

凡事有好有壞,沒有事情的完美的。既然有優點必然有不足,關於調度策略產生的問題,我們今天先不談,今天主要講講調度系統本身的問題。

第一點也是最重要的一條就是風險,表面上看我們使用集群調度系統降低了集群的風險,因為單個的節點掛了並不會影響整個集群的運行。我們只需要找到單個節點掛掉的原因進行修復,或者等待系統自動重啟就好了。系統宕機的風險被均攤了,但問題是均攤風險其實本身就是很危險的事情,它也意味著風險的聚集。

比如說有沒有想過如果集群管理系統本身宕機了呢

如果連負責任務調度的系統都掛了,顯然整個集群也就完蛋了。這種事情看似發生的概率非常小,但是一旦發生,對於企業帶來的影響和損失是巨大的。據說之前阿里雲宕機了一個下午,中國大半個互聯網的網站受此影響無法訪問。這也是阿里這幾年一直在搞異地多活,各種容災備案的原因。

第二個不足是系統目前還不夠智慧,比如說如果集群規定了每個任務最多佔用的資源總量,突然我們擴容了機器,或者是臨時有一個大任務需要超額。這些情況都需要人工干預,再比如對於系統開發的時候能夠預料的一些問題有很好的解決措施,比如節點掛了,資源吃滿了等等。但是對於沒有預料到的問題則完全解決不了,比如某個節點卡死了,沒有掛一直占著資源。

再比如一些集群里被人為安置了一些非法的腳本,比如黑客的入侵腳本,或者是挖礦腳本等等。前陣子比較火的某度員工在公司機器上挖礦了好幾個月才被抓,為什麼沒能及時發現?因為資源都是系統調度的,人工很少干預,也沒人會去整天看系統里到底都在跑些什麼任務。

當然,有問題就有前進的方向,這些問題其實也反應了我們目前這一塊還有很長的路要走,目前的方案還比較原始。以後應該會有更好用的集群管理的設計理念也會有更好的系統,當然萬丈高樓平地起,未來的方案也是基於當下一點一點改進得到的。我們學習的目的和意義也正在於此。

今天的文章就是這些,如果覺得有所收穫,請順手點個關注或者轉發吧,你們的舉手之勞對我來說很重要。