作業(yè)在互聯(lián)網(wǎng)電商行業(yè)中是很常見的技術(shù)手段。當當具有成千上萬的作業(yè)規(guī)模,大致分為業(yè)務(wù)類,歸檔類,監(jiān)控類和大數(shù)據(jù)類。
當當原有的作業(yè)解決方案是Elastic Job,以下稱為Elastic Job 1.X。主要關(guān)注以下4個方面:
高可用。這里高可用指主從熱備。主節(jié)點提供服務(wù)的同時從節(jié)點處于等待狀態(tài)。一旦主節(jié)點失效,其中一個從節(jié)點通過選舉成為主節(jié)點繼續(xù)提供服務(wù),原來的主節(jié)點再次生效后,作為從節(jié)點繼續(xù)等待選舉機會。線性擴展。可理解為高可用的高階功能。既然多節(jié)點參與服務(wù)提供,若從節(jié)點只負責熱備,難免造成資源浪費,將主備調(diào)整為分片,則可大幅提升處理能力。中心化分布 式服務(wù)基本都是提供獨立的調(diào)度中心和執(zhí)行節(jié)點,調(diào)度中心提供主備,執(zhí)行節(jié)點可以彈性的線性擴展。Elastic Job1.X采用無中心化架構(gòu),并無調(diào)度中心,而是各個執(zhí)行節(jié)點通過Zookeeper選舉主節(jié)點進行分片、清理等動作,作業(yè)調(diào)度由執(zhí)行節(jié)點自行觸發(fā)。Elastic Job 1.X通過分片進行線性擴展,每個執(zhí)行節(jié)點負責處理被分配到的分片項,應(yīng)用開發(fā)者負責分片項和業(yè)務(wù)邏輯的對應(yīng)關(guān)系。代碼示例:public class MyElasticJob implements SimpleJob { @Override public void process(ShardingContext context) { switch (context.getShardingItem()) { case 0: // do something by sharding item 0 break; case 1: // do something by sharding item 1 break; case 2: // do something by sharding item 2 break; // case n: ... } }}容錯性。主要包括節(jié)點失效重分片、失效轉(zhuǎn)移、錯過任務(wù)重執(zhí)行以及分布式場景下的腦裂,網(wǎng)絡(luò)抖動容錯等。異構(gòu)語言。Elastic Job支持Java和Shell,基本能做到異構(gòu)語言支持。Elastic Job 的核心組件圖如下:
綠色部分是Elastic Job 1.X對開發(fā)者提供的API。藍色部分為內(nèi)部實現(xiàn),主要有選舉模塊、分片模塊、調(diào)度模塊、持久化模塊以及分布式協(xié)調(diào)模塊。持久化和協(xié)調(diào)均基于Zookeeper。
部署架構(gòu)圖如下:
Elastic Job 1.X與應(yīng)用代碼部署在一起,作為lib提供服務(wù)。Elastic Job 1.X和運維平臺通過注冊中心進行交互。
花了這些篇幅介紹背景,目的是讓大家了解當當原有的分布式作業(yè)解決方案,接下來將闡述新一代的平臺化作業(yè)解決方案。
隨著時代發(fā)展進步,分布式操作系統(tǒng)、容器以及各式各樣的容器編排治理方案層出不窮,站在巨人的肩膀上,可以更快速穩(wěn)定的搭建云平臺,基于這樣的考慮,我們決定擁抱革新。我們首先將目光投在了Docker上,希望將Elastic Job容器化,然后再選擇一個容器治理方案。經(jīng)過調(diào)研,我們轉(zhuǎn)而傾心Mesos,因為我們的目標不是容器化,而是云化,容器是實現(xiàn)云的一種手段,但合理的分布式編排系統(tǒng)更加關(guān)鍵。Docker本身有網(wǎng)絡(luò)、日志采集等問題需要解決。而Mesos將Docker作為可選容器支持,為了最小化采用新技術(shù)帶來的風險,我們決定將Docker容器化推遲,先將Elastic Job遷移至Mesos。這也得益于Mesos對Docker的無縫支持,以后加入對Docker的支持非常容易。
下圖是Mesos的核心概念:
藍色是Mesos的基礎(chǔ)組件,由Mesos Master、Mesos Agent和運維界面/API組成。Master/Agent的形式在分布式系統(tǒng)中很常見,如Hadoop map-reduce的JobTracker/TaskTacker。Mesos Master節(jié)點通過Zookeeper實現(xiàn)高可用,用于分配資源至注冊在Mesos的 Framework,Mesos Agent用于收集宿主機資源,如可用CPU、內(nèi)存、甚至GPU等,并負責執(zhí)行Mesos Framework分發(fā)的任務(wù)。Mesos Master與Slave間使用內(nèi)部API交互,通過遠程執(zhí)行部署在Mesos Agent的程序無需Mesos Agent所在服務(wù)器提供免登錄賬號。
紫色是Mesos Framework的組成部分。Mesos只有基礎(chǔ)組件并不能獨立使用,需要注冊Framework接收Mesos Master分配的資源并決定如何執(zhí)行,目前常見的Marathon和Chronos都是Mesos Framework。Framework的兩個重要組成是Scheduler和Executor。Scheduler和Mesos Master通過Scheduler API交互,負責將分配的資源生成任務(wù)并分發(fā)。Executor通過Executor API與Mesos Agent交互,負責執(zhí)行分配的任務(wù)并回告狀態(tài)。
紅色是Scheduler中兩個最重要的回調(diào)方法,resourceOffers和statusUpdate。
resourceOffers用于將資源轉(zhuǎn)化為任務(wù)并調(diào)用Executor執(zhí)行。資源分配算法,任務(wù)業(yè)務(wù)邏輯都應(yīng)在此方法中實現(xiàn)。
statusUpdate用于處理Executor回傳的狀態(tài)。可通過Executor的狀態(tài)傳遞和Scheduler的statusUpdate實現(xiàn)失效轉(zhuǎn)等的分布式協(xié)調(diào)功能。
Executor分為兩種。
Marathon和Chronos都使用Command Executor,這也是Mesos提供的內(nèi)置的Executor,可以直接執(zhí)行命令行腳本,也提供了基本的狀態(tài)回傳功能,對于普通應(yīng)用使用Command Executor是不錯的選擇。
自定義Executor可提供更多靈活性。下面舉幾個例子,但不限于僅實現(xiàn)這些功能。
日志重定向。Command Executor的日志會輸出到Mesos提供的沙箱中,通過自定義Executor可將日志重定向到其他文件,或?qū)悠渌罩臼占ぞ摺?strong>多任務(wù)復(fù)用。Command Executor與任務(wù)是一對一的關(guān)系。有些初始化資源非常耗時的場景,可以復(fù)用Executor,多線程并發(fā)處理多任務(wù)。執(zhí)行進度報告。Command Executor僅回告狀態(tài)變化,如需更加細化進度回告功能,需定制化處理。心跳檢測。可以通過Executor定時傳遞消息做心跳檢測。簡單的介紹了Mesos,是該討論下Mesos能帶來什么好處的時候了。Mesos可作為部署平臺和運行平臺使用。
作為部署平臺,Mesos可以做到應(yīng)用分發(fā)自動化。將應(yīng)用上傳到網(wǎng)絡(luò)地址(或Docker倉庫),Mesos能夠自動將應(yīng)用分發(fā)至需要執(zhí)行相關(guān)任務(wù)的Mesos Agent,省去人工部署成本。由于應(yīng)用自動分發(fā),那么CMDB將大大簡化,只需要管理Zookeeper服務(wù)器即可,Mesos Master、Mesos Agent以及其他部署在Mesos內(nèi)部的應(yīng)用均可用Mesos界面統(tǒng)一管理。美中不足是Mesos目前缺乏管理數(shù)據(jù)類服務(wù)器的成功案例,數(shù)據(jù)庫等部署在Mesos之外的應(yīng)用仍需獨立的CMDB管理。
作為運行平臺,Mesos可以將資源收集至統(tǒng)一資源池,做到硬件資源與應(yīng)用一體化,按需分配資源,自動資源回收,減少資源閑置和浪費。
應(yīng)用分發(fā)、資源分配和安全管理,即可形成云平臺的雛形,由于當當僅搭建私有云,安全管理暫時不是重點。
現(xiàn)在再分析Elastic Job 1.X的解決方案,應(yīng)用分發(fā)和資源分配部分是缺失的。
決定基于Mesos搭建作業(yè)云,我們開始調(diào)研實現(xiàn)方案。首先想到自然是擁抱開源,不重復(fù)發(fā)明輪子。方案A是使用Marathon作為調(diào)度框架。
方案A的優(yōu)點是可以實現(xiàn)應(yīng)用分發(fā)和資源分配,并且是高可用的解決方案。
但缺點同樣明顯:
資源分配靜態(tài)化,作業(yè)無論執(zhí)行與否均需預(yù)分配資源;Executor無法復(fù)用,對于Elastic Job這種對內(nèi)部狀態(tài)報告有要求的框架,需要在框架中通過第三方存儲匯報狀態(tài);跨機房等定制化功能較困難;使用繁瑣,需要使用Mesos、Marathon和Elastic Job 3個管理界面。另一種類似的方案是使用Chronos,可以做到動態(tài)資源分配,但缺點是:
不支持CRON表達式,對于原crontab或Quartz的應(yīng)用遷移不友好;不適合低延遲作業(yè),每次啟動初始化資源會消耗時間,導(dǎo)致作業(yè)延遲,反復(fù)初始化也容易造成資源浪費;定制功能仍然困難。說到這里需要拋出常駐作業(yè)和瞬時作業(yè)概念了。
常駐作業(yè)是作業(yè)一旦啟動,無論運行與否均占用系統(tǒng)資源;瞬時作業(yè)是在作業(yè)啟動時占用資源,運行完成后釋放資源。
常駐作業(yè)適合初始化時間長、觸發(fā)間隔短、實時性要求高的作業(yè),要求資源配備充足。
瞬時作業(yè)適合初始化時間短、觸發(fā)間隔長、允許延遲的作業(yè),一般用于資源不太充分,或作業(yè)要求的資源多,適合資源錯峰使用的場景。
由于上述缺點,我們最終選擇方案B。
我們決定自行開發(fā)Mesos Framework,項目的名稱叫做Elastic Job Cloud。優(yōu)點:
包含方案A的全部優(yōu)點;資源分配靜態(tài)與動態(tài)相結(jié)合,常駐與瞬時作業(yè)分離處理;Elastic Job 1.X的核心理念仍可沿用,包括分片,以及之前未提及的功能,如多種作業(yè)類型,事件統(tǒng)計等;易于定制化需求開發(fā)。Elastic Job Cloud核心組件圖如下:
綠色的API部分變化不大;紅色的內(nèi)部實現(xiàn)部分,無論是模塊本身,還是模塊的內(nèi)部實現(xiàn)均有大幅度調(diào)整。
選舉模塊由執(zhí)行節(jié)點主節(jié)點選舉變更為主Mesos Framework選舉,仍然依賴Zookeeper。
Sharding模塊功能未變,但從執(zhí)行節(jié)點主節(jié)點分片調(diào)整為Mesos Framework集中分片。Elastic Job 1.X的分片以IP為依據(jù),Elastic Job Cloud更改為以運行任務(wù)實例為依據(jù)。
調(diào)度引擎從去中心化執(zhí)行節(jié)點調(diào)度轉(zhuǎn)變?yōu)镸esos Framework的中心節(jié)點調(diào)度。
通過調(diào)度作業(yè)向任務(wù)隊列中寫入待執(zhí)行作業(yè)。
日志輸出方式變更為事件發(fā)布,可自行監(jiān)聽發(fā)布的事件,收集Elastic Job Cloud的運行狀態(tài),默認提供日志和數(shù)據(jù)庫(推薦)兩種事件收集方式。
通過Executor和Scheduler API配合進行分布式協(xié)調(diào),替換通過Zookeeper協(xié)調(diào)的方案,有效的減少了與Zookeeper的連接數(shù)。
Elastic Job Cloud作為Mesos Framework獨立部署,將作業(yè)信息存入Zookeeper。
雖然Elastic Job Cloud可以提供中心化云解決方案,但Elastic Job 1.X作為無中心化解決方案,仍適用于中小規(guī)模的分布式作業(yè)調(diào)度場景。我們并未放棄Elastic Job 1.X,將其更名為Elastic Job Lite。Elastic Job Lite和Elastic Job Cloud共同組成Elastic Job,核心組件全景圖如下:
Elastic Job Lite和Elastic Job Cloud使用統(tǒng)一的Elastic Job API,開發(fā)者在開發(fā)時無需關(guān)心最終的部署方式。部署在Lite或Cloud環(huán)境無需修改業(yè)務(wù)作業(yè)代碼,秩序調(diào)整配置和啟動方式即可。Lite和Cloud的差別僅在于云平臺需要的應(yīng)用分發(fā)和資源調(diào)度一體化。
目前Elastic Job Cloud已開發(fā)完成并在公司內(nèi)部試用。日前對接監(jiān)控系統(tǒng)的萬余作業(yè),全天運行峰值百萬左右。
Elastic Job Cloud的roadmap是:
公司內(nèi)部大規(guī)模推廣使用;Docker支持;任務(wù)優(yōu)先級、依賴以及編排的支持;跨機房部署、物理機隔離等功能開發(fā)。目前Elastic Job已全部開源。項目地址,歡迎感興趣的人踴躍嘗試。
最后我分享下我們這4個月以來的里程碑。
本文由當當網(wǎng)架構(gòu)專家張亮在CNUTCon北京2016 全球容器技術(shù)大會上的演講整理而成。