淺談分佈式集羣管理系統的一些細節【二】

本文始發於我的公衆號:TechFlow,原創不易,求個關注web


今天是分佈式專題的第12篇文章,咱們繼續來看集羣資源管理系統。網絡

上一篇的文章當中咱們簡單瞭解了一下什麼是分佈式集羣資源管理,它的誕生背景和解決的問題是什麼,以及它大概有哪些優勢和不足。上一章的內容比較表面,沒有過多深刻原理,這一篇文章咱們一塊兒來看看集羣管理系統的原理部分架構

對一篇文章有所遺忘,或者是最新關注的同窗能夠點擊下方的傳送門,回顧一下上篇的內容。併發

淺談分佈式集羣資源管理系統原理框架

局部優先的原則

在大數據應用的場景下有一個基本的設計原則:咱們一般是將計算分配到存儲數據的節點執行,而不是從節點拿到須要的數據再來進行計算。這背後的緣由很容易想通,由於這樣能夠儘可能減小節點之間的網絡通訊,減小了數據傳輸。要知道大數據場景下的數據的規模是很是大的,動輒TB,PB,少則也有幾百幾十GB,一旦須要網絡傳輸數據帶來的開銷是很是可觀的。機器學習

咱們把這個原理總結一下,能夠稱爲」局部優先「原則,也就是說執行任務的節點越局部越好,若是在一臺物理機當中就太完美了,由於這樣能夠避免全部的數據傳輸。編輯器

咱們能夠簡單地根據這個原則來衡量一個集羣調度系統的能力,咱們根據局部性的狀況能夠簡單地列出三種級別。第一種是節點局部性,也就是全部的計算都發生在一個節點當中,這樣能夠避免全部的數據傳輸,這也是最佳狀況。第二種要差一些叫作機架局部性,也就是說全部的計算雖然不能保證在一個節點當中執行,可是至少能夠保證這些執行的機器在同一個機架當中。在機架當中的機器能夠經過內部的方式傳輸數據,而沒必要藉助外部網絡,這樣的傳輸也要快得多。最差的狀況就是節點分散在不一樣的機架,沒有辦法作任何加速,這種稱爲全局局部性,會帶來大量的開銷。分佈式

咱們都知道一個好的集羣調度系統要把集羣當中全部機器的性能」壓榨「到極致,但實際上固定的計算消耗的計算資源基本上是穩定的。除了機器的利用率以外,另外一個關鍵點就是這個。並且有時候網絡IO帶來的開銷可能比機器低使用率更可怕。高併發

資源分配細節

關於資源分配可能咱們直觀理解上很簡單,當有機器空閒的時候咱們就分配給它任務,而後執行完了咱們把資源收回,可是在實際的運用當中還存在不少細節須要咱們精心設計和思考,一旦稍微有點沒想清楚可能就會形成嚴重的後果。性能

咱們來看兩個問題,第一個問題是當咱們當下新來了一個任務,可是沒有足夠資源的時候應該怎麼辦

咱們很容易想到有兩種策略,第一種策略就是什麼也不作,。等到有任務結束了,資源釋放出來了以後,咱們再執行當前這個任務。但若是咱們當前的任務是一個很是緊急的任務呢?有可能如今正在執行的任務優先級並不高,可是佔用的資源又多又長,難道咱們還要一直等下去嗎?

因此咱們會想到還有第兩者策略,就是。既然咱們當下的資源優先級高,正在執行的任務優先級低。咱們能夠先從優先級低的任務當中搶一部分資源過來,先把當下重要的任務執行了再說。等優先級高的任務執行了以後再去執行優先級低的。可是很遺憾,這麼作是有問題的。技術上的問題咱們先不談,等會再說,有沒有想過這麼搞的話,還會有誰願意把任務的優先級調低呢?確定你們執行的任務都是最高優先級。到後來會發現所謂的優先級高低設置所有變成了擺設,正在運行的優先級都同樣,都是最高優先級。

