云存儲服務是云計算的重要組成部分。技術上,云存儲屬于大型分布式在線存儲范疇。云存儲是一大類特殊的共享存儲。作為提供存儲資源的服務,云存儲需要保證用戶存放的數據可靠,不丟失。同時,云存儲必須確保實時在線,任何宕機都會給用戶造成損失。因而,云存儲的基本要求是高可靠和高可用。此外,云存儲是海量數據的存儲,規模巨大。而且,出于成本和現金流量的考慮,云存儲的集群規模必須隨著用戶數據量的不斷增加而擴展。云存儲的架構,設計和技術運用都是圍繞這四個基本要求展開。反之,無論多么漂亮先進的技術,只要可能影響這些目標的實現,都不能應用于云存儲。
在我開始接觸存儲的時候,一致性哈希(以及著名的Dynamo)是非常熱門的技術。技術上一致性哈希很漂亮,簡潔,并且高效。但在實際應用中,卻是另一種表現。本文將對集中式的元數據存儲方案和一致性哈希作對比分析,以期說明元數據是更加適合云存儲的選擇。
1. 對象存儲,塊存儲
實用的云存儲可以分作兩類:對象存儲和塊存儲。對象存儲存儲是地道的數據倉儲,僅僅存放key/value數據:用戶有一個數據對象,需要存儲起來,他就給這個對象起一個名字(key),然后將對象連同名字一起存放入對象存儲。當需要的時候,用這個名字作為key,向存儲系統索要。而對象存儲系統必須在需要的時候將數據返還給用戶,除非用戶已將此數據從存儲系統中刪除。
塊存儲則是充當操作系統底下的塊設備(籠統地說,就是磁盤),供系統使用。塊存儲實際上就是一種SAN(Storage Attach Network),將集群的存儲空間分配給用戶,掛載到操作系統,作為磁盤使用。因為塊存儲需要模擬磁盤的行為,因此必須確保低延遲。
盡管兩種云存儲有完全不同的目標、用途和特性,但在分布式存儲基本特性方面都面臨著相同的問題,這里的討論對兩者都有意義。為了簡便起見,這里只討論對象存儲的情況。但很多內容和結論可以外推到塊存儲。
2. 存儲的基礎
云存儲功能非常簡單,存儲用戶的數據而已。但簡單歸簡單,幾個要點還是需要做的。當用戶將一個key-value對上傳至存儲時,存儲系統必須找合適的服務器,保存數據。通常會保存在多臺服務器上,以防止數據丟失。這叫多副本。
于是,一個關鍵的問題就是如何選擇存放數據的服務器。服務器的選擇是很有技術含量的事,需要兼顧到幾個要點:首先,數據必須在服務器之間平衡。不能把數據集中到少數幾臺服務器,造成一部分服務器撐死,而另一部分餓死。其次,在用戶讀取數據時,可以方便快捷定位。隨后,滿足云存儲服務高可靠高可用大規模的特點。最后,盡可能簡單。
于是,對于每個對象,都有一個key到數據存儲位置的映射: key->pos。映射方式很多,最直接的,就是將每一個對象的key->pos數據對保存下來。這些數據通常被稱為"元數據"。
但還有一些更巧妙的方式:根據key的特征,將key空間劃分成若干分組,并將這些分組對應到不同的存儲節點上。這種方式可以籠統地成為”Sharding"。如此,可以直接按照一個簡單規則定位到服務器。常用的分組方式之一是按key的區間劃分,比如a開頭的是一組,b開頭的是一組等等。而另一種更具"現代感"的分組方式,就是對key哈希后取模。哈希方案實際上就是哈希表的自然延伸,將桶分布到多臺服務器中。
這兩大類映射方式實質上是在不同的粒度上進行映射。"元數據"在對象粒度上,而sharding則是在一組對象的粒度。這兩種不同的粒度,決定了它們有著完全不同的特性。也決定了它們在實際應用中的表現。
3. 元數據和一致性哈希
于是,在云存儲方案中產生了兩大流派:元數據模型和Sharding模型。而Sharding模型中,一致性哈希最為流行。一致性哈希本身很難直接用作實際使用,進而產生了很多衍生方案,其中包括著名的"Dynamo"。這里用“一致性哈希方案”指代所有基于一致性哈希的設計。
元數據方案是對象級別的key->pos映射,也就是一個會無休止增長的"map"。每多一個對象,就會多一條元數據。通常會將元數據保存在一組數據庫中,方便檢索和查詢。元數據方案沒有什么特別的地方,其核心是元數據存儲部分。這部分設計的好壞,關系到系統整體的特性。關于元數據存儲的設計不是本文的重點,本文將集中探討元數據方案和一致性哈希方案的比較。
標準的一致性哈希模型是對key進行哈希運算,然后投射到一個環形的數值空間上。與此同時,對節點(存儲服務器)進行編碼,然后也做哈希運算,并投射到哈希環上。理論上,只要哈希算法合適,節點可以均勻地分布在哈希環上。節點根據自身在哈希環上的位置,占據一個哈希值區間,比如從本節點到下一個節點間的區間。所有落入這個區間的key,都保存到該節點上。
在這個模型中,key到數據存儲邏輯位置的映射不通過存儲,而是通過算法直接得到。但是,邏輯位置(哈希環上的位置)到物理位置(節點)的轉換無法直接得到。標準的做法是任選一個節點,然后順序尋找目標節點,或者采用二分法在節點之間跳轉查找。這種查找方式在實際的存儲系統中是無法忍受的。所以,實用的存儲系統往往采用的是一個混合模型(暫且稱之為“混合方案”):系統維護一個哈希區間->節點的映射表。這個映射本質上也是一種元數據,但是它是大粒度的元數據,更像是一個路由表。由于粒度大,變化很少,所以即便用文本文件都可以。這個映射表也需要多份,通常可以存放在入口服務器上,也可以分散到所有的存儲節點上,關鍵是保持一致即可,這相對容易。
一致性哈希解決了標準哈希表改變大小時需要重新計算,并且遷移所有數據的問題,只需遷移被新加節點占據的哈希區間所包含的數據。但是,隨著新節點的加入,數據量的分布會變得不均勻。為了解決這個問題,包括Dynamo在內的諸多模型,都采用了"虛擬結點"的方案:將一個節點分成若干虛擬節點。當節點加入系統時,把虛擬節點分散到哈希環上,如此可以更加"均勻地"添加一個節點。
一致性哈希及其衍生方案,將數據按一定規則分片,按一定規則將分片后的數據映射到相應的存儲服務器上。因此,它只需要維護一個算法,或者一個簡單的映射表,便可直接定位數據。更加簡單,并且由于少了查詢元數據,性能上也更有優勢。
但是,這只是理論上的。
如果我們只考慮存儲的功能(get,put,delete),一致性哈希非常完美。但實際情況是,真正主宰云存儲架構的,是那些非功能性需求:
1、 大規模和擴展性
2、 可靠性和一致性
3、 可用性和可管理
4、 性能
在實際的云存儲系統中,非功能需求反而主導了架構和設計。并且對key-pos映射的選擇起到決定性的作用。
4 規模和擴展
首先,云存儲最明顯的特點是規模巨大。對于一個公有云存儲服務,容納用戶數據是沒有限度的。不可能以"容量已滿"作為理由,拒絕用戶存放數據。因此,云存儲是“規模無限”的。意思就是說,云存儲系統,必須保證任何時候都能夠隨意擴容,而不會影響服務。
另一方面,云存儲作為服務,都是由小到大。一開始便部署幾千臺服務器,幾十P的容量,毫無意義。資源會被閑置而造成浪費,對成本和現金流量產生很大的負面作用。通常,我們只會部署一個小規模的系統,滿足初始的容量需求。然后,根據需求增長的情況,逐步擴容。
于是,云存儲系統必須是高度可擴展的。
面對擴展,元數據方案沒有什么困難。當節點增加時,系統可以更多地將新來的寫請求引導到新加入的節點。合適的調度平衡策略可以確保系統平衡地使用各節點的存儲空間。
但對于一致性哈希和它的衍生方案而言,卻麻煩很多。原始的哈希表一旦需要擴容,需要rehash。在基于哈希的分布式存儲系統中,這就意味著所有數據都必須重新遷移一遍。這當然無法忍受的。一致性哈希的出現,便可以解決此問題。由于對象和服務器都映射到哈希環上,當新節點加入后,同樣會映射到哈希環上。原來的區段會被新節點截斷,新加入的節點,會占據被切割出來的哈希值區間。為了完成這個轉換,這部分數據需要遷移到新服務器上。相比原始的哈希,一致性哈希只需要傳輸被新服務器搶走的那部分數據。
但是終究需要進行數據遷移。數據遷移并非像看上去那樣,僅僅是從一臺服務器向另一臺服務器復制數據。云存儲是一個在線系統,數據遷移不能影響系統的服務。但遷移數據需要時間,為了確保數據訪問的延續性,在遷移開始時,寫入操作被引導到目標服務器,而源節點的待遷移部分切換至只讀狀態。與此同時,開始從源節點遷移數據。當用戶試圖讀取遷移范圍內的數據時,需要嘗試在源和目標節點分別讀取。這種單寫雙讀的模式可以保證服務不受影響。但是,必須控制數據遷移的速率。如果遷移操作將磁盤吞吐能力跑滿,或者網絡帶寬耗盡,服務必然受到影響。
另一個問題是,除非成倍地增加節點,否則會存在數據不平衡的問題。為了平衡數據,需要遷移更多的數據,每臺節點都需要遷出一些,以確保每個節點的數據量都差不多。虛擬節點的引入便是起到這個作用。于是實際的數據遷移量同增加的容量數成正比,系數是當前存儲系統的空間使用率。
于是,一個1P的系統,三副本,70%的消耗,擴容200T,那么需要遷移大約140T*3=420T的數據,才能使數據存儲量得到平衡。如果使用現在常用的存儲服務器(2T*12),需要新增21臺。如果它們都并發起來參與遷移,單臺遷移速率不超過50MBps,那么這次擴容所需的時間為420T/(50M*21)=400000秒,大約4.6天。這是理想狀況,包括軟硬件異常,用戶訪問壓力,遷移后的檢驗等情況,都會延長遷移時間。很可能十天半月泡在這些任務上。而在數據遷移完成,老服務器的存儲空間回收出來之前,實際上并未擴容。那么萬一擴容實在系統空間即將耗盡時進行,(別說這事不會碰到,一個懶散的供貨商,或者廠家被水淹,都可能讓這種事情發生。云計算什么事都會遇到),那么很可能會因為來不及完成擴容而使系統停服。云存儲,特別是公有云存儲,擴容必須是快速而便捷的。
更復雜的情況是遷移過程中出錯,硬件失效等異常情況的處理過程會很復雜,因為此時數據分布處于一種中間狀態,后續處理必須確保系統數據安全一致。
系統的擴容規模越大,困難程度越大。當系統有100P的規模(很多系統宣稱可以達到的規模),而用戶數據增長迅猛(公有云存儲有明顯的馬太效應,規模越大,增長越快),在幾百上千臺服務器之間遷移成P的數據,是多么駭人的場景。
數據遷移會消耗網絡帶寬,吃掉磁盤負載,攪亂服務器的cache等等,都是云存儲的大忌,能不做盡量不做。
元數據方案一般情況下不需要做遷移。遷移只有存儲服務器新舊更替,或者租借的服務器到期歸還時進行。由于數據對象可以放置在任何節點上,因而可以把一臺節點需要遷移的數據分散到其他節點上。并且可以從其他副本那里多對多并發地傳輸數據。負載被分散到整個集群,對服務的影響更小,也更快捷。實際上,這個邏輯和數據副本修復是一樣的。
很顯然,相比一致性哈希方案動不動來回遷移數據的做法,元數據方案提供一個動態平衡的機制,可以無需數據遷移,服務器一旦加入集群,可以立刻生效,實現平靜地擴容。
5 可靠性和一致性
可靠性(本文特指數據的可靠性,即不丟失數據)無疑是云存儲的根本。用戶將數據托付給你,自然不希望隨隨便便地丟失。維持可靠性是云存儲最困難的部分。(當然,更難的是在保持高可靠性的前提下確保高可用)。
在任何一個系統中,硬件和軟件都無法保障完全可靠。芯片會被燒毀,電路可能短路,電壓可能波動,老鼠可能咬斷網線,供電可能中斷,軟件會有bug,甚至宇宙射線會干擾寄存器…。作為存儲的核心部件,硬盤反而更加脆弱。在標準的服務器中,除了光驅和風扇以外,硬盤是唯一的機電元件。由于存在活動部件,其可靠性不如固態電路,更容易受到外界的干擾。所以,硬盤時常被看作消耗品。在一個有幾萬塊硬盤的存儲集群中,每周壞上幾塊硬盤是再尋常不過的事。運氣不好的時候,一天中都可能壞上2、3塊。
因此,只把數據保存在一塊盤中是無法保障數據可靠的。通常我們都會將數據在不同的服務器上保存多份,稱之為“副本”。原則上,副本越多,越可靠。但是,過多的副本會造成存儲成本的增加,并且降低性能,增加維持一致性的難度。一般會保持3副本,是一個比較均衡的數字。
但是,在確定的副本數下,真正對可靠性起到關鍵作用的,是副本丟失后的恢復速度。比如,一個3副本存儲系統中,當一個磁盤損壞后,它所承載的數據對象就只剩2個副本了。在這塊盤修復之前,如果再壞一塊盤,恰巧和尚未修復的盤有共同的數據對象,那么這些數據就只剩一個副本在支撐著,這是非常危險的狀態。更有甚者,一個3副本的存儲系統,在運行過程中,即便沒有硬盤損壞,總會有一些對象由于種種原因處于兩副本狀態,尚未來得及修復。比如寫入數據時,有一個副本寫完后發現校驗碼不對,需要重寫。此時,如果一塊盤損壞了,上面正好有這些2副本的對象。于是,從這一刻開始,這個對象只有1副本。壞盤上的數據被修復之前,另一塊盤包含此對象的硬盤也壞了,那么數據就丟了。盡管這種概率很小,但是云存儲系統是經年累月地運行,大規模加上長時間,任何小概率事件都會發生。而且在實際運行的系統中,很多因素會導致硬盤壽命遠小于理論值,比如機架震動、電源不穩、意外失電、輻射等等。而且,對于成批采購的硬盤,通常都會集中在一段時間內一起進入失效期,多塊磁盤同時損壞的概率會大幅提高。
如果數據修復的速度足夠快,可以搶在另一塊盤損壞之前,修復丟失的副本,那么數據丟失的概率會大大減小。(嚴格地講,無論修復時間有多短,在修復期間壞第二塊盤的概率始終存在,只是修復時間越短,這個概率越小。關鍵是要讓它小到我們可以接受的程度)。
一致性哈希方案中,如果將一塊磁盤同一個hash區間一一綁定。因此,數據恢復時,只能先更換壞盤,然后從其他副本處讀取數據,寫入新磁盤。但是,磁盤的持續寫入能力通常也只有50-60MBps。如果是一塊有1.5T數據的硬盤失效,那么恢復起來至少需要30000秒,將近9個小時。考慮到服務器的整體負載和網絡狀況,時間可能會接近12小時。在這個時間尺度里,第二塊盤,甚至第三塊盤損壞的概率還是相當大的。而且,硬盤更換的時間取決于機房管理的響應能力,這往往是一個薄弱環節。
如果方案中讓節點同hash區間一一對應,在節點內部,再將數據分散存儲到一塊磁盤中,那么當需要恢復副本時,節點將損壞的磁盤上的數據對象分散存放到其他磁盤上。這樣,可以先發起修復,從其他副本那里都到數據,并發地向多個磁盤恢復數據,磁盤的吞吐限制會得到緩解。但問題的解決并不徹底。首先,網絡會成為瓶頸。1個千兆網口最多支持到120MBps,這個速率也僅僅比磁盤快一倍,而且實際使用中也不能將帶寬全部用光,否則影響服務,畢竟其他硬盤還是好的,還需要正常工作。原則上可以通過增加網口數量拓寬吞吐量,但這增加了網絡設備方面的成本。而且這也僅僅是增加3、4倍的吞吐能力,我們真正需要的是近10倍地縮小恢復時間。至于光纖,那不是普通公有云存儲所能奢望的。即便網絡吞吐問題解決了,還有一個更核心的問題。因為數據在節點內部任意分散到各磁盤上,那么節點就需要維護一個key->磁盤的映射,也就是節點內的局部元數據。這個元數據需要服務器自己維護,由于單臺服務器的資源有限,元數據的可靠性、可用性和一致性的維持非常麻煩。一套存儲一套元數據存儲已經夠麻煩的了,何況每個節點一套元數據。一旦這個元數據丟失了,這個節點上所有的數據都找不到了。理論上,這個元數據丟失了,也不會影響全局,可以利用一致性哈希算法到其他副本那里恢復出丟失的數據。但不得不將原來服務器上的所有數據都傳輸一遍,這個數據量往往有一二十T,恢復起來更困難。更現實的做法是直接掃描各磁盤,逆向地重建元數據。當然,這將是一個漫長的過程,期間整臺節點是不可用的,此間發生的寫入操作還需的事后重新恢復(具體參見本文“可用性”部分)。
副本恢復最快,影響最小的方法就是,不讓數據對象副本綁死在一臺節點上,只要數據對象可以存放到任意一臺節點,那么便可以在節點之間做多對多的數據副本恢復。集群規模越大,速度越快,效果越好。基于元數據的方案,每一個對象同節點,乃至硬盤的映射是任意的,在副本恢復方面,有得天獨厚的優勢。而一致性哈希嚴格地將數據同節點或磁盤綁定,迫使這種并發無法進行。
有一些基于混合方案的衍生方案可以解決一致性哈希在副本修復速度問題:將哈希環劃分成若干slot(bucket,或者其他類似的稱謂),數量遠遠大于將來集群可能擁有的節點數,或磁盤數。(好吧,我們說過規模無限,無限自然不可能,只要足夠大就行了,比如2^32)。slot到節點或者磁盤的映射,通過一個映射表維護。各副本集群中的slot分布互不相同。當一個磁盤損壞時,找出所包含的slot,將這些slot分散到其他節點和磁盤上去,這樣便可以并發地從其他節點以slot為單位恢復副本。在損壞磁盤更換之后,再將一些slot,可以是原來的,也可以是隨意的,遷移到新硬盤,以平衡整體的數據分布。遷移的時候,副本已經恢復,遷移操作的時間壓力就很小了,可以慢慢來,磁盤吞吐的瓶頸也不會有什么的影響。
但相比之下,元數據方案修復副本之后不存在數據遷移這一步,在這方面對象級元數據的存在使副本恢復簡單很多。
同數據可靠性相關的一個問題是一致性。一致性問題可以看作可靠性問題的一個部分。因為當各副本的數據版本不一致時,便意味著數據對象的當前版本是缺少副本的。(實際上,從存儲角度來講,一個數據對象的不同版本,就是不同的數據)。確保一個數據對象的一致性最實用的方法是所謂W+R>N。即N個副本中,一個版本寫入時確保有W個成功,而讀取時確保有R個成功,只要滿足W+R>N的情況,便可以保證始終可以讀到最后寫入成功的版本。
W+R>N的使用有一個問題,需要并發地從所有副本上嘗試讀取數據,然后通過讀取的數據對象版本(或者時間戳)的比對,以確定是否滿足一致性公式的要求。如果所讀取的數據有幾十上百MB,甚至上G的對象,一口氣讀出所有副本,而最終只取其中一個,著實浪費,系統壓力會整整大上N倍。解決的方法是先做一次預讀,讀出所有副本的版本信息,進行一致性比對,確定有效副本后,再行數據本身的讀取。
元數據方案在一致性上簡單的多。元數據為了保證可靠,也會使用多副本。因為元數據很小,可以保持更多的副本數,比如5個,甚至7個。如此多的副本,基本上不必擔心其可靠性。重點在于一致性。同樣也是采用W+R>N的策略,但卻將元數據讀取和一致性保障在一次訪問中解決。對于數據存儲服務器而言,任務更多地是在保障每一個副本和版本的完整。
隨著時間的推移,數據會發生退化,有各種原因造成副本的丟失。一致性也是一樣。對于熱數據,經常被訪問,存儲數據出錯很快就會發現。但冷數據需要依靠定期檢查發現錯誤。這個核對工作在元數據方案里,就是比對元數據和節點的每個盤上的對象清單,元數據保存的永遠是最新版本,只要不匹配,就可以認定出錯,立刻加以修復。但在一致性哈希方案中,需要交叉核對一個哈希區間的三個副本所包含的對象清單,以確定哪個對象是最新副本。然后再修正數據問題。
當一個節點由于種種原因下線,那么期間的所有寫入操作都無法完成。此時,元數據方案處理起來很簡單:另外挑選一臺合適的節點,寫入副本,更新相應的元數據項后,操作完成,一切太平。
一致性哈希方案要復雜得多。對于一個哈希區間的一個副本,被固定在一個節點上。換句話說,一組副本必須存放在特定的一個節點上,不能隨意放置。如果需要定位到其他節點上,必須整區間的遷移。這個特性的結果就是,當這臺節點下線后,無法寫入相應的副本,也無法隨意地將副本寫到其他節點上。后續處理有2種方法:1、將副本或者key寫入一個隊列,等節點恢復后,發起修復操作,從其他的副本獲得數據,補上缺失的副本。問題是這個隊列必須有足夠的可靠性,否則待修復key丟失,相應的對象會長時間缺少副本,直到數據一致性檢測發現問題。這會增加一致性檢測的壓力,使得原本就復雜的過程雪上加霜;2、按一定規則寫入其他節點,待恢復后原樣遷移回來。這個方案相對簡單些,但整個調度邏輯比較復雜,涉及到數據節點之間的協調。但是這種點到點的數據恢復,會給暫存服務器產生壓力,不利于穩定運行。不管哪種方案,數據遷移或者復制都是免不了的。這中間的異常處理,負載控制等都需要花費心思。
元數據方案在節點失效時的處理要比一致性哈希方案單純簡潔的多。節點失效是云存儲的常態,處理方式越簡潔越好。在大集群中,幾個節點同時下線都是很平常的事,一致性哈希如此復雜的節點失效管理,就是運維的地獄。
6. 可用性和可管理性
可用性在某些方面同可靠性有著共同的解決方案,比如多副本可以消除單點,提高可用性。但是它們在其他方面卻存在著矛盾。當一個副本寫入失敗,從可靠性角度而言,應當設法重試,或者索性告訴用戶寫入失敗。但這樣勢必造成響應變慢,或者可用性降低。(響應變慢超過一個程度后,便會被認為是失敗,不管最終是否成功)。此外,為了保障可靠性的諸多措施,比如副本修復,數據遷移等,會消耗系統資源,從而影響到可用性。
在上面對于可靠性的分析中可以看到,由于副本被綁定在特定節點上,一致性哈希要確保同元數據相當的可靠性的話,不得不放棄一些可用性,將有副本寫入出錯的操作返回失敗。因為元數據方案的數據存儲位置沒有限制,對于多數的副本寫入失敗可以通過重選服務器得到更正。一致性哈希則無此便利,要么放棄一定的可用性,要么承擔可靠性的風險。
根本上而言,一致性哈希在副本寫入上制造了局部的隱式單點,盡管是短期的或者臨時的,但依舊會對系統產生影響。一個設計良好的分布式系統會盡量地減少單點出現的可能性,這直接關系到系統的持續和瞬時可用性。元數據方案可以確保數據分布上不存在任何形式的單點。對于一個對象而言,任何節點都沒有特殊性,這種無差別化才能真正保證消除單點。
在云存儲系統中,使用公式R+W>N的地方,便是影響系統可用性的核心要點。可用性和一致性往往是一對冤家。在這個地方,需要向N臺服務器同時發出請求,而最終的有效性取決于服務器反饋的情況。一般來說,N越大,越容易在確保一致性的前提下,維持可用性。(實際上是取決于X=R+W-N的值,越大越好。這個值表示當X+1個副本下線或丟失后,系統將不能保證臨時的或永久的一致性)。但是,N-R和N-W越小,對可用性的影響越大。如果N=R,那么只要有一臺服務器下線,會造成系統不可讀取。如果N-R=3,那么即便是3臺服務器下線,系統還能正確讀取。對于W也一樣。在這里,一致性和可用性是一對矛盾。當副本數足夠多(N數可以很大),可以很容易地獲得較高的X數。比如N=7, R=W=5,X=3,N-R=2,N-W=2,意味著即便有2臺服務器下線,也能保證讀寫的有效性,同時確保一致性。
但如果N=3,無論如何也只能讓R=3或者W=3,此時盡管可以獲得X=3的一致性保障級別,但即便一臺服務器下線,也會造成系統不可用。如果R=W=2,可以保證1臺服務器下線,系統還是可用,但一致性保障級別降低到了X=1。
在元數據方案中,元數據的副本數(N)可以大些,故障和異常造成的副本下線,或者丟失,對系統的可用性和一致性產生的影響很小,對于這類問題的處理的緊迫性會低一些。相反,一致性哈希的一致性依賴于數據存儲節點,面對大大小小的數據對象,無法使用很多副本,通常都會用3。在這個N數下,無論一致性還是可用性,都很脆弱。
對于可用性而言,最后,也是最重要的一點是運維管理。運維的好壞直接決定了可用性。前文已述,一致性哈希在一些關鍵的系統維護點上相比元數據方案多出不少環節。在同樣運維水平和強度下,一致性哈希更加容易出現可用性問題。這方面對可用性的影響很難明確地給出量化的評判,但是運維是云存儲系統高可用保障的核心,運維的復雜性往往決定了最終9的個數。
現在來看看元數據方案的運維特點。元數據方案相比標準一致性哈希方案多出了一個元數據存儲系統。元數據通常有更多的副本,副本數越多,一致性的維持越發困難。一般的方案都是依賴異步執行的版本同步機制,盡快同步各副本。但是,為防止同步失效,會定期全面掃描核對所有元數據,確保元數據不會退化。這個過程伴隨者很大的數據吞吐和計算量。但這個過程是離線操作,并且沒有非常嚴格的時間要求,即便失敗,也不會過多地影響系統的運行。它的時間裕度比較大。元數據量不會很大,在合適的算法下,一致性比對的時間也不會很長,通常不超過2、3小時。并且可以根據需要增減所需的服務器數量。
一致性哈希運維的重點則在另一頭。一致性哈希模型及其各種變形由于需要確保數據平衡,不得不在擴容時進行大范圍的數據遷移。在不影響服務的情況下,遷移速率必須受到限制,導致遷移時間很長。但有時數據遷移的時間要求很高。因為在遷移完成之前,遷移的數據源所占的空間還不能回收。此時所添加的空間暫時無法使用。而且數據回收也需要花費時間。在可用空間緊迫的情況下,遷移速度的壓力會很大。一旦遷移過程中出現異常,將會雪上加霜。在長達幾天的數據遷移過程中發生磁盤損壞的可能性非常大,修復操作將迫使數據遷移減速,甚至停止。修復的優先級更高。遷移操作涉及很多服務器的并發,協調和控制工作很復雜。而且不同的遷移原因會有不同的遷移策略。再加上各種異常處理,運維管理內容很多,將是非常痛苦的事。隨著規模越來越大,最終可能超出運維能力的極限,無力維持存儲的可用性。
元數據方案在絕大多數情況下不會進行數據遷移。少掉這樣一個復雜重載的環節,對于系統維護的壓力會小很多。
因此,盡管元數據方案多出了一個元數據的存儲集群,但它相比一致性哈希方案反而更容易維持可用性。