互聯(lián)網(wǎng)的發(fā)展催生了云計算和大數(shù)據(jù)的發(fā)展, 云計算和大數(shù)據(jù)的本質(zhì)都是構(gòu)建低成本,高性能高可用的分布式存儲系統(tǒng),本文簡單介紹分布式存儲的一些基礎知識。
分布式存儲通過網(wǎng)絡連接的大量的普通服務器, 將數(shù)據(jù)分片分散在集群中的不同節(jié)點(服務器或進程)中,對外提供統(tǒng)一的服務。
分布式存儲一般需要具有幾個特性
可擴展:分布式存儲一般可擴展幾百甚至幾千臺服務器,并可容易的增加或減少節(jié)點, 在節(jié)點調(diào)整過程中, 分布式存儲服務可自動實現(xiàn)數(shù)據(jù)的遷移及負載均衡等操作。
低成本:組成分布式存儲服務的服務器可為普通服務器, 由于普通服務器故障率通常較高,因此要求存儲服務具有較好的容錯性。
高性能:分布式存儲理論上隨著節(jié)點數(shù)量的增加,對外提供的服務的性能應該成線性增長的趨勢。這是分布式存儲同非分布式存儲的一大區(qū)別之一, 一般非分布式存儲在數(shù)據(jù)量達到一定規(guī)模之后, 都會存在單點的讀寫問題,分布式存儲一般通過數(shù)據(jù)分片解決單點問題。
易用:分布式是存儲對外提供統(tǒng)一的接口, 用戶不需要關(guān)心數(shù)據(jù)的分片查找,副本維護等工作。
分布式存儲根據(jù)存儲類型可分為
分布式文件系統(tǒng):一般存儲非結(jié)構(gòu)的blob對象(文件,圖像等),比如淘寶的TFS, AWS的EBS, google的GFS等
分布式鍵值系統(tǒng):存儲關(guān)系簡單的半結(jié)構(gòu)數(shù)據(jù), 只提供基于鍵值的CRUD操作, 不能做關(guān)聯(lián)查詢, 比如Redis, Tair, MongoDB等
分布式表格系統(tǒng):用于存儲半結(jié)構(gòu)化數(shù)據(jù), 與鍵值系統(tǒng)相比, 除了提供CRUD操作外, 還支持基于某個主鍵的范圍掃描, 比如Google 的Big Table, AWS的Dynamo DB等
分布式關(guān)系數(shù)據(jù)庫:存儲關(guān)系數(shù)據(jù), 比如Taobao的Ocean DB。
存儲系統(tǒng)的性能瓶頸在于隨機的讀寫操作。下表列出了各種硬件的存儲性能比:
類別消耗時間訪問L1 Cache0.5 ns訪問L2 Cache7 nsMutex加鎖/解鎖100 ns內(nèi)存訪問100 ns千兆網(wǎng)絡發(fā)送1MB數(shù)據(jù)10 ms內(nèi)存順序讀取1MB數(shù)據(jù)0.25 ms機房內(nèi)網(wǎng)絡來回0.5 ms異地機房間網(wǎng)絡來回30~100 ms
SATA磁盤尋道10 ms
從SATA磁盤順序讀取1MB數(shù)據(jù)20 ms
固態(tài)SSD盤訪問延遲0.1~0.2 ms
SATA的順序讀取帶寬可以達到100MB以上, 由于磁盤的尋道時間大約為10ms, 順序讀取1MB數(shù)據(jù)的時間為:磁盤尋道時間 + 數(shù)據(jù)讀取時間, 即10ms + 1MB/100MB/s*1000=20ms。
分布式存儲系統(tǒng)一般需要解決幾個問題
數(shù)據(jù)分布
在分布式存儲系統(tǒng)中,如何將數(shù)據(jù)分片到不同的節(jié)點是首先要考慮的問題,一般分布式系統(tǒng)常使用的方法是Hash分布。
hash分布
哈希分布就是根據(jù)數(shù)據(jù)的某一個特征計算hash值, 并將hash值和集群中的節(jié)點做映射。從而將不同hash值的數(shù)據(jù)分布到不同的節(jié)點上。
hash分布的一個問題是一旦數(shù)據(jù)已經(jīng)分布到不同的節(jié)點中, 做擴容比較困難, 比如現(xiàn)在數(shù)據(jù)通過hash值分布到三臺機器上, 如果要將機器擴展到五臺, 需要重新將所有的數(shù)據(jù)重新算一下hash值, 然后重新分布。因此一般擴展節(jié)點的數(shù)量是原數(shù)量的一倍,這樣只需要移動一半數(shù)據(jù)。
一致性hash
一致性hash算法從某種程度上解決了擴展過程中移動數(shù)據(jù)太多的問題, 一致行hash算法給每個節(jié)點賦予一個hash值, 這些節(jié)點按順序構(gòu)成一個環(huán),數(shù)據(jù)根據(jù)hash值落在環(huán)中的某個節(jié)點上。當需要擴容時,將新加入節(jié)點放入環(huán)中,數(shù)據(jù)遷移只需要遷移新節(jié)點相鄰的節(jié)點上的數(shù)據(jù)即可。一致性hash容易造成數(shù)據(jù)偏斜, 而且在數(shù)據(jù)復制過程中, 對相鄰節(jié)點的壓力比較大。
一般系統(tǒng)會引入虛擬節(jié)點或虛擬槽的解決方式:即解耦數(shù)據(jù)與節(jié)點間的關(guān)系,引入虛擬節(jié)點, 將數(shù)據(jù)映射到大量的虛擬節(jié)點上, 然后虛擬節(jié)點在在映射到實體節(jié)點上,這樣在擴容過程中,可以以虛擬節(jié)點為單位移動數(shù)據(jù), 可從不同的實體節(jié)點上移動虛擬節(jié)點到新節(jié)點。很多存系統(tǒng)都采用了這種方案,如redis, Cassandra。
異常
分布式系統(tǒng)中,一臺服務器或者一個服務器上的不同進程被成為一個節(jié)點, 節(jié)點間通過網(wǎng)絡互聯(lián), 不論是節(jié)點還是網(wǎng)絡都是不可靠的。分布式系統(tǒng)需要處理由于節(jié)點或網(wǎng)絡引起的各種異常。
節(jié)點異常包括節(jié)點宕機或磁盤不可用(可恢復和不可恢復),分布式系統(tǒng)需要可以自動監(jiān)控的節(jié)點的異常, 并做相應處理:對不可恢復異常, 如果該節(jié)點值主副本節(jié)點, 則需要重新進行選主, 如果該節(jié)點是從副本節(jié)點, 則需要其他節(jié)點從主副本(或其他從副本)復制一份分片數(shù)據(jù), 保證副本數(shù)量不變。對可恢復異常, 需要恢復節(jié)點并重構(gòu)內(nèi)存。
網(wǎng)絡異常:通過網(wǎng)絡進行交互, 結(jié)果可分為成功, 失敗,和未知。未知的情況可能有成功也可能是失敗, 因此需要有重試機制, 而且多次調(diào)用的結(jié)果應該冪等。
復制
由于異常的存在,為了達到高可用的目的, 一般數(shù)據(jù)會有多個副本, 多個副本鍵間的關(guān)系有:
主從副本:主從副本只有主提供寫, 從可以提供讀服務(或僅是備份的作用),主從的缺點主的單點寫瓶頸, 但是由于數(shù)據(jù)被分片了, 如果數(shù)據(jù)的摸一個分片遇到寫瓶頸, 可以通過增加集群節(jié)點的方式解決,這要求分布式存儲的擴容比較容易,一般像redis, mongodb這種系統(tǒng)擴容都不會成為問題, 但是像ES, 分片數(shù)量不能修改, 擴容就需要重新倒入數(shù)據(jù)。
主主副本:同一個副本的不同節(jié)點都可以是進行寫操作, Cassandara即是用這種方式實現(xiàn)
一致性
因為同一份數(shù)據(jù)包含多個副本,副本間的一致性是分布性存儲系統(tǒng)需要考慮的問題。
一致性分為強一致性,弱一致性和最終一致性。最終一致又可分為:
讀寫一致性:A寫后, A后的讀都可獲得最新結(jié)果。
會話一致性:同一個會話內(nèi)寫后讀都可獲得最新結(jié)果。
單調(diào)讀:A讀取一次結(jié)果后, 后續(xù)讀取不會獲得之前版本的值。
單調(diào)寫:A的多次寫在多個副本間按照順序執(zhí)行。
一般分布式存儲系統(tǒng)都既可以支持強一致性又可支持最總一致性。
分布式存儲系統(tǒng)大體遵循相同的功能模式, 但具體實現(xiàn)又根據(jù)自身特點各有不同。在日常系統(tǒng)維護過程中,了解相應的分布式系統(tǒng)存儲的實現(xiàn)機制可以快速幫助定位問題并找到正確的解決方案。
責任編輯人:CC
評論