關於上面的問題還有後續,咱們先放一放,來看另一個問題,這個問題是上面這個問題的衍生品。不一樣的任務須要的資源不一樣,而且須要資源的狀況也不相同。好比有些任務資源多少均可以運行,好比spark或者是MapReduce,資源多就多用幾個機器,資源少就少用幾個,可是無論多少均可以跑,無非是執行的時間長短不一樣。可是有些任務就不是如此,好比機器學習的任務,可能一次性須要大量的資源,而且就要這麼多,少了就跑不了。那麼問題來了,當咱們新來了一個任務,當下資源不足以知足它分配須要的時候,咱們是先留着不分配給它,等資源足夠了一次性分配呢,仍是先分配一點,後面拿到一點資源再繼續分配呢?

你看,看起來平淡無奇的分配策略其實當中仍是有不少棘手的細節。事實也的確如此,這也是爲何我以前說目前的集羣資源管理系統還遠遠沒有成熟纔剛剛起步的緣由,由於對於以上的問題都沒有特別好的解決方案。

餓死與死鎖

還記得上面的兩個問題麼,若是這兩個問題沒有回答好,那麼就會出現餓死與死鎖的狀況。

餓死是指任務一直得不到調度,好比因爲設置的優先級不合理。只有你一個老實孩子給本身以爲一個不過重要的任務設置了一個正常的優先級,而其餘的老司機紛紛給本身的任務設置了最高優先級。因爲一直有高優先級的任務被提交進來,因此你的任務被一直延後,你覺得很快就能獲得結果,可能到下班你的任務還沒開始執行。在這種狀況下,你要麼同流合污,也把本身的任務設置成最高優先級,要麼就只能一直等下去,或者由於完成的工做不夠多而面臨績效以及老闆的壓力。

因而,這就從了一個簡單的任務調度的問題上升到了心裏價值觀的考驗,這也是一個經典的劣幣驅逐良幣的過程。因爲少部分人的不遵照規則,致使反卻是遵照規則的人受到懲罰,想一想真是男默女淚[狗頭]。

死鎖的狀況比較容易理解,若是學過操做系統的同窗應該很熟悉,原理是同樣的。打個比方,若是咱們當下有AB兩個任務,這兩個任務都須要集羣2/3的資源才能夠執行。因爲這兩個任務是差很少時間點提交的,而系統採起了先來先分配的原則,給這兩個任務都分配了1/2的資源。那麼這就會致使死鎖,由於這兩個任務沒有一個能執行,也就沒有一個任務會釋放資源,因此除非人工kill掉一個,不然會一直如此持續下去。

從目前的狀況來看,好像沒有一個完美的方法能夠徹底避免這兩種狀況出現。只能架構師根據本身集羣調用的實際狀況進行決策,而且還要加入一些人工干預的因素,好比在團隊當中約法三章制定一些規範和條例等等。也就是說,某種程度上來講這已經不僅是一個系統的問題了,而是一個系統和團隊協調的複雜問題。

調度器

下面咱們來看看常見的調度器的架構,常見的調度器有三種,第一種是集中式調度器,第二種是兩級調度器,最後一種是狀態共享調度器

集中式調度器

咱們先來看集中式調度器,它最直觀也最簡單:

它的設計邏輯就是集中,整個系統當中只有一個全局的中央調度器。全部的框架或者是計算任務都由中央調度器來實現。有點像是封建時候的宗族制度,整個你們族當中全部的大事小事所有由一我的來管理。顯然這樣作的弊病很是多,剛纔提到的兩個問題都須要人工干預,不然很難解決。

後來在此基礎上進行了改進,在整個中央調度器當中又加上了分支邏輯。這種調度器被稱爲多路徑調度器:

總體而言變化不大,只是多了一個條件判斷。也就是說內部實現了針對不一樣種類的任務執行不一樣的調度和分配策略。好比若是是小的碎片任務,那麼執行優先級管理,先來先得策略。若是是大的機器學習任務,只有拿到完整資源纔會執行,防止死鎖等等。

相比於單路徑集中調度而言,多路徑集中調度增長了一些靈活性,可是總體的拓展性仍是遠遠不夠,而且併發能力也比較差,資源的利用率不夠高,若是規模大了,調度性能很容易成爲瓶頸。可是它勝在架構簡單,容易維護。

兩級調度器

因爲集中式調度器有許多的問題,也不夠靈活,咱們爲了增長它的靈活性,在此基礎上又增長了一層結構:

咱們一樣有一箇中央調度器來坐鎮指揮,只不過中央調度器並不會直接調度任務,而是會以一種比較粗粒度的策略將集羣當中的資源分配給框架調度器。具體調度、執行任務的邏輯在框架調度器當中。相比於中央調度器,框架調度器執行的策略會更加細粒度一些。

