劉福鑫,李勁巍,王熠弘,李 琳
(武漢理工大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院,武漢430070)
云計(jì)算已成為互聯(lián)網(wǎng)未來的趨勢之一,擁有不可估量的潛力[1]。云應(yīng)用和云平臺(tái)的普及使開發(fā)者能夠?qū)⒏嗟木ν度胗趹?yīng)用程序本身的開發(fā)與維護(hù)上,不用再關(guān)心硬件架構(gòu)、服務(wù)器資源與日常硬件維護(hù)等與業(yè)務(wù)本身無關(guān)的雜項(xiàng)工作。近年來,越來越多的業(yè)務(wù)開始從傳統(tǒng)的服務(wù)器架構(gòu)遷移到云上,同時(shí)我們也看到有更多的業(yè)務(wù)從設(shè)計(jì)之初即計(jì)劃運(yùn)行在云端。這些業(yè)務(wù)通常被稱作云原生業(yè)務(wù),意指其與云的高度結(jié)合。云原生業(yè)務(wù)相對傳統(tǒng)業(yè)務(wù)通常會(huì)更加充分且頻繁地應(yīng)用例如微服務(wù)、彈性計(jì)算和服務(wù)編排等云平臺(tái)所提供的先進(jìn)技術(shù)幫助業(yè)務(wù)更穩(wěn)定、高效地運(yùn)行。部分前沿實(shí)踐甚至嘗試使用更加輕量的操作系統(tǒng)(如Alpine Linux 等)來適應(yīng)容器化和虛擬化技術(shù)[2]。
當(dāng)前較為典型的云原生業(yè)務(wù)是移動(dòng)互聯(lián)網(wǎng)時(shí)代的社交平臺(tái),這些平臺(tái)大多充分利用了云計(jì)算的優(yōu)勢,比如微博廣泛使用阿里云作為其計(jì)算后端,構(gòu)建大規(guī)?;旌显疲瑢⒉糠指哳l業(yè)務(wù)運(yùn)行于公有云平臺(tái)上,以靈活處理熱點(diǎn)事件的突發(fā)負(fù)載[3]。社交平臺(tái)的用戶量不斷增加,且對計(jì)算和存儲(chǔ)的需求極大,這不僅需要靈活而穩(wěn)定的基礎(chǔ)架構(gòu)來保障其穩(wěn)定性,還要利用自動(dòng)化擴(kuò)容與災(zāi)備等高級功能使其在突發(fā)負(fù)載下依舊為用戶提供良好的體驗(yàn)[4]。
早在2010 年,F(xiàn)acebook 就已發(fā)表了其應(yīng)對大規(guī)模照片與文件存儲(chǔ)的方案,這一方案被稱為Haystack。Haystack是一個(gè)專注于海量文件存儲(chǔ)的對象存儲(chǔ)系統(tǒng),它充分滿足Facebook對文件的存儲(chǔ)需求。它使用文件塊將小文件打包進(jìn)名為Superblock的物理卷中,并將元數(shù)據(jù)緩存在內(nèi)存里以獲得極高的索引和查詢性能。它同樣支持集群化部署,能夠?qū)⒋鎯?chǔ)負(fù)載進(jìn)行分散,以有效提升性能與可擴(kuò)展性[5]。
隨著近些年來云計(jì)算的普及,互聯(lián)網(wǎng)展現(xiàn)出了整體向云上遷移的趨勢,以便充分享受云平臺(tái)所帶來的高效與穩(wěn)定。但Haystack 及其大多數(shù)相似實(shí)現(xiàn)卻依舊被設(shè)計(jì)為運(yùn)行在傳統(tǒng)硬件架構(gòu)上,需要相對復(fù)雜的配置才能使其運(yùn)行于云端,這與云原生開箱即用、輕量部署的理念有一定差距。若出現(xiàn)熱點(diǎn)事件或用戶量極速增長,手動(dòng)擴(kuò)容集群規(guī)模往往不能及時(shí)應(yīng)對突發(fā)壓力,甚至在擴(kuò)容過程中還會(huì)由于節(jié)點(diǎn)拓?fù)錈o法在線修改,引發(fā)不可避免的閃斷,降低服務(wù)可用性。此外,上述存儲(chǔ)方案在緩存與資源利用上的缺失,同樣導(dǎo)致了它們大多并不能充分利用云所能提供的資源與環(huán)境,所提供的性能依舊不夠理想,這一問題也影響了該類存儲(chǔ)方案的普及。
綜上所述,無論是傳統(tǒng)的文件系統(tǒng)還是當(dāng)前的對象存儲(chǔ)系統(tǒng),其設(shè)計(jì)與優(yōu)化都不能充分滿足數(shù)據(jù)密集型業(yè)務(wù)在云上不斷擴(kuò)張的需求,原因主要在于上述存儲(chǔ)方案大多都無法充分利用云平臺(tái)所提供的調(diào)度功能,適應(yīng)負(fù)載的波動(dòng)并利用以上功能實(shí)現(xiàn)自動(dòng)化調(diào)度,進(jìn)一步實(shí)現(xiàn)自我優(yōu)化、自我管理。
為了解決以上問題,本文提出了一種新的存儲(chǔ)系統(tǒng),稱之為Kubestorage,指運(yùn)行在Kubernetes 上的存儲(chǔ)系統(tǒng)。該系統(tǒng)基于Haystack,但在服務(wù)發(fā)現(xiàn)和自動(dòng)容錯(cuò)等宏觀調(diào)度方面進(jìn)行了專門優(yōu)化,使其更符合云原生技術(shù)的定義,更適合部署在云端,也更適合于在存儲(chǔ)方面驅(qū)動(dòng)數(shù)據(jù)密集型的云業(yè)務(wù)高效穩(wěn)定運(yùn)行;此外還針對Haystack 于磁盤方面的性能瓶頸,在緩存與易用性方面進(jìn)行了優(yōu)化。
學(xué)術(shù)界在對象存儲(chǔ)方面的研究要遠(yuǎn)早于云計(jì)算。早在1996 年,卡內(nèi)基梅隆大學(xué)就開始了由Garth Gibson 領(lǐng)導(dǎo)的相關(guān)研究,并于1998 年首次提出了對象存儲(chǔ)的概念與基礎(chǔ)架構(gòu)[6]。此后,對象存儲(chǔ)在各存儲(chǔ)公司的支持下持續(xù)蓬勃發(fā)展。據(jù)統(tǒng)計(jì),在1999 年到2013 年之間,在對象存儲(chǔ)方面的風(fēng)險(xiǎn)投資已突破3 億美元[7],這使得對象存儲(chǔ)技術(shù)得到了極大的發(fā)展,并迅速應(yīng)用于大量成熟的產(chǎn)品中。
美國亞馬遜公司旗下的AWS(Amazon Web Services)早在2006年初就將對象存儲(chǔ)作為開放服務(wù),開發(fā)了亞馬遜S3對象存儲(chǔ)服務(wù)。僅2012年一年,S3對象存儲(chǔ)系統(tǒng)就新增了超過一萬億個(gè)對象,而在短短一年后,甚至增加到每年新增兩萬億個(gè)對象。此外,S3 還能確保這些數(shù)據(jù)可以隨時(shí)被訪問與隨機(jī)讀寫。據(jù)亞馬遜官方報(bào)告,S3 中的任意一個(gè)文件都可以承載每秒最高110萬次的讀?。?]。
另一個(gè)相對較為知名的對象存儲(chǔ)解決方案是由Weil、Brandt、Miller、Long 和Maltzahn 在2006年USENIX 操作系統(tǒng)設(shè)計(jì)會(huì)議(OSDI 2006)中提出的Ceph[9]。Ceph 在軟件層面進(jìn)行大量優(yōu)化,能使用普通硬件實(shí)現(xiàn)大規(guī)模的文件存儲(chǔ),相對于來自IBM、EMC等大型存儲(chǔ)方案公司的產(chǎn)品擁有更好的兼容性。
Facebook 公司在2010 年通過論文的形式提出了一種專注于大量小文件的存儲(chǔ)、更實(shí)用且更靈活的對象存儲(chǔ)模型,稱之為Haystack。Haystack 的獨(dú)特之處在于將小文件合并到一個(gè)稱為物理卷的文件塊中,以便在存儲(chǔ)大量小文件的同時(shí)保持較為理想的索引速度。文件索引則包含了文件的基礎(chǔ)信息、文件在文件塊中的偏移量等元數(shù)據(jù)。此外,文件索引被讀入內(nèi)存中,以此提升索引速度,降低磁盤負(fù)擔(dān)。
Kubestorage存儲(chǔ)系統(tǒng)由三部分組成:
1)目錄服務(wù)器,用于節(jié)點(diǎn)信息的存儲(chǔ)、文件到存儲(chǔ)節(jié)點(diǎn)的映射、節(jié)點(diǎn)自動(dòng)管理與負(fù)載均衡等功能。
2)存儲(chǔ)服務(wù)器,用于文件存儲(chǔ)、元數(shù)據(jù)管理和存儲(chǔ)一致性的自動(dòng)維護(hù)。
3)緩存服務(wù)器,用于緩存高頻訪問的文件,以獲得更好的性能。
整個(gè)存儲(chǔ)系統(tǒng)運(yùn)行在以Docker 為容器后端的Kubernetes集群之上,通過Kubernetes 配置文件的方式進(jìn)行快速部署,Kubernetes負(fù)責(zé)提供管理、服務(wù)發(fā)現(xiàn)與故障恢復(fù)等功能。
Kubestorage 為解決Haystack 和其他存儲(chǔ)解決方案的缺點(diǎn),進(jìn)行了以下改進(jìn):
1)使用Raft 一致性算法[10]實(shí)現(xiàn)了對多目錄服務(wù)器的支持,使目錄服務(wù)器更穩(wěn)定、可靠,避免單點(diǎn)故障造成整個(gè)存儲(chǔ)系統(tǒng)失效。
2)相較于Haystack,Kubestorage 并未將存儲(chǔ)服務(wù)器直接暴露給外部用戶或業(yè)務(wù),而是使用反向代理由目錄服務(wù)器與業(yè)務(wù)進(jìn)行讀取與寫入操作以提升安全性,同時(shí)增強(qiáng)目錄服務(wù)器對整體的控制能力。鑒于Kubernetes 環(huán)境下虛擬交換機(jī)帶寬大于傳統(tǒng)服務(wù)器互聯(lián)帶寬,且可以通過負(fù)載均衡器實(shí)現(xiàn)集群部署,因此相對于帶寬瓶頸,相對應(yīng)的安全性與簡便性提升更有價(jià)值。
目錄服務(wù)器為業(yè)務(wù)提供單點(diǎn)API,涵蓋所有的讀寫與管理操作,以便簡化業(yè)務(wù)開發(fā),避免存儲(chǔ)服務(wù)器暴露所導(dǎo)致的安全隱患。
3)定期巡檢所有文件,并自動(dòng)壓縮長時(shí)間未訪問的數(shù)據(jù),以節(jié)省存儲(chǔ)空間.
4)使用多級緩存機(jī)制以最大限度地降低檢索文件以及從磁盤中讀取文件造成的性能損失。
5)自動(dòng)將經(jīng)常訪問的文件復(fù)制到多個(gè)存儲(chǔ)服務(wù)器中,以分散文件讀取壓力,實(shí)現(xiàn)負(fù)載均衡。
此外,Kubestorage 還充分利用了容器化的特性和Kubernetes 所提供的豐富功能,保證了在不同軟硬件上運(yùn)行環(huán)境的一致性,并在此基礎(chǔ)上使其具有如下更多功能:
1)動(dòng)態(tài)監(jiān)測所有Kubestorage 節(jié)點(diǎn)的狀態(tài),并在磁盤空間、CPU配額、內(nèi)存空間不足時(shí)自動(dòng)擴(kuò)容。
2)自動(dòng)運(yùn)行狀況檢查,其中包括一致性檢查、有效性校驗(yàn)、延遲檢查、壓力測試與硬件健康檢查。
3)基于kube-apiserver 與kube-dns 的自動(dòng)服務(wù)發(fā)現(xiàn),可在服務(wù)不中斷的情況下動(dòng)態(tài)修改存儲(chǔ)集群拓?fù)?,提升Kubestorage的可用性。
Kubestorage 的詳細(xì)架構(gòu)如圖1 所示,主要由目錄服務(wù)器、存儲(chǔ)服務(wù)器和緩存服務(wù)器三個(gè)部分組成。
目錄服務(wù)器主要承擔(dān)以下工作:
1)管理邏輯卷和物理卷之間的映射;
2)管理目錄服務(wù)器級別緩存;
3)當(dāng)某個(gè)文件訪問量激增時(shí),開啟自動(dòng)文件冗余,在多個(gè)存儲(chǔ)服務(wù)器上建立該文件的副本以提升吞吐能力;
4)作為負(fù)載均衡器,對存儲(chǔ)服務(wù)器進(jìn)行反向代理,并向外部業(yè)務(wù)提供統(tǒng)一的API。
同時(shí),Kubestorage還具有以下功能,使其更適合自動(dòng)化集群部署,并提供一致性與可靠性保障:
1)使用Raft 一致性算法提供較高的一致性與可靠性,避免單點(diǎn)故障導(dǎo)致整個(gè)存儲(chǔ)系統(tǒng)失效,外部業(yè)務(wù)對附屬節(jié)點(diǎn)的訪問將會(huì)被轉(zhuǎn)發(fā)到主節(jié)點(diǎn)。該算法保證了數(shù)據(jù)的一致性與可靠性,使得在每個(gè)輪換周期內(nèi)有且僅有一個(gè)目錄服務(wù)器負(fù)責(zé)響應(yīng)用戶請求。
2)Kubernetes 將會(huì)對每臺(tái)目錄服務(wù)器設(shè)置3 個(gè)預(yù)設(shè)標(biāo)簽:角色、狀態(tài)和健康度。例如角色為kube-storage-directory,狀態(tài)為leader 或slave,運(yùn)行狀況將是以下4 種類型之一:正在運(yùn)行(Running)、正在初始化(Initializing)、忙碌(Busy)或離線(Offline)。當(dāng)每個(gè)目錄服務(wù)器需要知道其他目錄服務(wù)器的狀態(tài)和數(shù)量時(shí),可以使用這3 個(gè)標(biāo)簽作為選擇器,向kubeapiserver 詢問目錄服務(wù)器列表,kube-apiserver 將返回集群內(nèi)滿足所選擇條件的服務(wù)器。
3)為了保障數(shù)據(jù)一致性,避免使用讀/寫鎖造成系統(tǒng)邏輯復(fù)雜化,所有目錄服務(wù)器將會(huì)共享一個(gè)數(shù)據(jù)庫后端。數(shù)據(jù)庫后端的種類可以根據(jù)實(shí)際需求自由決定,但以Redis為例的內(nèi)存數(shù)據(jù)庫通??梢蕴峁┳罴训男阅?。
此外,目錄服務(wù)器還會(huì)記錄最近的文件讀取請求并存儲(chǔ)在數(shù)據(jù)庫內(nèi)該文件對應(yīng)的記錄中,然后定期讀取上一個(gè)巡檢周期內(nèi)各文件訪問次數(shù)。對于頻次超過設(shè)定閾值的文件,目錄服務(wù)器會(huì)使用存儲(chǔ)服務(wù)器的冗余寫入API 進(jìn)行自動(dòng)冗余,依靠在多個(gè)服務(wù)器上建立該文件的副本以提升性能,若下一次巡檢發(fā)現(xiàn)已冗余的文件訪問量低于閾值,目錄服務(wù)器則會(huì)使用冗余刪除API進(jìn)行已冗余文件的移除。
圖1 Kubestorage的架構(gòu)示意圖Fig.1 Schematic diagram of Kubestorage architecture
存儲(chǔ)服務(wù)器主要承擔(dān)以下工作:
1)負(fù)責(zé)管理存儲(chǔ)在其中的文件、文件的元數(shù)據(jù)以及文件的寫入和讀?。?/p>
2)管理存儲(chǔ)服務(wù)器級別緩存;
3)執(zhí)行數(shù)據(jù)壓縮、解壓縮與有效性校驗(yàn);
4)定期向目錄服務(wù)器報(bào)告其狀態(tài),以便根據(jù)統(tǒng)計(jì)信息進(jìn)行自動(dòng)化管理。
存儲(chǔ)服務(wù)器的技術(shù)實(shí)現(xiàn)如下:
1)元數(shù)據(jù)和物理卷的底層存儲(chǔ)與Haystack 基本一致,但Kubestorage 在此基礎(chǔ)上增加了對壓縮文件的支持,文件是否被壓縮的狀態(tài)被存儲(chǔ)在元數(shù)據(jù)中,并在寫入時(shí)壓縮存入,讀取時(shí)解壓讀取。
2)Kubernetes所提供的持久卷(Persistent Volume)將用作存儲(chǔ)服務(wù)器的存儲(chǔ)后端。它具有高度抽象的特性,獨(dú)立于特定的操作系統(tǒng)、存儲(chǔ)架構(gòu)和硬件,可以與現(xiàn)有的存儲(chǔ)方案良好兼容,并可避免計(jì)算與存儲(chǔ)的強(qiáng)耦合。為了使Kubestorage 盡可能簡潔,冗余和高可用由實(shí)際的存儲(chǔ)后端自主實(shí)現(xiàn),以充分利用磁盤/網(wǎng)絡(luò)存儲(chǔ)行業(yè)中長期的技術(shù)積累。
3)Kubestorage 選擇了較為松散的元數(shù)據(jù)存儲(chǔ)后端結(jié)構(gòu),以接口方式實(shí)現(xiàn),使其能充分利用云平臺(tái)中所提供的數(shù)據(jù)庫服務(wù)進(jìn)行元數(shù)據(jù)的存儲(chǔ)。此外,為了簡化部署和使用,Kubestorage搭載了leveldb[11]作為其默認(rèn)數(shù)據(jù)庫。該數(shù)據(jù)庫在存儲(chǔ)量較小但訪問頻次較高、數(shù)據(jù)結(jié)構(gòu)單一的情況下可以實(shí)現(xiàn)用很少的資源消耗提供相對理想的性能,避免普通文件數(shù)據(jù)庫頻繁磁盤讀寫與復(fù)雜存儲(chǔ)結(jié)構(gòu)造成的性能瓶頸。
4)每個(gè)存儲(chǔ)服務(wù)器將定期運(yùn)行自檢服務(wù),獲取當(dāng)前存儲(chǔ)容量、并發(fā)讀寫狀態(tài)、文件數(shù)量、硬件健康狀態(tài)、網(wǎng)絡(luò)情況以及其他所需信息,并提供API,便于外部查詢服務(wù)器狀態(tài)。自檢服務(wù)使得目錄服務(wù)器、Kubernetes、甚至運(yùn)維人員可以隨時(shí)了解到當(dāng)前每個(gè)節(jié)點(diǎn)的狀態(tài)并及時(shí)進(jìn)行管理。
5)當(dāng)具有副本標(biāo)記的文件寫入請求到達(dá)存儲(chǔ)服務(wù)器時(shí),存儲(chǔ)服務(wù)器會(huì)首先在本地存儲(chǔ)該文件。然后存儲(chǔ)服務(wù)器會(huì)根據(jù)寫入請求中所指定的地址向?qū)?yīng)的其他存儲(chǔ)服務(wù)器發(fā)送副本創(chuàng)建請求,其他存儲(chǔ)服務(wù)器收到請求后同樣將文件寫入。副本創(chuàng)建請求同樣也可以被目錄服務(wù)器所觸發(fā),以根據(jù)訪問頻次進(jìn)行副本數(shù)的動(dòng)態(tài)變化,實(shí)現(xiàn)動(dòng)態(tài)負(fù)載均衡。
6)刪除文件時(shí),存儲(chǔ)服務(wù)器會(huì)立即刪除元數(shù)據(jù),但此時(shí)文件尚未被物理刪除。巡檢程序會(huì)定期啟動(dòng),以比較物理卷和元數(shù)據(jù)中的文件對應(yīng)情況。如果發(fā)現(xiàn)當(dāng)前物理卷有已刪除文件或損壞的文件,巡檢程序?qū)?chuàng)建新的臨時(shí)物理卷,并根據(jù)元數(shù)據(jù)將物理卷中的每個(gè)文件復(fù)制到臨時(shí)物理卷。
緩存服務(wù)器負(fù)責(zé)統(tǒng)一的數(shù)據(jù)緩存,由于需要存儲(chǔ)文件,因此使用Redis作為其存儲(chǔ)后端,從內(nèi)存中進(jìn)行文件讀寫以保障性能。緩存服務(wù)器使用了目錄/存儲(chǔ)兩級緩存設(shè)計(jì),以提升緩存性能,盡量降低響應(yīng)時(shí)間與服務(wù)器負(fù)載。
其具體的技術(shù)實(shí)現(xiàn)如下:
1)緩存服務(wù)器定期檢查存儲(chǔ)在其中的目錄與存儲(chǔ)級緩存,刪除重復(fù)的緩存(即緩存文件都存在于目錄級緩存和存儲(chǔ)級緩存中),并自動(dòng)清除一段時(shí)間內(nèi)未訪問的緩存以節(jié)省內(nèi)存空間。
2)緩存服務(wù)器還會(huì)將頻繁訪問但只緩存在存儲(chǔ)級緩存中的文件移動(dòng)到目錄級緩存中,以提升請求效率。
將文件上傳到Kubestorage 的過程分為以下幾步:目錄服務(wù)器首先接收來自業(yè)務(wù)的文件上傳請求,其中包括文件的副本次數(shù)和文件的二進(jìn)制數(shù)據(jù)。如果當(dāng)前目錄服務(wù)器不是Leader 服務(wù)器,則受理上傳請求的目錄服務(wù)器將向Leader 服務(wù)器發(fā)送一個(gè)反向代理請求。Leader 服務(wù)器將會(huì)核對數(shù)據(jù)庫,以確保物理卷數(shù)量足夠,然后創(chuàng)建區(qū)塊和存儲(chǔ)數(shù)據(jù)的請求將被發(fā)送到指定的存儲(chǔ)服務(wù)器。目錄服務(wù)器最后生成對應(yīng)鏈接以便后續(xù)訪問。
從Kubestorage 下載文件的過程則分為以下幾步:首先業(yè)務(wù)將向目錄服務(wù)器發(fā)送文件下載請求,請求中包含此前所生成的永久鏈接,目錄服務(wù)器首先將檢查文件是否存在于目錄級緩存中,如果文件存在,數(shù)據(jù)將從內(nèi)存中讀取,并直接傳輸給業(yè)務(wù);如果未命中緩存,則會(huì)將文件獲取請求發(fā)送到相應(yīng)的存儲(chǔ)服務(wù)器,存儲(chǔ)服務(wù)器同樣將檢查文件是否存在于存儲(chǔ)級緩存中,如果在存儲(chǔ)級緩存中則直接傳輸,如果緩存未命中,則存儲(chǔ)服務(wù)器會(huì)將當(dāng)前文件放在存儲(chǔ)級緩存中,以此減少下次讀取時(shí)間,如果頻繁訪問該文件,它還會(huì)被轉(zhuǎn)移到目錄級緩存進(jìn)一步提高文件的訪問速度。
存儲(chǔ)服務(wù)器會(huì)將接收到的每一次讀取請求記錄在數(shù)據(jù)庫中(每次巡檢周期結(jié)束后清空一次計(jì)數(shù)),并在下一次巡檢周期開始時(shí)將滿足訪問次數(shù)閾值的文件放置于相對應(yīng)的存儲(chǔ)級緩存中。對于已緩存的文件,若下一次巡檢的讀取次數(shù)低于閾值,則將其從緩存中清除。若多次巡檢發(fā)現(xiàn)緩存依然未被清除,則將該文件轉(zhuǎn)移至目錄級緩存。
若緩存服務(wù)器緩存體積超過最高安全閾值,則會(huì)按照上一個(gè)巡檢周期內(nèi)的緩存命中次數(shù)對文件進(jìn)行排序,清除命中次數(shù)較低的文件直至緩存體積低于最低安全閾值。
上文所述所有閾值與巡檢周期均可配置,以便平衡性能與成本,適配不同規(guī)模的存儲(chǔ)需求。
Kubestorage 能容許服務(wù)器節(jié)點(diǎn)的故障并能實(shí)現(xiàn)自動(dòng)恢復(fù)。每臺(tái)目錄服務(wù)器都會(huì)通過kube-apiserver 組件定時(shí)獲取當(dāng)前所有節(jié)點(diǎn)狀態(tài),若發(fā)現(xiàn)某臺(tái)服務(wù)器出現(xiàn)異常(即Kubernetes 自檢不成功,Pod 狀態(tài)為NotReady 或狀態(tài)標(biāo)簽為Offline),目錄服務(wù)器會(huì)立刻調(diào)用kube-apiserver 清除故障節(jié)點(diǎn)并完成持久卷綁定、數(shù)據(jù)庫初始化等操作,實(shí)現(xiàn)自恢復(fù)。該策略對目錄服務(wù)器、存儲(chǔ)服務(wù)器與緩存服務(wù)器均有效。
由于負(fù)載均衡的存在,所有請求均會(huì)被傳遞到正常的目錄服務(wù)器中,若出現(xiàn)異常的目錄服務(wù)器為Raft 集群的Leader,則剩余的所有Followers會(huì)重新進(jìn)行選舉。選舉期間的請求將會(huì)被放入等待隊(duì)列,并在對應(yīng)存儲(chǔ)服務(wù)器恢復(fù)后立刻繼續(xù)任務(wù)。對故障緩存服務(wù)器的請求被視為緩存未命中,直接從存儲(chǔ)服務(wù)器請求所需文件。
性能分析部分將使用阿里云的ECS 服務(wù)器作為測試平臺(tái),配置為Intel Xeon Platinum 8163 處理器(8 個(gè)虛擬核心),32 GB 內(nèi)存,同時(shí)掛載6 TB 的SSD 云磁盤作為測試用數(shù)據(jù)盤(標(biāo)稱IOPS為25 000,吞吐量為讀/寫均256 MB/s)。
我們選擇了EXT4、ZFS 和SeaweedFS 作為基準(zhǔn),分別代表傳統(tǒng)文件系統(tǒng)、現(xiàn)代文件系統(tǒng)和傳統(tǒng)對象存儲(chǔ)系統(tǒng)。SSD 云磁盤將分別被格式化為EXT4、ZFS 文件系統(tǒng),并對其進(jìn)行一系列的測試。該云磁盤也將被格式化為EXT4,并在其上配置Kubernetes 單機(jī)集群(使用Flannel 虛擬網(wǎng)絡(luò)),以便使用Kubestorage和SeaweedFS進(jìn)行測試。
測試方法如下:在測試服務(wù)器上運(yùn)行使用Golang 開發(fā)的文件讀寫API,并使用另一臺(tái)配置相同的服務(wù)器在局域網(wǎng)內(nèi)遠(yuǎn)程訪問此API,避免測試工具本身對測試造成的干擾。Kubestorage 將構(gòu)建于Kubernetes 上,使用2 個(gè)目錄服務(wù)器、8個(gè)存儲(chǔ)服務(wù)器與1 個(gè)緩存服務(wù)器構(gòu)成小型的Kubestorage 集群,物理卷大小為每文件1 GB,文件默認(rèn)副本數(shù)為2。SeaweedFS 將保持與Kubestorage 相同的硬件配置與環(huán)境配置,并按照使用文檔使其運(yùn)行于Kubernetes上。
測試過程如下:
1)提前分別將1 000 萬個(gè)文件大小為4 KB、40 KB 與400 KB 的文件寫入待測試的存儲(chǔ)系統(tǒng),文件內(nèi)容為隨機(jī)ASCII字符。為避免EXT4由于inode不足造成測試失敗,已提前擴(kuò)增inode容量。
2)在另一臺(tái)服務(wù)器上(兩臺(tái)服務(wù)器之間網(wǎng)絡(luò)帶寬為10 Gb/s)通過測試軟件分別啟動(dòng)足量線程直至測試服務(wù)器報(bào)告其正在執(zhí)行的并發(fā)請求數(shù)量為50、500、1 000、5 000(避免由于發(fā)起線程數(shù)與測試服務(wù)器收到請求數(shù)不一致對測試造成干擾,使接收請求數(shù)盡量接近實(shí)際的并發(fā)讀取數(shù)),使用上文所提及統(tǒng)一的API 從測試服務(wù)器中隨機(jī)進(jìn)行文件的讀取和寫入,在發(fā)起請求的服務(wù)器上記錄每次讀取和寫入的響應(yīng)時(shí)間以供后續(xù)性能分析。每輪讀取測試中,1 000萬個(gè)文件中的隨機(jī)20 萬個(gè)將被以隨機(jī)的不同頻次總共讀取500 萬次,以模擬云計(jì)算環(huán)境中真實(shí)業(yè)務(wù)中的負(fù)載場景。每輪寫入測試中,將寫入20 萬個(gè)文件,每個(gè)文件大小分別為4 KB、40 KB 與400 KB,文件內(nèi)容同樣為隨機(jī)ASCII。
3)從預(yù)寫入的1 000 萬個(gè)40 KB 文件中隨機(jī)選取100 個(gè)40 KB 文件進(jìn)行熱點(diǎn)測試,模擬社交平臺(tái)中常見的熱點(diǎn)圖片資源,對這100 個(gè)文件同時(shí)進(jìn)行并發(fā)數(shù)為1 000 的隨機(jī)讀取,每個(gè)文件讀取10 000次,記錄讀取過程中性能的變化、緩存的變化與文件分布的變化,以測試上文所述緩存策略與自動(dòng)冗余策略是否有效。
4)在1 000個(gè)線程的40 KB隨機(jī)讀寫測試過程中,手動(dòng)將一半的目錄服務(wù)器與一半的存儲(chǔ)服務(wù)器狀態(tài)配置為Offline(拒絕所有請求),以測試性能波動(dòng)與服務(wù)穩(wěn)定性。
由于Kubestorage 與SeaweedFS 均不支持目錄功能,為保證測試的準(zhǔn)確性與可信度,對于傳統(tǒng)文件系統(tǒng),所有讀取與寫入的文件均放置在同一目錄下。
在測試過程中,將記錄并比較平均響應(yīng)時(shí)間、響應(yīng)時(shí)間方差和1 000并發(fā)下響應(yīng)時(shí)間占比(即小于特定響應(yīng)時(shí)間的請求占比)。平均時(shí)間越短,表示性能越好;方差越小,表示越穩(wěn)定;響應(yīng)時(shí)間占比中低延時(shí)所占百分比越多表示性能越好。每組實(shí)驗(yàn)將在相同條件下重復(fù)5 次,并取所有數(shù)據(jù)的平均值。實(shí)驗(yàn)結(jié)果如表1~3所示。
表1 不同線程數(shù)量下各存儲(chǔ)方案的平均讀取時(shí)間、平均寫入時(shí)間與方差對比Tab.1 Comparison of average read time,average write time and their variances of different storage schemes under different thread number
表2 1 000并發(fā)請求下各存儲(chǔ)方案的讀取與寫入時(shí)間占比Tab.2 Average read and write time proportion of different storage schemes under 1 000 concurrent requests
表3 熱點(diǎn)訪問測試中平均響應(yīng)時(shí)間與方差 單位:msTab.3 Average response time and variance in hot spot access test unit:ms
3.5.1 性能分析
從表1、2 中可以看出,ZFS 受限于其復(fù)雜的設(shè)計(jì),響應(yīng)時(shí)間與穩(wěn)定性落后于其他存儲(chǔ)方案,這是由于ZFS相較于性能,更側(cè)重于可管理性與可擴(kuò)展性,導(dǎo)致文件讀寫過程相對復(fù)雜,相應(yīng)的資源耗費(fèi)更多。當(dāng)并發(fā)讀取量較低時(shí),Kubestorage、SeaweedFS 的讀取性能與EXT4 大致相同。當(dāng)并發(fā)讀取量上升后,Kubestorage 開始逐漸展現(xiàn)出其優(yōu)勢,盡管Kubestorage和SeaweedFS 具有相同的存儲(chǔ)模型,但在讀取時(shí),Kubestorage受益于其多級內(nèi)存緩存與自動(dòng)建立副本的設(shè)計(jì),相對SeaweedFS 性能更占優(yōu)勢。從表中可以看出,Kubestorage 在1 000 與5 000 并發(fā)時(shí)的平均響應(yīng)時(shí)間與穩(wěn)定性相對于SeaweedFS 與EXT4 均占有一定優(yōu)勢。總體而言,采用Haystack 存儲(chǔ)結(jié)構(gòu)的Kubestorage 與SeaweedFS 性能均優(yōu)于EXT4 和ZFS,其中Kubestorage 由于緩存與自動(dòng)副本策略的引入,性能相對更優(yōu)。
從表1、2 中還可以看出,由于創(chuàng)建元數(shù)據(jù)和將文件插入物理卷的開銷較大,Kubestorage 和SeaweedFS 的寫入性能均遠(yuǎn)低于其他文件系統(tǒng),這一問題在請求數(shù)量增多時(shí)格外明顯。
從表3 中可以看出,在熱點(diǎn)訪問測試過程中,由于EXT4、ZFS、SeaweedFS 均不帶有文件緩存,在不同測試階段的性能并無顯著變化,但Kubestorage 隨著訪問計(jì)數(shù)的不斷增加開始逐漸開啟副本冗余(10 min 內(nèi)500 次讀取觸發(fā))、寫入緩存(10 min 內(nèi)1 000 次讀取觸發(fā)),以降低存儲(chǔ)服務(wù)器的磁盤壓力。表3數(shù)據(jù)充分證明了緩存策略為Kubestorage 帶來的性能與穩(wěn)定性提升。
3.5.2 穩(wěn)定性分析
在手動(dòng)關(guān)閉服務(wù)器的測試過程中,被關(guān)閉的目錄服務(wù)器是當(dāng)前Raft集群的Leader,Kubernetes 的負(fù)載均衡將所有請求移交給另一臺(tái)Follower,F(xiàn)ollower 在節(jié)點(diǎn)檢測過程中檢測到Leader 不可用,立刻開始新一輪選舉,并將自己設(shè)置為Leader。期間正在處理的請求被放入目錄服務(wù)器隊(duì)列,并在選舉完成后繼續(xù)請求。隨后新的Leader在選舉完成后立即調(diào)用kube-apiserver 新建了一臺(tái)新的目錄服務(wù)器以填補(bǔ)空缺,該服務(wù)器成為Follower,服務(wù)恢復(fù)正常。
被關(guān)閉的一半存儲(chǔ)服務(wù)器在節(jié)點(diǎn)檢測過程中被目錄服務(wù)器判斷為不可用,并由目錄服務(wù)器調(diào)用kube-apiserver 新建了4 臺(tái)新的存儲(chǔ)服務(wù)器,自動(dòng)完成持久卷掛載與數(shù)據(jù)初始化操作,然后取出所需文件傳輸給客戶端。由于存儲(chǔ)服務(wù)器的初始化需要一定時(shí)間,關(guān)閉后約20 s內(nèi)出現(xiàn)了一定的性能波動(dòng),這20 s 內(nèi)的平均讀取響應(yīng)時(shí)間由10.7 ms 增加到1 466.1 ms,但由于默認(rèn)副本數(shù)為2,只有少部分文件完全不可讀。
綜上所述,本文所提出的Kubestorage 存儲(chǔ)系統(tǒng)被設(shè)計(jì)為更適合存儲(chǔ)云平臺(tái)與云業(yè)務(wù)中的大量小文件,尤其是以社交網(wǎng)絡(luò)為典型,即讀遠(yuǎn)多于寫的使用場景。上述測試充分展現(xiàn)了Kubestorage 在架構(gòu)設(shè)計(jì)上的優(yōu)勢與潛力,且部署過程簡單,使用預(yù)配置的腳本僅需數(shù)條命令即可搭建出任意規(guī)模的Kubestorage存儲(chǔ)集群,這使其更為靈活,在云上擁有比傳統(tǒng)存儲(chǔ)解決方案更好的性能和更優(yōu)秀的穩(wěn)定性。Kubestorage開箱即用,更適合云原生業(yè)務(wù)部署,為云上的應(yīng)用提供更快捷穩(wěn)定的存儲(chǔ)解決方案。
但同時(shí)我們也看到了目前Kubestorage 所存在的一些不足,將來還需要在以下方面進(jìn)行改進(jìn),以提供更好的使用體驗(yàn),進(jìn)一步提升其實(shí)用性與易用性:
1)使用緩存服務(wù)器對文件寫入進(jìn)行緩存,以實(shí)現(xiàn)異步文件保存功能,提供更好的寫入性能;
2)添加對目錄、文件別名、軟鏈接等高級特性的支持,以保持與傳統(tǒng)文件系統(tǒng)的雙向兼容和相互轉(zhuǎn)換,提升兼容性與靈活度,便于讓更多業(yè)務(wù)享受對象存儲(chǔ)的便利;
3)考慮到目標(biāo)應(yīng)用場景內(nèi)可能有大量重復(fù)的文件資源,因此可對散列相同的文件進(jìn)行合并存儲(chǔ),以節(jié)省磁盤空間。