上週小數羞澀出鏡,和數人云架構師春明一塊兒爲你們進行了在線直播的乾貨分享,今天小數抱來了實錄,你們能夠一睹爲快啦!
本文從Mesos的基礎概念講起,不懂Mesos的小夥伴也徹底沒有問題,一步一步教你寫出優雅的Framework,讓Mesos更增強大好用:)java
今天主要和你們聊一聊Mesos、Marathon,以及數人云剛剛開源不久的一個Mesos Framework——Swan。nginx
微服務概念起來以後,不少大型互聯網公司須要把資源(好比說幾千臺機器、幾萬臺機器)抽象工做,讓更多人來使用。以前你們的作法比較粗暴,一個部門分幾百臺機器,一個項目分幾百臺機器,而後把程序裸跑在一些硬件或者虛擬機上,但這個過程當中資源的利用率不是很高。git
另外一方面,有些增長資源的場景中,增長一些機器很是緩慢,安裝、作機器的provision等等都很困難。所以一些聰明的工程師就萌生了一個想法:能不能把這些資源都抽象,須要的時候分配給不一樣的人來使用?這個背景誕生了Mesos,即資源調度的工具。資源調度器Mesos不是創新,它源自於Google Omega的論文,由Twitter的公司最先推出來。github
最近一段時間使用Mesos的API以及看代碼時間比較多,接下和你們分享一下我對Mesos內部的理解。golang
首先,Mesos是一個分佈式的架構,它分Mesos master和Mesos slave,slave和master分別有不一樣的職責。從Mesos的源代碼能夠看出Mesos實現得比較優雅——它是一個C++代碼。代碼中有大量的關鍵詞叫process,它不是傳統意義上的進程,而是一種抽象的libprocess,libprocess是它最核心的庫。若是你們之前使用過Erlang的語言就知道libprocess實際是對Erlang的IO和通信模型的一個抽象。算法
libprocess,在Erlang裏面也叫進程,其實是一個虛擬進程,在運行Erlang的VM上。它最優的特色是消息在不一樣的process之間傳遞,它抽象了process,消息傳遞實際上是一個事件的庫。向process裏發一個消息,這個消息不是直接打到process,而是中間有一個buffer的過程。編程
這樣作的優勢是特別適合分佈式的系統,之前最經常使用的作法是監聽網絡端口,有包來了,有一個模塊專門負責解這個包,解開一個協議後把這個協議發到後面一個處理進程,這個處理的進程多是IO操做,可能去作其它事情,而後裏面有不少IO上的Block,最後構造出一個response,經過一個socket傳給客戶端。這是最經常使用的一個寫網絡程序的辦法,可是這裏有一個大的IO上Block的地方——後面處理的邏輯依賴於解包的邏輯。若是處理邏輯很快,但解包邏輯很慢,後面會拖慢,都在等解包。瀏覽器
後來人們想到一種IO處理的方式,讓任何一個東西都是分離的,好比從某一個端口收到一個消息,有一個單獨的進程,一個線程或者其它的東西去處理這個惟一的請求。這個線程很重,後來你們又發明了一些其它的東西,好比golang裏面去搞一個channel,Erlang裏面去搞一個process。libprocess實際上作了IO方面的事情, Mesos大量使用這個模型。網絡
Mesos底層實際上依賴於Zookeeper,爲了保證分佈式存儲最終一致性。在Mesos運行過程當中產生了一些數據,最終都會落在Zookeeper。由於Mesos是多個master,爲了達到HA的需求,只要一個master活的,那麼整個服務就能獲得保證。架構
Mesos內部在通訊裏面選擇了protobuf協議。好處是比較流行,各個語言的庫都比較多,結構化的語義也比較強,因此Mesos內部選擇了protobuf。
至此,簡單介紹了Mesos內部的一些動做。接下來介紹Mesos提出的一些概念。
Mesos是一個分佈式的系統,分master和slave, master的部分主要協調任務的分發、一些資源的調度。slave是負責執行的部分,好比一個任務最終是slave去執行的。固然,能夠配在master執行。Mesos是一個雙層調度,slave處於下層,也就是說能夠動態的增長或者減小一些slave而不影響整個的任務池資源的變化,不影響上一層的任務。
Executor是真正的執行任務的邏輯。Mesos平臺不太區分須要執行什麼任務,因此它給用戶一些靈活性,能夠寫不一樣的Executor。好比最經常使用的Mesos運行容器的部分,就是一個Executor。還有Map Reduce的大型任務,一個Map、一個Reduce, Executor均可以執行。它的表現形式能夠是一個二進制,Mesos在運行時,slave會把Executor從遠程一個URL上拉下來,而後開始執行Executor。
Scheduler的意思是調度, Mesos master和slave把資源收上來以後,再把這些任務交給Scheduler,由Scheduler決定應該運行什麼Task。
Framework是雙層調度的上一層,也就是由Framework來決定到底該執行什麼任務,而後執行多少這樣的任務。
Offer是Mesos資源的抽象,好比說有多少CPU、多少memory,disc是多少,都放在Offer裏,打包給一個Framework,而後Framework來決定到底怎麼用這個Offer。
Task其實是運行的小任務。有兩大類Task,一大類咱們叫Long Running Task,好比Docker的一個進程或者其它的進程。另一類是Batch類型任務,這類應用很是普遍,好比說Map Reduce這麼一個小任務或者是定時任務。
這裏分別介紹一下剛纔提到的這些名詞,說一說它們都是如何工做的。
Mesos master是整個集羣的核心,master爲了保證高可用實際上是能夠跑多個master,分佈式系統爲了保證儘可能的高可用,實際上是能夠有多個master在那兒運行的。好比倒了幾個master,不會影響整個服務。Mesos master主要內部的工做有:Framework註冊或者Framework出了什麼問題,它來保證Framework的生命週期;slave的添加、slave的異常、slave的任務分配,我把它叫作slave的Lifecycle;Task Management,好比說Mesos master可能記錄了哪些Task運行在哪些slave上;Resource Allocation&Offer,就是說slave有什麼資源彙報給master,而後由master把這些任務交給註冊在這個master上的一些Framework。
slave能夠動態添加和減小,它lost不會影響整個服務,只是把這個事件(好比說一個slave掉了)由master去通知Framework。在Mesos slave代碼裏有大量執行器,即Executor的邏輯,由於全部Executor都是在slave上執行的,包括把Executor從遠程拉下來、開始執行Executor、開始執行launch task,維護task的生命週期,task fail瞭如何去作等等。
Mesos的定位是一些資源的調度,它把任務的調度交給了Framework來作,Mesos只關心資源以及把資源給了誰, Framework來決定哪些資源怎麼去使用。Mesos鼓勵Framework在上面共生。想象一下,做爲一個大型公司,有不少的資源,有核心的一組人來維護Mesos的集羣,不斷的往Mesos上添加資源和減小資源,而把Framework執行的能力交給其它的組、須要資源的那些組,各個組就能夠寫本身的Framework,丟到整個大的Mesos集羣上來執行了。Mesos框架上和執行上各類各樣的Framework,而Mesos自己也不瞭解爲何Framework工做,它只是知道把Offer給Framework,而後Framework告訴它來執行什麼樣的Executor。
Marathon Framework,它的任務偏Long Running,核心是application。由於Mesos只關注task自己,task偏向於小任務,不會產生什麼巨大的效應,而在企業裏面尤爲是彈性應用,更可能是一個應用,它有不少的實例來執行,這就是Marathon來作的。
Chornous是一個偏Job、定時任務類型,若是把定時任務以Docker形式發出來,這個Chornous是很是適合的。傳統的的Cron Job也是解決這類問題, Cron Job其實有很大的痛點,由於Cron Job是跑在主機上的,主機有limit的限制,如何把Cron Job放在多機上,須要有一個很好的哈希算法。到底如何把一堆單臺機器很難執行的多個job水平分佈在不少機器上,很麻煩。可是有了這個Chornous的Framework,事情就變得簡單多了。
它們倆區分度不是太大,有一些區分。Scheduler是作任務分配的,它從master上獲得一個Offer的事件,拿到Offer後,決定到底接受這個Offer仍是拒絕,接受這個Offer以後,把什麼樣的Task放在這個Offer上, Framework也開始佔用這個Offer,這是Scheduler作的事情。Scheduler Driver實際上是偏消息通訊的那一部分,而Scheduler可定製化特別強,在代碼裏看到Scheduler實際上是一個java的abstract glass,至關於一個interface,Framework本身去實現這麼一個東西。若是想寫一個Framework,其實大部分時間在如何寫好一個Scheduler實現這一部分。
若是Executor和Scheduler是對應的, Executor就是執行的這一部分。Mesos container這個Executor是Mesos本身提供的,不用寫Executor就能夠launch一個Docker的任務。但若是有一些本身的需求,就須要去實現一個Executor,好比七牛和樂視實現了一些Executor。
舉例來講,處理圖片、處理文件的Executor,偏向於這種小任務,寫一個Executor來實現這個interface,最終打成一個二進制,放在一個URL裏面。在Framework,slave就能夠把這個Executor拉下來,而後執行這個Tasks。Executor是一個獨立的二進制,它和master、和slave之間的通訊是要支持RBC的。
剛纔已經提到了Marathon基本的功能,Marathon做爲一個Long Running上一層的調度機制,爲用戶作了不少有意義的事情。單純一個Mesos的話作不了什麼,由於Task的力度特別小,Mesos的功能更偏重於資源的管理、資源的調度,Marathon更偏向於一些任務。
Marathon提出了幾個概念,最核心的概念叫application,還有Group的application,是一組的application。一個application是什麼呢?好比一個Rails的任務、NodeJS任務或者其它的一些任務,在部署的時候並非部署一個Task,而是部署很是多的Task,application就是一組Task。這個Task在Marathon裏面叫instance,能夠選擇scale down或者scale up這些instance,這些任務最終交給Mesos,Mesos調度到不一樣的slave上。
圍繞着這個application,Marathon就提供了一些概念叫Group,Group是一組application。舉例來講,在內部可能有不少的微服務,這些微服務達到同一個目標,好比說服務之間還有調用、還有依賴,這時去發一個Group application就比較好用。但實際工做中,由於生產級別的服務對穩定性的要求很高, Group之間其實假設服務和服務之間是有必定的依賴。
Marathon提供了一個有意思的feature—— rolling update。假若有APP的新版本上來,它能夠經過必定的機制去發多個版本,並且能夠多個版本共存。若是那個新版本沒有問題的話,能夠繼續preceeding deployment。若是有問題的話,能夠Rollback。這時有兩個概念Deployment和Version,能夠選定哪個Version,想Rollback哪一個Version。Deployment是每次update,每次更新、每次從新的Deployment、每次scale,都會在內部生成一個Deployment,和應用一對多有關。有趣的是Deployment之間是不能夠重疊的,Deployment是一種部署排隊的機制,Deployment不能夠多個同時進行,既想update又想scale,會讓Marathon崩潰。
Marathon scale和rolling update的功能都很是有用,好比新浪微博如今有一個大的事件,須要更多的Task頂上來,馬上 scale up,只要資源足夠就能夠無限多的Task生成。Rollback,若是有一個版本有問題,能夠瞬間Rollback到之前一個健康的版本。
雖然Mesos對下面的資源作了一些抽象,可是有時候有一些傾向性,好比但願CPU使用率比較高的一些任務調度到CPU比較好的機器上,須要一種在調度上的傾向性來知足剛纔的場景。不少調度器都有相似的功能,叫Constraints,好比一臺主機的label,要把Task打到一組主機這樣的Label上或者是Host name like,這是Marathon作的,Mesos不用作這類的事情。
Marathon的接口很是友好,都是HTTP的接口。Mesos的接口by design不是面向最終用戶,因此它的接口並非那麼友好。馬拉松的UI也很是漂亮,尤爲是新版。
最後介紹一下Swan(https://github.com/Dataman-Cl... )這個項目,Swan是最近數人云作的一個Mesos的Framework,定位是作一個General Purpose Long Running Task的Framework。數人云使用馬拉松較長時間,發現不太知足需求,好比很難作一些定製化,控制不住它的發展趨勢。咱們但願研發一款工具既有馬拉松的功能又自主可控、添加一些想要的featur,具體的feature會在下文中逐一介紹。
咱們但願這個通用性的Framework在任何狀況下,服務不會受到影響。由於Mesos HA這方面已經作得很好,因此Framework不會是單點,首先Swan要支持HA,由於受到Swarmkit啓發比較大, Swarmkit天生就是Raft協議,在一堆manager中只要有一個活的,就能健康的對外服務。
Marathon沒怎麼作服務發現,無非是把端口暴露出來,哪一個任務在哪些IP和端口上,經過API的形式告訴給外面。Swan裏內置服務發現,會有一個列表告訴外面哪些服務跑在哪些端口、哪些APP上。
DNS是服務發現的另外一種。主流的一些Framework都把DNS這個功能放在了比較核心的位置,好比K8s裏面的SkyNet,Mesos曾經之前有Mesos DNS,以及Swarmkit,Swarm的服務發現分爲DNS Round Robin和IPVS兩種,把DNS放在Swan這個模塊裏更加的可控。它不單是一個DNS,同時是一個DNS的代理。這樣最終能實現的效果,在企業內部經過咱們的DNS和用戶的DNS來混搭,來達到一種Mesos內部和外部互相調用,在瀏覽器上既能夠訪問Mesos內部的東西又能夠訪問外面的東西,達到比較完美的效果。
Proxy,並不單是Proxy,還有負載均衡。最多見的Proxy的工具備HAProxy或者nginx。 HAProxy和nginx雖然很優秀、性能很好,缺點是可控性太差,很難控制它。HA可編程的能力不好,Nginx可編程的能力不錯,新浪微博有一個項目叫upsync-module,很是優秀。以前評估過這個項目,發現集成這兩個的難度很大。
個人分享就到這裏,謝謝你們。