另外,只有中央調度器能夠看到整個集羣當中全部資源的狀況,框架調度器只能看到本身分配到的那一部分資源。咱們比較熟悉的YARN,Mesos都是採起的這種架構。

有了框架調度器以後,咱們能夠在不一樣的框架調度器當中執行不一樣的策略。有助於提高整個集羣的併發能力,以及資源利用率。因此整體而言,兩級式調度器的性能要比集中式調度器好得多。

可是即便是這樣,也不是完美的。由於中央調度器在調度的時候執行的是一種悲觀併發的策略。簡單解釋就是在執行分配的過程中,中央調度器會嚴格按照事先制定的順序,而且會對資源加鎖來防止不一樣框架申請資源時致使的衝突。既然用到了悲觀鎖,顯然也會影響總體的性能。

狀態共享調度器

狀態共享調度器的架構和兩級調度器很是接近,能夠簡單理解成了去掉了中央調度器的結果:

這個架構最先出如今Google公司的Omega調度系統當中,Omega調度系統是如今很是火熱的Kubernetes的前身。它和兩級式調度器的最大的不一樣就是沒有中央調度器,全部的框架調度器能夠直接看到整個集羣當中的全部資源。在須要使用資源的時候,由框架調度器之間互相競爭來獲取。

而且和中央調度器不一樣的是,狀態共享策略當中使用的是樂觀鎖。簡單解釋一下樂觀鎖和悲觀鎖的區別。悲觀鎖每每會假設最壞的狀況,好比當下獲取了資源以後,在使用結束以前有可能會有其餘的線程來訪問或者是修改,因此咱們須要加上鎖來避免這樣的狀況發生。

樂觀鎖則相反,基於樂觀假設,也就是說系統是基於可以順利運行不會有資源搶佔的狀況發生的前提進行的。也就是說先執行,執行以後若是發生了搶佔或者其餘問題,那麼再來經過重試或者其餘機制來解決

即便在高併發場景當中,資源衝突也是一個相對來講的小几率時間。若是使用悲觀鎖顯然會帶來大量的加鎖的開銷,因此基於樂觀鎖的設計會使得系統的併發性能更強。可是這也是有代價的,樂觀鎖也不是完美的,若是真的發生了大量競爭衝突的狀況,競爭失敗的一方每每須要重試任務,這會帶來不少沒必要要的開銷,也會形成資源的浪費

另外因爲全部框架之間的搶佔是自由的,也就是說有可能會出現高優先級的框架一直搶佔資源,而低優先級的任務被餓死的狀況發生。在這種機制下是沒有辦法保證任務之間的公平性的。這也是削弱中央調度器帶來的必而後果。

總結

咱們回顧一下以上三者策略,會發現這三者策略的演進順序其實就是中央調度器被削弱的順序。想一想其實很容易理解,中央調度器強大能夠維護整個集羣的公平性,可是因爲效率比較低,頗有可能會成爲整個集羣的瓶頸。而中央調度器越弱,框架調度器的自由度越高,整個系統調度的靈活性越強,那麼也就意味着系統的性能每每越好。

有人打了一個比方很是經典,集中式調度器有些像是計劃經濟。全部一切都由國家來規劃,好處是能夠保證公平,可是自由度和靈活性差,整個國家運轉和發展都不夠高效。兩級調度器有些像是大政府小市場的混合模式,政府的干預力度仍是很大,可是多了一點自由性。而狀態共享器則是小政府大市場的自由競爭經濟模式,政府的干預幾乎沒有了,變成了看不見的手,這樣能夠進一步提高靈活性和國家的運轉效率。可是國家的干預少了,當風險降臨的時候,也可能致使很大的問題。

某種程度上來講,和國家社會的制度沒有天衣無縫的同樣,集羣調度的策略目前來看也沒有一個完美的,各有各的優點和特長,須要咱們結合實際狀況,尋找適合咱們問題場景的最佳方案,這也是咱們學習這些底層原理而不僅是停留在如何使用上的緣由。

今天的文章就是這些,若是以爲有所收穫,請順手點個關注或者轉發吧,大家的舉手之勞對我來講很重要。

相關文章
相關標籤/搜索