在代碼的編寫、編輯、測(cè)試與發(fā)布等工程流程當(dāng)中,我們需要依靠后端服務(wù)及設(shè)備以執(zhí)行各類任務(wù),具體包括構(gòu)建新軟件包、安裝依賴關(guān)系并運(yùn)行測(cè)試任務(wù)??紤]到Facebook極為可觀的業(yè)務(wù)規(guī)模,執(zhí)行上述工作的員工數(shù)量及職務(wù)種類每一天都可能不斷增加,這顯然會(huì)成為系統(tǒng)性能的瓶頸所在。我們的目標(biāo)在于盡可能減少工程師在設(shè)備上的等待時(shí)長(zhǎng),確保其能夠快速獲取反饋,并將更多時(shí)間與精力投入到生產(chǎn)任務(wù)身上。每項(xiàng)任務(wù)實(shí)際上都運(yùn)行在一個(gè)被稱為“工作程序”的隔離環(huán)境當(dāng)中,而這些環(huán)境則分布在不同數(shù)據(jù)中心的不同主機(jī)之上。各工作程序會(huì)通過預(yù)配置以針對(duì)某些特定任務(wù)類型進(jìn)行優(yōu)化——例如輸入的Android任務(wù)會(huì)被交付至擁有正確代碼庫且完成了依賴性更新的工作程序處。此類分布式系統(tǒng)需要一些保障性機(jī)制以可靠且高效地為正確的工作程序交付對(duì)應(yīng)的任務(wù)內(nèi)容。作為一類常見解決方案,人們通常會(huì)利用分布式隊(duì)列以及調(diào)度器/調(diào)度程序系統(tǒng)等追蹤當(dāng)前全書狀態(tài),并嘗試以最佳方式進(jìn)行工作負(fù)載分配。然而,這些解決方案亦各有利弊; 舉例來說,調(diào)度器往往會(huì)對(duì)系統(tǒng)的可擴(kuò)展性造成負(fù)面影響。在今天的文章中,我們將介紹的Jupiter項(xiàng)目正是專門為此而生——一項(xiàng)負(fù)責(zé)任務(wù)匹配的服務(wù)。對(duì)于各工作程序,其職能的本質(zhì)在于對(duì)其特征或者所能處理之任務(wù)的聲明。其中的具體特征可能表現(xiàn)為內(nèi)存大小、工作程序所處之?dāng)?shù)據(jù)中心、設(shè)備的當(dāng)前負(fù)載因子、工作程序接入的智能手機(jī)型號(hào)以及預(yù)加載至設(shè)備之上的存儲(chǔ)庫或數(shù)據(jù)部件等等。每個(gè)工作程序都擁有多項(xiàng)功能與特征,且各功能特性在實(shí)際上屬于一個(gè)或者一組值(例如,內(nèi)存大小即為一個(gè)值,而多套預(yù)加載源代碼庫則為一組值)。同樣的,不同任務(wù)亦會(huì)對(duì)其所需功能特性提出要求。舉例來說,資源密集型構(gòu)建任務(wù)需要強(qiáng)大的設(shè)備作為支持; 特定代碼庫中的CI任務(wù)更適合由已經(jīng)預(yù)加載對(duì)應(yīng)代碼的工作程序來完成; 需要特定內(nèi)核版本的任務(wù)只能匹配運(yùn)行在該內(nèi)核之上的工作程序; 而一組分布式構(gòu)建任務(wù)則最好能夠在集群環(huán)境下執(zhí)行。
在由更新與并發(fā)請(qǐng)求構(gòu)成的持續(xù)流當(dāng)中,我們往往很難準(zhǔn)確對(duì)具有多維功能要求的任務(wù)進(jìn)行快速匹配。而作為一項(xiàng)服務(wù),Jupiter非常擅長(zhǎng)高效響應(yīng)工作程序的任務(wù)要求,同時(shí)追蹤當(dāng)前可用的工作負(fù)載,且確切符合工作程序與負(fù)載需求所作出的多層級(jí)功能限定條件。Jupiter服務(wù)能夠?yàn)楣ぷ髌ヅ涮峁┗A(chǔ)性保障——即使同時(shí)存在多項(xiàng)請(qǐng)求,每項(xiàng)任務(wù)也只會(huì)被分配給一個(gè)工作程序; 而一旦工作程序確認(rèn)收到該任務(wù),那么此任務(wù)將不再進(jìn)行分配。與眾多其它Facebook后端服務(wù)一樣,Jupiter服務(wù)同樣由C++編寫而成,且可通過Thrift進(jìn)行訪問。Jupiter擁有橫向可擴(kuò)展性——意味著其能夠進(jìn)行輕松拆分,并確保其中各個(gè)分區(qū)根據(jù)不同任務(wù)集要求作出獨(dú)立決策,且不存在任何負(fù)責(zé)全部判斷的單一領(lǐng)導(dǎo)節(jié)點(diǎn)。Jupiter強(qiáng)調(diào)任務(wù)隊(duì)列順序,各分區(qū)可采取最為簡(jiǎn)單的先進(jìn)先出型排序策略,但亦支持其它一些更為復(fù)雜的概念——例如作業(yè)優(yōu)先級(jí)機(jī)制。在性能方面,Jupiter服務(wù)的每個(gè)分區(qū)每秒能夠處理數(shù)十萬項(xiàng)請(qǐng)求。工作程序向Jupiter發(fā)送請(qǐng)求以描述其具備的全部功能特性,而Jupiter則查詢內(nèi)部數(shù)據(jù)結(jié)構(gòu)以找到最佳匹配選項(xiàng)。在實(shí)際生產(chǎn)工作負(fù)載場(chǎng)景下,Jupiter的任務(wù)獲取請(qǐng)求延遲通常在數(shù)十微秒左右。收取到合適的任務(wù)后,工作程序?qū)⑾騄upiter發(fā)送新的請(qǐng)求以確認(rèn)接受或者加以拒絕。如果加以拒絕,則該任務(wù)會(huì)被放置在請(qǐng)求所指定的暫存區(qū)域內(nèi); 在此段時(shí)間中該任務(wù)無法被分配給其它工作程序。Jupiter亦可對(duì)接各類不同類型的API使用方式。舉例來說,工作程序可以向Jupiter發(fā)送租約請(qǐng)求,通知自身已經(jīng)開始處理相關(guān)任務(wù),但只有在真正成功處理完成后方可進(jìn)行確認(rèn)。從高層級(jí)角度來看,全部Jupiter客戶皆遵循獲取任務(wù)、確認(rèn)工作、處理工作并再次循環(huán)這一基本模式。
由于Jupiter掌握著隊(duì)列中全部任務(wù)的相關(guān)信息,因此其亦能夠執(zhí)行高級(jí)調(diào)度決策——例如僅在某些高優(yōu)先級(jí)任務(wù)完成后才允許向工作程序提供其它任務(wù)。在大多數(shù)情況下,Jupiter的主要優(yōu)勢(shì)在于能夠通過一組(異構(gòu))工作程序高效消費(fèi)處理能力,同時(shí)實(shí)現(xiàn)理想的可靠性與原子性。在Facebook公司,Jupiter被用于支持各類不同內(nèi)部客戶——包括我們的資源管理系統(tǒng)One World以及我們的持續(xù)集成系統(tǒng)Sandcastle。由于數(shù)據(jù)與匹配模塊之間的API邊界非常明確,因此與新系統(tǒng)之間的集成也就非常簡(jiǎn)單。同樣值得一提的是,Jupiter在某些場(chǎng)景下并不適用。其并不屬于數(shù)據(jù)持久層。因此如果需要對(duì)任務(wù)數(shù)據(jù)進(jìn)行記錄,則應(yīng)由數(shù)據(jù)產(chǎn)生方負(fù)責(zé)進(jìn)行——而Jupiter則僅不斷從持久層處獲取增量更新以保持上下文同步。之所以選擇這樣的處理方式,主要出于兩大考量。第一,我們認(rèn)為服務(wù)應(yīng)該專注于特定任務(wù),而非面向一切需求。第二,通過將任務(wù)存儲(chǔ)與任務(wù)匹配加以拆分,我們能夠確保Jupiter不致成為整體系統(tǒng)中的單點(diǎn)故障來源:一旦Jupiter發(fā)生故障,任務(wù)生產(chǎn)方仍然能夠以隊(duì)列方式正常運(yùn)作; 而Jupiter順利恢復(fù)后,全部隊(duì)列內(nèi)工作則可繼續(xù)由其交付至工作程序。Jupiter將數(shù)據(jù)供應(yīng)接口背后的所有狀態(tài)操作抽象出來,這意味著其能夠隨意使用選定的任意存儲(chǔ)引擎——包括關(guān)系型數(shù)據(jù)庫、分布式文件系統(tǒng)或者是在無需對(duì)數(shù)據(jù)加以持久保留的情況下使用Jupiter的內(nèi)存內(nèi)存儲(chǔ)。Jupiter亦不具備對(duì)工作程序狀態(tài)的全局性了解(例如特定時(shí)間點(diǎn)上哪些工作程序正處于忙碌狀態(tài),或者哪些工作程序有能力處理某一任務(wù)),亦無法將任務(wù)的具體分配趨向作出任何中央式?jīng)Q策。相反,Jupiter的惟一原則就是以高效方式進(jìn)行任務(wù)分配,這是因?yàn)楣ぷ鞒绦蛑回?fù)責(zé)提出其適合處理的任務(wù)類型、而任務(wù)本身則提出工作程序所需要具備的具體特性——在其之中,Jupiter將作為有效的仲裁者,單純?yōu)樽钸m合處理對(duì)應(yīng)任務(wù)的工作程序提供接入任務(wù)負(fù)載的途徑。總而言之,Jupiter是一項(xiàng)高效的任務(wù)匹配服務(wù),非常適用于生產(chǎn)者/消費(fèi)者類型的分布式系統(tǒng)。通過將全局任務(wù)保留在這項(xiàng)專用服務(wù)當(dāng)中,Jupiter的功能完全可供各類其它系統(tǒng)引入并使用。最后,希望我們的這一實(shí)踐經(jīng)驗(yàn)與發(fā)現(xiàn)能夠?yàn)檐浖こ填I(lǐng)域帶來更為廣泛的助益。
查看英文原文:https://code.facebook.com/posts/222017798302928/jupiter-a-high-performance-job-matching-service/