虚拟座谈会:有关分布式存储的三个基本问题
本文轉自InfoQ,作者楊賽
現在分布式存儲這一塊,有塊存儲、對象存儲、文件存儲,有不同的開源項目如Ceph、GlusterFS、Sheepdog、Swift,還有不同的商業實現如Google、AWS、微軟、金山、七牛、又拍、阿里云還有QingCloud,思路或多或少都有些不同,可選的硬件種類也很多。似乎可選的東西太多了,而且各有優缺點。
選擇的多樣性是好事,同時也對技術選型人員的知識和能力提出了更高的要求。在本次座談會上,我們提出了有關分布式存儲的三個基本問題,邀請領域內各路專家來分享他們的解讀。本次邀請嘉賓分別是:
王豪邁(麥子邁|wheats),UnitedStack工程師,擅長OpenStack、單機物理存儲、分布式存儲系統、Web應用棧等領域。OpenStack Nova、Cinder、Trove、Ceph、VirtualBox等項目的貢獻者。他的個人博客是麥子邁。
許式偉,七牛云存儲CEO,《Go語言編程》一書作者,ECUG大會發起者。2000年畢業于南京大學,后進入金山的WPS Office事業部,從事Office軟件的研發,是WPS Office 2005的首席架構師。2007年,許式偉創立了金山實驗室,致力于云存儲技術的研究。2009年,許式偉離開百度加盟盛大創新院,發起了盛大祥云計劃(盛大云前身)。2010年10月發布了面向個人的盛大網盤。2011年6月,許式偉離開盛大創辦了七牛,專注云存儲,專注為創業者服務。
甘泉,青云QingCloud聯合創始人&研發副總裁(Cofounder & VP of Engineering),具有14年軟件開發相關工作經驗。曾在華為公司、IBM 軟件實驗室任職;后在百度網頁搜索部擔任阿拉丁產品檢索基礎架構負責人。對Linux操作系統、網絡、存儲以及分布式系統架構、軟件工程等方面有比較深入的理解。
王旭,MadeiraCloud CTO,在來到 Madeira Cloud 之前,曾在盛大云進行云硬盤(彈性塊存儲)服務的開發、在中國移動研究院進行Hadoop HDFS和彈性存儲服務的開發,是《Cassandra權威指南》的譯者。
三個基本問題分別是:
對于一套分布式存儲的方案,怎樣評估它是好還是不好?
如何對分布式存儲的不同實現進行分類?
分布式存儲中的“數據可靠性”是如何計算的?
InfoQ:無論是在做方案的選型,還是實現一套存儲系統,權衡的因素主要考慮哪些?有沒有一套比較全面的考量/評估方式來決定哪種存儲方案更適合哪種場景?換句話說:當你去看一個存儲方案的實現,無論是看代碼還是實測,你如何評估這套方案哪里好,哪里不好?
甘泉:其實評價一個存儲方案好和不好,只有一個客觀的標準,那就是是否能滿足用戶的需求。不站在這個立場上思考這個問題,就會將技術凌駕于用戶需求之上,而技術應該是服務于用戶需求的。
那么我們可以簡單的剖析一下用戶對存儲的需求到底是什么。從青云的角度來說,有以下幾點是用戶需要的:
1、運行或在線系統需要高性能。這個不用多說,用戶的業務數據幾乎都會存儲在數據庫里面,沒有一個用戶會覺得數據庫性能不重要。
2、離線或備份數據需要高容量,低價格。這部分數據通常量很大,但是對性能要求不高,對不經常用的東西也不希望負擔高額成本。
3、所有的數據都必須是可靠的,絕對不能丟。這是用戶對于存儲的容忍底線,所有負責任的企業都會將可靠性放在最重要的位置上,在這個基礎上能達到多高的性能就看技術實力了。
所以從上面的分析來看,之所以沒有銀彈方案,是因為用戶對存儲的需求差異很大,不同的需求需要用不同的方式來解決。這就好像現在機械 硬盤已經存在這么多年了,磁帶依然沒有消失的原因,因為它用一種最廉價的方式解決了大容量離線數據的存儲問題,雖然它是最慢的。
王旭:
首先對象存儲和文件存儲的區別是不大的,存儲的都是一樣的東西,只是拋棄了統一的命名空間和目錄樹的結構,使得擴展起來桎梏少一些。
獨立的互聯網存儲服務一般都是做對象存儲的,因為塊存儲是給計算機用的,對象存儲是給瀏覽器等HTTP客戶端用的。獨立服務所提供的存儲系統,訪問都來自互聯網,自然是做對象存儲;與之相對應,大部分類AWS的主機服務商都會提供一個塊存儲服務搭配主機服務。
同一個服務商同時提供兩個服務是有好處的,除了提供的服務比較全這個優點以外,對象存儲還可以支撐塊存儲的快照、主機的系統鏡像存儲等應用,可以相互結合的。
權衡的因素有很多——可靠性要求、可用性要求、時延要求、一致性要求、使用模式相關要求(包括請求大小、QPS/IOPS、吞吐)等。
比如:
-
對于塊存儲,要求的訪問時延是 10ms 級的,因為給虛擬機用的,傳統硬盤也是10ms 級的時延,請求尺寸都很小,但qps(iops)可能會很高,那么在這種情況下:
-異地多中心是不現實的,存儲要和主機盡量接近,相應地可靠性必然會有所打折-強一致副本不會過多,強一致要求對時延有影響 對于對象存儲,要求的訪問時延是 100ms - 1s 級的,請求一般是中到大尺寸,低 qps 的,在這種情況下可以用更多的分散副本數來換取更高的可靠性,但過多副本增加維持一致性的難度,需要折衷。
另外SSD隨著成本降低,在塊存儲里逐漸成為主流了,以便提供更好的IOPS,AWS這個月開始,創建的EBS卷缺省就是SSD的了。
對于評價一個實現,首先是看適合不適合這個用途,然后看這個方案有沒有顯著的缺點,是否有嚴重的影響,然后成本之類的也是一個因素,做軟件的人總覺的用便宜硬件實現高大上的服務才值得吹牛,呵呵。
我得補充一點就是,做存儲這東西是需要良心的,一致性這種東西有的時候用戶是很難看出來的,偶爾一個程序出錯了,你一般不會懷疑是硬盤上存著的數據壞了,做存儲服務的人還是要盡量避免出現這種情況的。底層存儲服務(有別于數據庫)的一致性是一種很難被用戶觀測到的,但是如果一個實現根本沒達到應有的一致性,比如塊服務,只寫了一個副本就返回給應用說寫成功了,這樣是不太道德的,反正我個人堅持應該(EBS塊存儲)應該寫兩個副本再返回,在這個約束之內來優化。
也就是說,我的觀點是,先看是否滿足約束,然后看架構是否恰當,最后看細節流程的優化。
InfoQ:目前分布式存儲從應用場景、實現等層面來看,是如何分類的?
豪邁:分布式存儲的應用場景相對于其存儲接口,現在流行分為三種:
對象存儲: 也就是通常意義的鍵值存儲,其接口就是簡單的GET、PUT、DEL和其他擴展,如七牛、又拍、Swift、S3。
塊存儲: 這種接口通常以QEMU Driver或者Kernel Module的方式存在,這種接口需要實現Linux的Block Device的接口或者QEMU提供的Block Driver接口,如Sheepdog,AWS的EBS,青云的云硬盤和阿里云的盤古系統,還有Ceph的RBD(RBD是Ceph面向塊存儲的接口)。
文件存儲: 通常意義是支持POSIX接口,它跟傳統的文件系統如Ext4是一個類型的,但區別在于分布式存儲提供了并行化的能力,如Ceph的CephFS(CephFS是Ceph面向文件存儲的接口),但是有時候又會把GFS,HDFS這種非POSIX接口的類文件存儲接口歸入此類。
按照這三種接口和其應用場景,很容易了解這三種類型的IO特點,括號里代表了它在非分布式情況下的對應:
對象存儲(鍵值數據庫):接口簡單,一個對象我們可以看成一個文件,只能全寫全讀,通常以大文件為主,要求足夠的IO帶寬。
塊存儲(硬盤):它的IO特點與傳統的硬盤是一致的,一個硬盤應該是能面向通用需求的,即能應付大文件讀寫,也能處理好小文件讀寫。但是硬盤的特點是容量大,熱點明顯。因此塊存儲主要可以應付熱點問題。另外,塊存儲要求的延遲是最低的。
文件存儲(文件系統):支持文件存儲的接口的系統設計跟傳統本地文件系統如Ext4這種的特點和難點是一致的,它比塊存儲具有更豐富的接口,需要考慮目錄、文件屬性等支持,實現一個支持并行化的文件存儲應該是最困難的。但像HDFS、GFS這種自己定義標準的系統,可以通過根據實現來定義接口,會容易一點。
因此,這三種接口分別以非分布式情況下的鍵值數據庫、硬盤和文件系統的IO特點來對應即可。至于冷熱、快慢、大小文件而言更接近于業務。但是因為存儲系統是通用化實現,通常來說,需要盡量滿足各種需求,而接口定義已經一定意義上就砍去了一些需求,如對象存儲會以冷存儲、大文件為主。
實現方面,主要有兩層區別:
系統的分布式設計:主從、還是全分布式或者是兼而有之,目前現在存儲系統因為一致性的要求,以主從為主。
底層的單機存儲:一種是依賴本地文件系統的接口,如GlusterFS,Swift,Sheepdog,Ceph。一種是依賴塊接口的,目前只知道Nutanix是使用這個的。最后一種是依賴鍵值接口的,目前應該只有Ceph是支持(Ceph支持多種單機存儲接口)。第一種依賴文件系統是因為分布式存儲系統本身已經夠復雜,實現者很難從上層一直到底層存儲都去實現,而本地文件系統已經是一個通用化并且非常成熟的實現,因此分布式存儲系統絕大部分(上述提到的都應該是)都會直接依賴本地文件系統。第二種接口目前只知道Nutanix是支持的(傳統的存儲廠商的存儲產品一般會使用這種方式),這種接口也就是比第一種去掉了文件系統層,實現一個簡單的物理塊管理即可。第三種它的主要原因是“存儲定義”和對象存儲的普及,希望硬盤來提供簡單的鍵值接口即可,如希捷的Kinetic API,Fusionio NVMKV,這種接口另一方面是閃存廠商非常喜愛的,因為閃存的物理特性使得它支持鍵值接口比快接口容易得多,目前Ceph是支持這種接口,而希捷和華為最近推出了IP硬盤,聽說已經實現了Swift上的原型。
從這里可以發現,分布式存儲系統是在傳統的單機接口上重新包裝了一層,然后實現三種類似的接口。
策略方面,三副本、多AZ六副本和網絡RAID都是一類的,它們都是指數據的分布策略來提供數據可用性,通常來說前兩者情況就是數據的多個副本分布在所有服務器的幾個中,也就是只要超過副本數的服務器掛掉,存儲系統就面臨部分數據不可用的情況。網絡RAID是為了避免這種情況,比如在1000臺服務器的情況,將其分成10臺一組的100組,這樣同樣是一份數據(Data1)的三個副本都只屬于某一個組,它不可用只當1組內(10臺)中超過3個臺機器不可用時才會發生,這樣概率會小非常多。
EC是一個類副本策略,它可以理解為增強版的復制,更少的副本可以達到更好的數據可用。
硬件方面,SSD,SAS,SATA和內存的組合是為了提供數據訪問的性能。千兆、萬兆甚至Inifiniband是組合是為了提供網絡傳輸的性能。
許式偉:如果我們按存儲的業務邏輯分,那么可以分為:鍵值存儲(Key-Value Storage)、文件系統(File System)、數據庫(Database,不是很嚴謹,只是作為所有支持多鍵值的存儲的統稱)、消息隊列(MQ)等等。按這種分類方法存儲的種類是無窮盡的,我曾經說過 “存儲即數據結構”,表達的就是這個意思。數據結構無窮盡,存儲也會無法窮盡。塊存儲我們很少把它劃分到上面的分類中,因為它是虛擬存儲設備,是為 VM 服務的一個東西,并不直接面向用戶業務(用戶不需要調用塊存儲設備的 api 來完成業務,當然如果我們把 VM 也認為是一個業務系統的話,塊存儲也勉強可以作為一種特定的數據結構存在)。對象存儲(Object Storage)是鍵值存儲(Key-Value Storage)的特例,它假設Value是文件,尺寸范圍可以很大(比如七牛可以支持文件大小從0字節到1TB)。如果要對對象存儲做進一步分類,我能夠想到的就是按實現方案來分類。比如按冗余方案來分,可分為多副本、RAID、糾刪碼等等;或者我們按一致性方案分,可以分為主從結構和對等結構等。
不會有什么存儲方案能夠一統天下。不同業務系統的場景需求不同,對存儲的訴求會不同,選擇自然會不同。基于糾刪碼的存儲系統,復雜性遠高于三副本的存儲系統。從易維護的角度,如果業務對存儲成本不敏感,那么人們自然而然會選擇三副本的方案。
王旭:除了開源服務外,這些私有的實現都沒有太公開自己的實現,不同的實現確實差異很大。但另一方面因為有共同的目標,常常有很多細節是做得差不多的,比如很多對象存儲都會把小對象放到一些預分配的大塊存儲區域里,然后定期做compaction,來提高存儲效率、避免文件系統碎片等。
對于塊服務,有些實現是比較簡單直接的,直接把存儲分成塊,用戶有申請,就調度到某幾臺機器上,分配一些塊,組成卷給用戶用,而有些實現是比較高層的,會先構建一個底層的分部式存儲系統,然后再從中分配塊給用戶用。后者技術含量更高一些,但一般前者的實現都屬于簡單直接型,實際效果反而更好(性能、故障處理等)一些。
InfoQ:所有做云存儲的都表示數據丟失是不可接受的,但數據丟失的概率——即理論上的數據可靠性(reliability),不同方案的計算方式是不同的。你們是怎么做的,或者現在有哪些比較成熟的資料描述這個計算方法的?
豪邁:實際上這個計算是需要依賴于存儲系統本身的。我們使用Ceph,Ceph的優勢是提供了一個叫CRush算法的實現,可以輕松根據需要來規劃數據的副本數和高可用性。參考Ceph提供的模型定義來規劃自己的。這是我的同事朱榮澤做的故障計算,這個計算只針對副本策略,并不適合使用EC(擦除碼)的情況。
硬盤發生故障的概率是符合泊松分布的。 fit = failures in time = 1/MTTF ~= 1/MTBF = AFR/(24*365) 事件概率 Pn(λ,t) = (λt)n e-λt / n! 我們對丟失數據是不能容忍的,所以只計算丟失數據的概率,不計算丟失每個object的概率。 N代表OSD的個數 R代表副本數 S代表scatter width,關系著recovery時間 我們忽略Non-Recoverable Errors的概率 計算1年內任意R個OSD發生相關故障概率的方法是 1年內OSD故障的概率。 在recovery時(R-1)個OSD發生故障的概率。 以上概率相乘。假設結果是Pr 因為任意R個OSD不一定屬于Ceph的Copy Sets,則Ceph的丟失Copy Sets的概率是: M = Copy Sets Number 在N個OSD中,任意R個OSD的組合數是 C(R,N) 丟失Copy Sets的概率是 Pr * M / C(R, N)。 最終公式是: P = func(N, R, S, AFR)許式偉:可靠性的定義可以有不同,比如有人會定義為:假設整個系統有 L 個對象,在 1 年內會損失 m 個對象,那么可靠性為 1 - m/L。我在我那篇文章中的定義是:整個系統有 L 塊硬盤,1 年內丟失數據的概率是多少(而不管丟失了多少個對象)。
沿用文章中的可靠性定義,數據可靠性的計算涉及到以下幾個量:
集群規模-總硬盤數目(L)
容錯度(M)
修復速度(t)
單盤可靠性(p:在t時間內損壞的概率)
我的計算方法是,先計算這L塊硬盤在t時間內同時損壞M+1塊硬盤的概率是多少(Pt,也就是丟失數據的概率,當然有細心的網友說t時間內同時損壞M+1塊盤不一定會丟失數據,這點當然是正確的,但是這個丟失數據的概率雖然不為1但是非常接近1,而且此時對軟件系統來說已經是失控狀態,為了簡化計算假設為1),然后把時間拉長到1年(T)的數據丟失概率(P)。這個拉長是非常簡單換算公式:
P = 1 - (1 - Pt)^(T/t) ≈ Pt * (T/t)
所以關鍵是計算 Pt(這L塊硬盤在t時間內同時損壞M+1塊硬盤的概率)。我們擴展一下,用 Pt(i) 表示 t 時間內有且僅有 i 塊盤損壞的概率。前面的 Pt 實際上是 Pt(>M),而不是 Pt(M+1)。不難得出:
Pt(>M) = 1 - Pt(0) - Pt(1) - ... - Pt(M)
好了,我們就剩下計算 Pt(i) 了。這個概率的計算比較常規:
Pt(i) = C(L, i) p^i (1-p)^(L-i)
其中 C(L, i) 是組合數,也就是 C(L, i) = L! / (i! * (L-i)!)
至此整個計算過程完成。不過有一個細節需要說明下,由于以下兩個原因,你無法用計算機常規的浮點數計算來得到 P:
C(L, i) 值會很大,甚至會超過 float64 浮點類型的最大值(約為1e308),用浮點運算最終會變 Inf(無窮大)。
p 非常小,這會導致計算過程精度損失非常大,計算的累計誤差無法忽略,答案和理論值大相徑庭。
所以如果你真要去算這個概率,需要用無損計算的數學包。
甘泉:我們這個概率的計算和RAID是類似的,我們可以將RAID的概念延伸一下,其實RAID的本 質就是replication,通過多個副本來解決一個或者多個節點出問題造成的影響。所以不管是本機的副本,還是跨網絡或者跨地域的副本,本質上都是在用replication做冗余。
王旭:其實只是丟數據的概率問題,沒有云存儲服務可以承諾絕不丟的。國內有個問題,就是——如果我在服務條款里說了可能丟數據,那用戶就不愿意用了(“云還丟數據?!”),競爭對手的公關也要找上門來了;可是丟數據的 case 總是可能存在的,那么,一旦丟了就是沒有盡到告知義務,而且還是會被炒作(“云還丟數據” again),但實際上這是個 SLA 嘛,生意上的事,最后要用錢解決的嘛。
AWS的兩個主要資源層存儲服務是 EBS 和 S3,后者是對象存儲服務,強調數據可靠性,承諾11個9的 Durability,據說實際能達到更高;而EBS承諾的是年平均故障率(AFR),一年中發生塊設備故障而導致卷無法使用的概率,這個要求實際上不高的。
對于存儲服務,對象存儲可以視為在線數據的最終存儲方案,要保證更高的可靠性,而EBS是半永久存儲方案,只有結合備份方案、多副本方案或者快照,才可以保證高可靠性的,教育用戶是云服務行業不能回避的任務,騙用戶說我絕對可靠是不行的,出來混是要還的。
原文鏈接: https://community.qingcloud.com/topic/10
總結
以上是生活随笔為你收集整理的虚拟座谈会:有关分布式存储的三个基本问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Please enable make s
- 下一篇: C#、VB.NET 使用System.M