UCan下午茶武漢站,為你全面挖寶分散式儲存
11月10日,UCan下午茶武漢站的活動在武漢青年光谷咖啡館召開,在此次沙龍上,UCloud檔案儲存研發工程師鄧瑾、塊儲存研發工程師葉恆、奧思資料創始人兼CTO李明宇、深信服科技儲存研發專家盧波四位儲存專家為到場的近百位觀眾詳細講解了分散式檔案系統和分散式儲存的技術原理和應用實踐。
Line"/>
UCloud分散式檔案系統產品架構解析
UCloud儲存研發工程師鄧瑾首先就UCloud分散式檔案系統產品架構進行了解析。
分散式檔案系統簡介
鄧瑾表示,分散式檔案系統從概念上來說,就是經典檔案系統的一個延伸,通過一些分散式技術,包括現在公有云的規模,帶來了傳統檔案系統所不能達到的功能和特性。分散式檔案系統的經典能力,第一是Scale Out,這是分散式系統的經典特性也是其基本門檻,Scale Out能在檔案系統上帶來線性或者近線性的容量和效能的提升。第二,通過分散式技術,依靠多副本、分散式協議、一致性協議,分散式系統可以提升單節點不能提供的高可用性和高可靠性,讓上層系統可以遮蔽硬體上的故障。第三,通過公有云廠商的規模效應,它能夠給應用層的使用者提供比較低的TCO。
鄧瑾接著回顧了比較經典的幾種系統,他表示,最早期的分散式檔案系統是谷歌File System,以及基於GFS開發的一個開源的檔案系統HDFS,它是一種面向高吞吐場景的檔案系統,它還有一個特點,就是它是一種索引,並且有一些管控節點是中心化的。
第二類系統是淘寶的TFS或者是Facebook的Haystack,它們是小檔案的場景,而且是一類存放圖片的物件儲存系統,一個圖片寫入之後就不會修改了。
第三類系統是GluesterFS和CephFS,它們的共同點是都是開源的,設計理念是基於去中心化的,基於動態演算法來決定儲存系統的定址,這也是大型系統比較流行的設計理念。
第四類是通用儲存系統,一類是以微軟Azure Blob Storage為代表的,包括阿里的盤古也是這套系統,它通過一個底層拓展性非常強的一個統一儲存的介面,來支撐上面不同的業務,微軟的Blob Storage都是靠這套系統來支撐的。
第五類是一些比較特定場景下的檔案系統,它也是一種比較典型的設計理念,例如WAFL和PolarFS,它們都是為某些特定場景優化的,PolarFS是阿里雲的一款底層的儲存系統,支援的就是PolarFS對底層系統的要求所具有的特定的一些特點。
鄧瑾還比較了物件儲存、KV和檔案儲存三大類儲存系統,他表示,物件儲存在設計上其實是比較簡單的,它是一種immutable storage,寫一次後面再不會改,但是可以多次的讀,例如,S3,它天生基於面向Web的優勢,現在與CDN的結合,整個生態非常廣泛,應用也非常廣泛。但是對一些傳統的應用,它需要做改造,或者需要在客戶端上把這個API傳成物件儲存的API。對於傳統廠商,比如說醫院的裝置,就不太願意做這個改造,物件儲存可能有一些劣勢,但它的優勢是檔案大小沒有上限。
KV的特點就是面向一些遞延式場景,因為它通常會用於一些快取場景,KV系統有非常多的變種,因此在KV選擇上提供了非常高的靈活性。但是一般來說,KV系統儲存容量不會太大,因為它追求高效性。
檔案儲存最大的優勢是有一套通用的檔案API,現在能夠比較接近模擬API的是NFS介面。檔案儲存規模可以很大,而在用單機檔案系統的時候,到TB級或者百TB級就會遇到瓶頸,這個瓶頸不僅是容量上的,還有處理能力上的。分散式檔案系統系統主要致力於解決消除這些瓶頸,提供一個高可用的服務。
UFS發展歷程
鄧瑾表示,UFS是一個UCloud在前年開始研發的一個完全自主研發,面向公有云設計的一款分散式檔案系統,公有云產品有非常多的型別,因為一些特定需求,在公有云場景下,怎麼把這些主機融入到分散式檔案的訪問客戶端之內,都在UCloud檔案系統設計的範疇之內。
從功能上來說,UFS現在支援V3和V4,2019年會支援Windows SMB系列,UFS的基本使命是給客戶提供高可用、高可靠的儲存服務。UCloud有一些比較典型的產品,這些產品與物件儲存、KV儲存有一些區別,它有四類場景,首先是容量型檔案儲存類場景,即備份場景, 再就是資料分析類場景,像Hadoop資料分析平臺,廣電的渲染,在高效能的檔案儲存上都可以得到應用。第三類就是資料共享。第四類對開發者比較有用,適用於實現Layer storage,上層做一箇中間層,冗餘可以丟到下層,如果檔案系統可以提供高可用、高可靠資料服務的話,甚至可以把它當成一個選址服務,這是對開發人員比較大的支援。
鄧瑾表示,UFS的設計是利用開源軟體GlusterFS快速在公有云環境中進行產品原型驗證,然後從運營角度積累分散式檔案產品在多租戶的公有云環境中的痛點和難點,進行自研產品的設計改進,同時吸收社群經驗,經過這樣的過程,UFS 1.0誕生了。
1.0整體架構
UFS 1.0首先是一個索引和資料分離的架構,它是對傳統檔案系統一個最直接的延伸,它不採用中心節點儲存索引,而是直接把檔案系統概念在分散式磁碟上模擬出來。另外,UFS 1.0的索引有一套索引管理系統,有著自定義的索引結構和語義,這將便於後續拓展非NFS協議。同時,它還具有獨立設計的儲存服務,並支援set管理、灰度等策略,還支援百萬級大目錄和TB級檔案大小,也支援QoS,對多租戶場景下使用者的訪問也做了一些隔離。最後,相比GluserFS來說,UFS 1.0資料安全性較高。
上圖是UFS 1.0的整體架構,它有一個管理平面和一個數據平面,在資料平面,左邊是使用者訪問入口,使用者在他自己的網路專區,會有自己的很多主機,包括虛擬的雲主機,物理雲主機,託管雲主機等等,都是通過VPC網路來訪問接入服務,接入服務會通過UCloud的ULB負載均衡器,然後把流量匯入接入服務,接入服務就是圖上的NAS。
它的特點非常明確,是一個無狀態的服務,包括NFS協議本身,這實際上是為了提升故障恢復的時候,客戶端的啟動不需要去記憶一些資訊。對比單機檔案系統,它也有兩類功能,一類是索引,包括定址的功能,另一類就是資料訪問操作,UFS 1.0把這兩類東西抽象成兩個部分,紫色部分叫system index,包括目錄索引,檔案索引兩部分。下面是資料叢集,儲存檔案的資料,在裡面做一些多副本、高可靠、高可用的檔案。
索引層
如下圖所示,在索引層主要就是模擬兩個概念,一個是目錄樹,傳統檔案系統一個比較大的特點,就是它會有一段目錄樹,在下圖右邊有一個DIAdex,把整個目錄樹模擬下來。左邊比較簡單,它不會有層級結構,而是KV平臺的結構,它會把檔案需要的一些屬性記錄下來,這裡最關鍵的是它跟下層的資料層會存在同一個連結中,這裡會記一個FH,叫做檔案距離。
這裡面比較重要的一點,是如果去做一個檔案或者目錄索引,非常簡單,就是實現一個檔案和目錄操作就可以了。但是它面臨的一個很大的問題,如何做到水平拓展?在多節點的操作上怎麼保證原資料操作的一致性?因此,UFS 1.0會把它分成很多範圍,某個檔案可能會在A節點上處理,某些檔案在B節點上處理。因為在分散式系統當中,經常會遇到宕機,或者網路導致的節點丟失,可能某個節點就沒法訪問了,這時候就需要維護一個租約,這個租約會定期續約,保證系統對這個節點的某個範圍,或者某個檔案有處理許可權,當失去這個租約的時候,必須把自己從叢集當中踢掉,否則會出現兩個節點都對同一個檔案進行操作,就會破壞後端檔案系統的結構。
USF 1.0就是靠這一套系統來實現了之前一些單機檔案系統不能提供的一些功能,包括處理能力的線性拓展,因為節點處理空間非常大,幾十萬甚至上百萬的節點對它進行排程,也可以依賴它來實現一個大檔案和大目錄的支援,這主要還是模擬單機檔案系統的概念,UFS 1.0會把一個大檔案分成很多二級或者三級的一小段一小段的資料,存到這個索引中。
資料層
在資料層,一個檔案儲存需要經過以下過程,首先,使用者從主機發一段資料到NAS接入層,UFS 1.0會把流失的資料,就是FH代表的檔案,按4M進行切分,每4M生成一個獨立的IO請求發往儲存層,儲存層會做一個模擬,把這4M進行切分,切成64K。檔案切分主要是考慮如果把一個大檔案直接往儲存叢集上落,磁碟空間可能會不足。因此,需要把它打散,打散有兩個好處,一是儲存會落在各個地方,IO比較平均,也不會有特別大的熱點。另外,這樣可以充分利用整個叢集的容量。
之後在儲存層,會把整個叢集分成很多個,因為它本身有很多機器,每個機器上有很多磁碟,UFS 1.0把每塊磁碟分成很多個chunk,把空間分散之後,還會帶來一個好處,當發生某個chunk有熱點的時候,可以把它調到別的地方去,但如果chunk非常大,排程也沒有特別大的意義,所以要先做一個chunk切分,每個chunk有三個副本,這三個副本組成了chunk group。當一個IO請求進來的時候,這是一個最多4M的檔案,會切成64K,每個64K會寫到某一個chunk group上,這64K就併發往這些chunk gourp上去寫。
下圖就是儲存層一個簡單的模型,右邊藍色的就是多叢集灰度管理的系統,它可以暴露給前端業務,說明有多少叢集可用。紫色的index是記錄4MB分片切成64K的一個對應關係,為什麼要存這個呢?因為必須要知道這個64K是存在哪個chunk的,通過查詢它在哪個chunk,再去定位到真正的chunk所在的三個副本當中的任意一臺機器。
UFS 1.0的侷限
鄧瑾介紹,UFS 1.0運營了一段時間後,發現這個儲存模型,因為支援NAS的一些隨機或者覆蓋寫引入小分片的概念,但這個分片太小了,導致儲存層那邊很難模擬一個超大檔案。 然後就是底層的儲存,它是一個固定的64K,不管寫不寫滿64K,都要佔用64K,這在規模很大的時候,會形成一定的空間浪費。第三是儲存層支援的檔案尺度較小。第四就是對隨機寫的支援不夠,在做FIO,做4K這種寫的時候會發現延時會比較高。
UFS 2.0儲存架構
針對UFS 1.0的侷限,UCloud進行了2.0架構的升級,主要對儲存層進行了優化,優化不僅僅針對NAS服務,而是進行了面向統一儲存場景的整體設計和優化,它支援超大檔案,冗餘機制也更靈活,同時,它通過與新硬體和軟體技術棧的結合來實現低延時高效能的場景。
Append-only模型
在底層的Stream layer,是真正的統一儲存的概念。每個儲存的檔案,稱為Stream,每個Stream是永遠可以追加寫的,但是它分成了很多小分片,叫做Extent,UFS 2.0把這個Stream切成了一大段一大段很大的Extent,而且只有最後一個Extent是可以進行追加寫的,中間一旦寫完之後就再也不能改變。它帶來的好處,是這種模型非常簡單,不會擔心資料篡改或者曾經寫過的資料被覆蓋掉,或者沒有辦法回軌,因為Append-only可以很好模擬快照功能,有整個操作的歷史記錄。每個Extent被分配三個或者N個多副本,會滿足一定容災的要求,來保證副本的高可用。
每個Extent是以檔案的形式落在儲存介質上,檔案可能會比較大,現在是4GB一個Extent。使用者在寫的時候是以Block為單位,往Extent上面追加,這個Block是不固定的,每次往裡面追加寫之後,Extent覺得達到一定的量就可以關掉,再新開一個,這即是Append-only整個的模型。
資料層
Append-only模型裡有幾個模組,綠色的streamsvr,它管理Stream的功能,做Stream的建立,分配副本,副本所在的位置等。它會把原資料儲存在資料庫當中,Streamsvr會有一個master對外提供服務。Extentsvr做一些資料的持久化。
Extentsvr的儲存引擎設計有兩個功能,一是消除寫入毛刺,另一個是功能持久化一些還沒有落地的索引更新或者是更新操作。資料來了之後,會先落,然後更新,把它放在記憶體裡,這個時候就可以返回成功了,業務側就可以收到,進行訪問。FileLayer的機器是高記憶體的,可以對資料進行快取,它可以把整個熱點給打散,降低單節點訪問壓力以及資料讀取的毛刺。FileLayer還把整個底層Stream提供的儲存空間切分成很多個數據單元,以便於做負載均衡。
針對隨機寫,依然是利用底層的方式,把資料先追加下去,追加是追加在Date Uint(DU)提供的檔案上,這樣就可以直接反饋給使用者這個隨機寫完成了,而不需要去讀老資料進行合併。帶來的開銷可以通過軟體方法去優化它。此外,針對沒有辦法結束對DU寫的問題,會對資料進行分片,每個分片的最小顆粒度是100GB,每個DU只有一個fserver進行處理,從而實現隨機寫邏輯。
分散式儲存中的資料分佈演算法
奧思資料創始人兼CTO李明宇則具體講解了分散式儲存中的資料分佈演算法,他的講解分為四部分:一致性雜湊演算法及其在實際應用中遇到的挑戰、典型的“儲存區塊鏈”中的資料分佈演算法、典型的企業級分散式儲存中的資料分佈演算法以及比較和總結。
一致性雜湊演算法及其在實際應用中遇到的挑戰
李明宇表示,常見的在分散式系統中的資料分散式演算法,就是一致性雜湊演算法,一致性雜湊演算法在實際應用中會遇到很多挑戰,一方面是應用在雲端儲存或者企業級儲存裡面的挑戰。另外就是在比較新的一些研究方向,比如說區塊鏈或者區塊鏈儲存等的方面,也會遇到一些挑戰。
雜湊表及其在分散式系統中的問題
如果用一致性雜湊做資料分佈,經常會用到資料結構是雜湊表,雜湊表是把一個空間劃成N個區域,比方有一個字串,假如這個字串是一個檔名,根據這串字串,會得到一個雜湊。現在假如說有八個儲存位置,那麼,這些資料會放在哪個儲存位置呢?雜湊演算法正是有著這樣的作用,因為雜湊具有非常好的隨機性,因此,通過雜湊演算法對檔案的檔名字串進行雜湊,就可以把這些資料均勻地分佈到六個裝置上。
但這種演算法看起來很好,卻會帶來一個問題,因為在分散式儲存裡面,隨著儲存的資料越來越多,系統可能就要擴充節點。而這時如果用雜湊演算法來算,很多資料都需要重新去分佈。而當增加的節點越來越多時,幾乎所有的資料都要去移動,資料遷移的開銷是非常巨大的,系統將會無法承受。為了解決這個問題,有人發明了一種演算法,將儲存平面圈起來,形成一個雜湊圈,首尾相接,這樣就可以讓增加的資料更均勻的分佈在裝置上,而且不需要移動太多資料,比傳統的雜湊表好很多。
但即使是這樣,如果需要增加一塊硬碟,還是要移動很多資料,為此,就引入了虛擬節點的概念,一塊盤不再對應一個位置,而是對應多個位置,這樣,從概率上,分佈的均衡性就會好很多。此外,當有硬碟出現故障需要退出時,這種方法也會分散資料遷移的壓力,這就是一致性雜湊演算法。一致性雜湊演算法具有不需要查表或通訊過程即可定位資料,計算複雜度不隨資料量增長而改變,效率高、均勻性好、增加/減少節點時資料遷移量小等優點,但在企業級IT和儲存區塊鏈場景,仍然面臨很大的挑戰。
企業儲存會用到一些方式,比方說多副本,如果隨機找幾個位置去分佈,很可能會造成副本落在同一臺伺服器上的情況,這種情況,企業級IT是無法容忍的。還有在儲存區塊鏈場景下,它需要用到全球的資源,讓大家自發參與進來,組成一個跨全球的大的分散式儲存系統,如果在這裡面根本不知道有多少裝置,也無法控制所有裝置,如果來了一個儲存物件,算出了一個雜湊值,就不會知道這個雜湊值究竟會對映到哪個裝置上,因為這個裝置可能隨時出現,隨時退出,是全球參與者自發參與的,無法控制。所以幾乎不可能獲得一個全域性檢視,而且一致性雜湊環中的裝置是隨時都會發生變化的,甚至沒有一刻是穩定的,這將帶來很大的問題。
典型“儲存區塊鏈”中的資料分佈演算法
那麼,儲存區塊鏈剛才說的這種場景,應該怎麼解決?在此之前,首先需要清楚儲存區塊鏈的概念,它是分散式儲存或者去中心儲存或者P2P的儲存加上區塊鏈,它的目的是通過區塊鏈的機制,通過token的機理,鼓勵大家貢獻儲存資源,一起組成一個大的儲存系統。儲存區塊鏈的代表專案有Sia,Storj,IPFS+filecoin。
但如果是全球使用者自發參與,就沒有去中心化的儲存系統的定址和路由的問題,但因為參與者隨時可以加入和退出這個網路,就需要解決這個問題,這在歷史上已經有一些代表演算法,比方說Chord、Kademlia等等。
這些演算法,實際上最根本的還是一致性雜湊演算法,Chord更難理解一些,如果有一個數據要儲存,這個資料檔名是K,資料相當於是V,整個P2P儲存網路裡面有一些節點,這些節點算出來的雜湊值是14、21、32、42等,如果算出來雜湊值是10,它比8大,比14小,它就應該順時針放到8和14之間的節點上,以此類推。在一個真正的P2P儲存網路中,節點數量是眾多的,所以按照這樣順時針存,和一致性雜湊沒有任何區別。現在問題是,在沒有任何節點知道到底有哪些節點參與到這個網路中時到底應該怎麼辦?Chord採用的方法是,既然沒辦法維護,就不維護,如果有一個數據,K就是其檔名,算出來的雜湊值是54,那麼,它先不管資料到底存在哪兒,首先和最近的一個節點比較雜湊值,如果比臨近的大就繼續往下尋找,如果比自己的小,就儲存在該位置,並進行反饋。這樣,新加的節點並不需要其他節點知道,因為新加入的節點會向周圍的節點去廣播自己的存在,按道理說,總有概率說有些節點知道是新加入進來的,這樣找下去,總是能找出來。
Chord
但這樣的演算法非常低效,一圈下來,延時很高。而降低這個延時有兩種辦法,一種辦法是多存幾份,降低延時的同時能提高可靠性,Chord中的一個最大的改進是Finger table,它不僅僅記錄自己的下一個節點,最臨近的節點,還記錄自己的2的i次方加1的那個位置,這個i的最大值就取決於Finger table用幾位來表示產生的索引,所以它能夠記錄最臨近的,最遠的,或者說是一半遠的,1/4遠的,等等的節點。這樣的話,如果要搜尋一個數據,就沒有必要像剛才那樣挨個去找,可以直接進行跳轉,這樣就把計算複雜度降低了,這就是Chord演算法。
Kademlia
在此基礎上還有另外一個演算法,就是Kademlia,它跟Chord演算法比起來有幾個不一樣的地方,首先計算距離的時候,並不是在用數值的大小去計算,而是用XOR計算,因此計算的複雜度就會降低。另外一方面,它設計了一個數據結構叫做K-桶,比如當前節點的id是0011,最近的節點是0010,所以它就用這種方式來表示距離,而在尋找的時候,其方法是與Chord演算法是形同的。
另外與Chord相比,它支援並行搜尋,這樣就解決了沒有全球檢視的問題。因為不需要掌握全域性到底有哪些節點參與的情況,每個節點都會週期性的向周圍發請求,如果有節點退出,就會被發現。如果有新節點加入,新加入的節點會往臨近節點廣播它的存在,所以也會被發現,節點之間互相可以聯絡上。
典型的企業級儲存中的資料分佈演算法
具體到企業級儲存裡面,這個問題變得更加複雜,關於企業級儲存中間典型的資料分佈演算法也有一些,比如像Dynamo裡有Amazon,Ceph裡有CRUSH的演算法等等。這些演算法都有一定的相似度,都是要對資料算雜湊,對資料的K算雜湊等等,然後再做對映關係。這些演算法還引入了對資料中心物理拓撲的建模。比如Cluster Map,一個大的儲存叢集,分幾個資料中心,每個資料中心下面可以再分zone,zone下面再分機櫃,機櫃下面再分節點等等,它會把這種拓撲結構給記錄下來。這樣的話,資料的分佈就會根據Cluster Map分佈到不同的故障域裡面,這樣當一個故障域出現問題的時候,資料不會丟失,資料仍然可以訪問。這些演算法中還有對節點劃分的權重,資料分佈和容量/效能匹配,輔助擴容以及多種儲存策略選擇。
李明宇最後表示,歸根到底,各種演算法的源頭都是一致性雜湊,因為不同的需求,有不同的改進方向。企業級的更注重副本故障域的分佈,對於P2P儲存更注重在節點隨時退出隨時加入的情況下,怎麼樣保證資料能夠在有效時間內定址。
雲硬碟架構升級和效能提升
UCloud塊儲存研發工程師葉恆主要就雲硬碟架構升級和效能提升進行了講解。
雲硬碟架構升級目標
葉恆首先介紹了雲硬碟架構的升級目標,第一,解決老架構不能充分使用後段硬體能力的弊端。第二,支援SSD雲盤,提供QoS保證,可以用滿後端NVME物理盤的IOPS和頻寬效能,單個雲盤可達2.4W IOPS。第三,充分降低熱點問題。第四,支援超大容量盤,一個雲硬碟可以支援32T,甚至可以做到無限擴容。最後就是新架構上線之後,怎麼樣讓老架構遷移到新架構。
IO路徑優化
而葉恆認為要達成這樣的目標,首先需要對IO路徑進行優化。下圖是新老架構的架構圖,主要是IO路徑上的,左邊是舊架構,VM、Qamu,雲硬碟是掛在虛機裡面的,通過虛機來到Qamu的驅動,然後轉化到Client,Client之後會將IO轉到後端的儲存叢集上,分兩層,第一層是proxy,IO的接入層,然後再分到chunk,就是讀寫一塊磁碟,後端的chunk是一個副本的形式。
而在新架構中將IO的接入層去掉,直接將路由的功能做到client,直接連線到後端的儲存節點。這樣的話,在寫的時候,從client直接到chunk,因為三副本內容是完全一致的,讀只要讀主chunk就可以了。因此,讀路徑上就減少了一次網路轉發,相比於老架構的話,由於軟體的升級,隨機測下來,寫延時也有所降低。
元資料優化
在老架構中,分片大小是1G,新架構中,支援了1M大小的分片。1G的分片最多隻能發揮一塊物理磁碟的效能,對於普通硬碟,它後端的儲存介質是機械盤,效能有瓶頸。1M的分片會帶來很多好處,首先解決了熱點的問題,還可以充分發揮後端叢集效能,因為1M的分片,如果客戶的寫在1G的範圍內,端能用到1024的分片,整個叢集的效能就會全部發揮出來。
在資料組織方式方面,在老架構中,按索引的方式來組織元資料,申請一塊雲盤時,所有元資料分配成功,並持久化到元資料模組,掛載雲盤時,將所有元資料load到記憶體中,後續IO訪問直接從記憶體獲取路由。這樣看起來似乎沒有什麼問題,但在併發建立和掛載的情況下,如果有幾千個盤同時掛載,如果按1G的分片,300G的雲盤,300條的元資料,按1M的分片,300G是30萬條,它同時建立100塊300G的雲盤,需要分配3千萬條元資料,掛載也是一樣的,同時要從元資料模組載入3千萬條資料,這對元資料模組的設計難度是極大的,它會成為一個瓶頸。
因此在設計過程中,考慮過多種方案,方案一仍然保持帶索引的儲存方式,但在建立的時候不分配,把元資料延時分配,只有當雲硬碟上某個分片上有讀寫的時候,才向元資料請求,這樣的IO延時分配,好像是能解決問題。但如果這個時候使用者開機了,幾千臺一起開機建立好了,想做個測試,或者開始用了,同時對這100塊300G的雲盤做一個隨機的寫,隨機的寫會落到每個分片上去,這樣看,元資料模組仍然是個瓶頸。
第二種方案,選用了一個一次性雜湊,一個節點下線了,但是沒有機會去遷移或者分配到同一個故障率裡面去,這時通過後端的chunk服務,按三個三個一組,組成一個所謂的PG,PG就是備份組,將這個備份組作為物理節點,因此,物理節點就不是一個儲存節點了,而是一組備份級。當這個組作為物理節點插到這個環上之後,會作為虛節點放大,放大三、四千倍,保證這個環大概在幾十萬左右,不能超過百萬,因為構建這個環需要時間,如果這個環太大,重啟時間就會過長。而且這三個chunk也不是隨便寫三個chunk,按照容災的策略,這三個chunk組成一個PG,分別在三個機架中,如果機架斷電,最多影響一個。
把這三個chunk組成一個PG作為物理節點插入到這個環上,然後一個節點放大成幾千個虛節點,使用者建立一塊盤,上面每個分片派來IO之後,用這個盤唯一的ID,加上這個分片,去做雜湊,雜湊之後落到中間,找到了PG之後,它裡面包含了三條chunk的路由,將這個IO轉發到後端的主節點,由主節點去同步,主節點直接返回就可以了。
通過這個方案,以前動輒幾千萬的資料量,就是PG的個數,後端是chunk的一個路由,然後就是構建這個環的幾個引數,一個是對映的演算法,一個是虛節點的放大倍數,以及衝突解決引數。這樣當雲構建起來之後,向元資料模組請求這幾個引數,最多是幾千條,之後再構建這個環,這個環構建好了之後,有IO過來的時候,只需查這個環。而當查第一次的時候,系統會把計算好的路由記住,最後就可以直接找過去,非常快。這樣的話就完全解決了上述問題,同時創造幾千個盤是完全沒有問題,同時讀寫也沒有問題,這時因為讀寫過程中不需要去分配,因為全是計算出來的。
執行緒模型設計
具體到軟體設計就是執行緒模型設計,我們知道HDD與NVME效能差別有幾百倍。原來的軟體設計用一個執行緒就可以,一個CPU用滿的話,一個核跑幾萬沒有問題。但現在的軟體沒辦法去發揮這種硬體的能力,所以需要改變執行緒的模型。
在新的架構中,在雲端,採用了多執行緒的方式,每掛載一塊雲盤的時候,會分配一個執行緒專門用於IO轉化,後端是執行緒池,main eventloop就是IO執行緒,當某一個分片查這個環,發現要跟後端的某個chunk通訊,第一個連線分配到IO路徑1,迴圈派發,整個IO執行緒負責的連線就是均勻的。假如一個IO執行緒跑滿能跑5萬IOPS的話,現在跑130NVME,用它來管理執行緒30萬的NVME的話,六個這樣的執行緒就可以了,完全可以發揮硬體的效能。
防過載策略
任何一個儲存系統,都有一個過載保護的功能,比如說掛載了幾千塊盤或者幾百塊盤,使用者同時測試,落在儲存的某一個硬碟上,併發有幾千NVME,如果不做過載保護,IO將會全部超時。在新架構中,對於普通的雲硬碟,會限制物理盤上IO提交佇列的深度。
在實際程式碼實現的時候,要考慮到權重,雲硬碟的大小不一樣,大的雲硬碟,使用者要多付費,更大的雲硬碟,會獲得更多的傳送機會。對於SSD雲盤,傳統的單個執行緒會是瓶頸,難以支援幾十萬的IOPS以及1到2GB的頻寬。新架構會監控每個chunk的IO執行緒CPU的使用率,如果發現長時間CPU使用率都是95%或者100%,就會去通知這個chunk,斷開IO執行緒裡面一部分連線,分配到其他執行緒,實現了負載均衡的效果,使得每個執行緒的壓力都是均勻的。
線上遷移
葉恆介紹,為了幫助使用者從老架構向新架構遷移,UCloud為使用者提供了一套線上遷移系統,在進行遷移時,首先要把下圖中上部的clond old斷掉,連上trons cilent,同時寫一份到新老架構,然後通過trocs模組,當所有的存量資料都搬遷完成之後,這一次遷移就完成了。遷移完成之後,qemu就可以跟trons cilent斷開連線,連上一個新的cilent。這樣在遷移的過程中即使出現什麼故障,重啟之後,老架構仍然可用,從而降低了遷移的風險。
超高效能雲盤
葉恆還介紹了UCloud正在研發的下一代超高效能的雲盤,單個延時可以降低到100us,IOPS單盤可以突破百萬。而要達到百萬的IOPS的話,則需要用到使用者態、zero copy、polling mode,這幾個技術。使用者態就是把原來在核心態做的事情,比如網絡卡驅動,磁碟驅動,拿到使用者態來做,直接在使用者態操作裝置。polling mode,是為了解決CPU與儲存硬體的效能差異,使用polling mode,將會大大提升效能。zero copy,是指原來資料發一個包,需要從這個態拷到那個態,但現在完全在使用者態操作硬體的話,就是零拷貝,可以直接發出去。
UCloud是全鏈路的改造,因此,client端用了VHOST,網路端用RDMA,後端提交用SPDK。分別看一下這三個技術,在clinet端,原來資料從qume拷貝,現在資料直接VM,直接與clinet共享,這樣,只要做虛機的實體地址到後端實體地址對映,直接通過共享記憶體的方式就可以了。
在網路通訊部分,採用RDMA,DMA直接訪問記憶體,繞過CPU,從而降低CPU的使用率。RDMA直接訪問遠端的記憶體,這樣就實現了通訊的作用。
在後端,直接是SPDK,SPDK直接從使用者態來操作固態硬碟,當掛一個盤到機器上,在核心裡看不到,通過採用polling的方式,實現零拷貝,IO提交的延時非常低。
葉恆透露,在測試中,該高效能雲盤,單盤IOPS突破了百萬。預計此款超高效能雲盤將會在12月底推出公測版。
基於Cephfs的改進及優化
深信服科技儲存研發專家盧波最後一個登場,他就Cephfs的改進和優化進行了詳細的分析。
Ceph及CephFS的背景
盧波表示,Ceph是分層的架構,底層基於CRUSH,Ceph分佈的策略是針對分級的雜湊,跟一致性雜湊有區別,它是區分故障域的,分了兩級,第一級是物件到PG的對映,就是根據物件進行一個雜湊值,然後根據PG數舉模,最後得到這個資料物件分佈在哪個PG上面。PG到Ceph底下,它的每一個儲存裝置OSD,叫做物件儲存裝置,PG到OSD之間,就是通過CRUSH演算法來進行的路由。它的底層是基於RADOS,它是可靠,自動的分散式的一個物件儲存,具備的特性可以自修復,遷移,容錯,上層提供了物件儲存、塊儲存和檔案系統訪問三種方式。CephFS支援多種協議,最早起源於2007年Sage Weil的博士論文研究,最開始Ceph針對的應用場景更多是針對高效能運算,需要高擴充套件性大容量的檔案系統。
像Ceph這樣的分散式作業系統的出現,源於傳統單機檔案系統的侷限,第一是共享沒辦法在多個機器中提供應用訪問。第二就是單個檔案系統容量是有限的。第三是效能,傳統的檔案系統它可能沒辦法滿足應用非常高的讀寫效能要求,就只能在應用層面做拆分,同時讀寫多個檔案系統。第四是可靠性,受限於單個機器的可靠性以及單個硬碟的可靠性,容易出現故障導致資料丟失。第五是可用性,受限於單個作業系統的可用性,故障或者重啟等運維操作會導致不可用。
而這些特點對於企業級的應用或者私有云來說,是無法接受的,在這種情況下,就出現了CephFS。CephFS最早是一個博士論文研究,它實現分散式的元資料管理以及可以支援EB級的資料規模,後續專門成立了一個公司來做CephFS的開發,在2014年被Redhat收購,2016年CephFS釋出可用於生產環境的穩定版本釋出了,目前主要應用還是單MDS。
CephFS的架構
CephFS的架構不只是CephFS,包括Ceph也在裡面,第一個部分是客戶端,第二部分就是元資料。檔案系統最核心的是資料,所有檔案的訪問,首先離不開源資料的訪問,與塊儲存不一樣,塊儲存就是直接指定哪個硬碟的哪個位置,有了地址,就可以去讀取那個固定的資料。但Ceph的檔案系統是有目錄結構和層級結構,要管理這樣的目錄結構,需要通過元資料來實現。
Ceph MDS也是元資料架構,可以理解為它是一個元資料的快取,是一個元資料服務,本身並不儲存資料,它最終的資料是存在底下的RADOS的叢集下面,MDS本身是不儲存資料的。當客戶端要寫一個檔案,首先要開啟這個檔案,這個時候客戶端會跟MDS通訊,去獲取它的距離,客戶端拿到之後,通過一個雜湊,找到它位於哪個PG裡面,直接通過計算的方式,不再需要去跟MDS交付,確定了哪個PG之後,再把資料發到對應的資料值上面去,並且它的元資料和資料是分開的,可以存在不同的儲存池中,這種設計也是分散式檔案系統設計的跟傳統檔案系統不一樣的地方。
MDS的作用
MDS作為元資料的快取,同時控制元資料的併發處理,主要的作用有下面幾個:第一,要提供檔案資源,要對客戶端以檔案的方式,同時相容POSIX的語義。第二,要提供一個檔案系統名稱空間,它要通過MDS能夠構建出分散式檔案系統的一個目錄樹,一個層級結構。第三,要管理檔案的元資料,比如inode、dentry這樣的檔案元資料。第四,它需要持久化檔案元資料,把元資料儲存到一個可靠的儲存裝置上面去,在異常的情況下,保證這個資料是持久化的,可讀的,不會丟失資料。
MDS具有併發控制的流程,多個客戶端可以同時跟MDS通訊,MDS通過一個鎖來處理這個請求,同時客戶端跟元資料互動的時候,除了獲取元資料資訊之外,它還要知道客戶端是不是一個有效的客戶端,這個客戶端是不是能進行讀或者寫操作,以保證資料的一致性。
當MDS收到這樣的請求之後,會通過lock machine的模組,去判斷這個請求是不是可以正向操作,以及去覆蓋剛才訪問的許可權,最後會把這個請求返回給客戶端,然後會返回檔案的元資料資訊。
MDS是CephFS的一部分,另外CephFS還有三個點,MDS是實現元資料的分離,管理元資料,作為元資料的快取,另外MDS是一個叢集,可以有多個MDS,它是利用動態指數分割槽的技術,每一個MDS管理一部分的目錄,一個MDS可能負責一部分目錄層級,另外一個MDS負責另外一部分層級,這樣它可以做到很好的擴充套件性,它的效能也能得到提高,達到一個線性提升的目的。當然,現在還是單MDS的方式相對可靠一些,這是未來的方向。
Ceph的優化實踐
針對Ceph的問題,最直接和比較常見的想法,是縮短它的IO路徑,解決小IO的寫放大問題,第二,當前Ceph的IO路徑過長,延時高。第三,提升檔案的元資料寫操作的效能。第四就是支援寫快取的方式。第五,對讀也可以通過快取進行加速。第六,Ceph最早出現是針對廉價的節點或者是伺服器來設計的,但是現在的技術發展,有些在設計之初沒有考慮到,當然現在也在改進,這個優化也是能夠充分利用SSD或者新的網路傳輸介質這樣的優點來提高它的效能。
在業界,在這方面優化的思路有幾種,OceanStor9000的快取,是一個典型的分散式檔案系統,它通過全域性的快取,來實現任意節點上的檔案,它會對檔案進行分條,任意節點收到資料訪問請求之後,都會從這個快取裡面去看,是不是這個快取命中了,如果命中的話,這個時候直接返回客戶端。寫的話,首先直接也是寫到這個快取裡面,通過快取的全域性化,以後後臺快取資料的全域性化,去實現效能加速。快取的一個目的除了縮短IO路徑,還有一個好處,是可以把小的IO合併,形成一個大的IO這樣一起寫下去。
Fusion storage的處理思路是一樣的,也是用到了EC,如果是大IO直接寫EC,大IO直接用硬碟的儲存能力。但是小IO,就會通過EC Cache,寫到Cache裡面,這次IO結束了,就直接返回到客戶端。但後臺要保證這個Cache的資料最終持久化到HDD上面去,同時會進行IO的聚合。
Isilon是另外一個,這是NAS最早的一個產品,它裡面快取的分層分三層,第一是記憶體,第二層用到NVRAM的介質。第三層才是SSD。
Intel的思路是一樣的,因為它的IO路徑比較長,Intel提出了Hyper Converged Cache的思路,把這個開源了,這個思路是說,在客戶端就是由SSD來進行讀寫加速,它把後端的Ceph作為一個慢儲存來使用,在塊和RGW場景中,作為讀快取沒有問題,如果要作為寫快取,就涉及到冗餘的問題,所以在它的設計裡面,做寫快取的時候,是用到了DRBD這樣的雙拷貝,寫到快取裡面的時候,會做一個多副本。
通過加了這樣的快取之後,可以看到Datrium公司基於這樣的架構,做了一個快取的實踐,給出了一個性能,可以看到對於IOPS提升是非常可觀的。這裡有一個問題,多了一個快取對於Ceph來講是很難受的,為什麼?因為通過DRBD的方式,可靠性還是比較差的,對Ceph擴充套件性是打了折扣的。另外一個,這個快取要實現資料的持久化,不可能是主備的方式,因為這樣也是會降低可靠性的,所以要實現這樣的快取,是要實現分散式的一個管理邏輯。
盧波介紹說,針對這些問題,整體的思路跟前面幾種產品是一樣的,通過增加的塊儲存,來縮短IO路徑,進而提高小IO的效能。但是這個快取底下是一個分散式的使用場景,所以這個快取本身也是一個分散式的快取,下面是此架構的架構圖。
這個架構與Ceph相比,只是在中間多了一個OCS的快取服務,快取是一個獨立的服務,從客戶端請求,也叫做CA,是NFS過來的請求,都會轉化到快取服務上面來,在快取服務裡面,根據資料分佈策略,就知道這一次操作到底要寫在哪一個快取節點上面去,選到這個快取節點之後,快取節點實現多副本的資料分發,等多處副本完成之後,再返回給客戶端,這次操作完成,這是一個正常的寫入流程。
寫入之後,這個資料後臺是會定期根據水準高低,把快取的資料直接放到底層的Read儲存上面去。一方面利用了快取加速的效能,另外一方面,可以利用Read的全域性化性以及它的擴充套件性。
讀流程也是一樣的,因為快取對於小IO可以最大限度發揮空間的優勢,但是對於大IO,不需要經過快取,直接寫到底層的Read上去。另外通過索引的方式,也可以知道具體寫到哪個快取節點上去,大體流程就是這樣。而經過這樣改進之後,該系統的IOPS確實得到了提升。
Ceph未來展望
最後,盧波認為,CephFS最有殺傷力的一個東西,就是多MDS,即動態指數分割槽這樣一個技術,這方面在社群也會有一些深度的開發和討論,也在進行一些測試。下圖就是多MDS的技術原理,多個MDS去負責不同的目錄樹的元資料訪問,當客戶端來請求的時候,會去到不同的MDS,在這個MDS裡面,它去實現元資料的管理以及資料間的訪問。這是多MDS效能的對比,明顯可以看到,當8個MDS併發測試的時候,其效能基本上是可以達到線性增長的。