(一)關鍵問題
- 數據分布
對於存儲系統,最重要的問題就是數據分布,即什么樣的數據放置在什么樣的節點上。數據分布時需要考慮數據是否均衡、以后是否容易擴容等一系列問題。不同的數據分布方式也存在不同的優缺點,需要根據自身數據特點進行選擇。
1)哈希分布 => 隨機讀取
取模直接哈希:將不同哈希值的數據分布到不同的服務器上
關鍵:找出一個散列特性很好的哈希函數
問題:增加、減少服務器時的大量數據遷移
解決:1)將<哈希值,服務器>元數據存儲在元數據服務器中;2)一致性哈希
一致性哈希: 給系統每個節點分配一個隨機token,這些token構成一個hash環。執行數據存放操作時,先計算key的hash值,然后存放到順時針方向第一個大於或者等於該hash值的token所在節點。
關鍵:哈希值變成了一個范圍,每個物理節點上存儲的數據是哈希值處於前一段范圍的數據。
優點: 節點增加/刪除時只會影響到在hash環中相鄰的節點,而對其他節點沒影響。
維護每台機器在哈希環中的位置方式:1) 記錄它前一個&后一個節點的位置信息,每次查找可能遍歷整個哈希環所有服務器;2) O(logN)位置信息,查找的時間復雜度為O(logN);3) 每台服務器維護整個集群中所有服務器的位置信息,查找服務器的時間復雜度為O(1)
虛擬節點:將哈希取模的模數取得很大,就會得到更多的哈希值,這個哈希值成為邏輯節點,一個物理機器可以根據自己的能力選擇若干個邏輯節點的存儲節點。
優點:將傳統哈希的一(物理節點)對一(哈希值)的分布變成了一(物理節點)對多(哈希值)的分布。可以根據物理節點的能力調整數據的分布。
2)順序分布 => 順序掃描
表格上的數據按照主鍵整體有序
- 負載均衡
1)數據寫入時,寫入節點的選擇(空間容量?CPU負載?)
2)運行過程中,數據的遷移
如果運行過程中有新機器的加入,導致每個機器的存儲數據量不同,需要能夠自動發現,並自動進行調整。但是在調整的過程中也要控制好速度,以免對業務產生影響。
- 復制&多備份
1)最大保護模式
強同步復制:至少在一個備庫上執行成功
至少成功存儲2個備份,才返回成功。
2)最大性能模式
異步復制模式:主庫執行成功即返回
只要成功存儲1個備份,就返回成功。
3)最大可用性模式
兩種模式折衷:正常情況是最大保護模式,出現故障時變成最大性能模式
- 數據一致性
版本號:在收到寫入數據請求時,生成對應版本號。
刪除老的版本號;讀取時,保證讀取到的是最新的版本號的數據;寫入時,保證寫入數據的版本號要新與存儲的。
- 容錯
1)故障檢測
心跳:S每隔一段時間向C發送一個心跳包
租約機制:帶有超時時間的授權
2)故障恢復
master:主備機制,持久化索引
datanode:永久故障,增加備份
- 可擴展性
1)總控節點是否成為瓶頸
不是瓶頸:舍棄小文件的處理,數據的讀寫控制權下放到工作機,通過客戶端緩存元數據減少對總控節點的訪問
內存成為瓶頸:采用兩級結構,在總控機與工作機之間加一層元數據節點
2)同構系統
存儲節點分為若干組,每個組內的節點服務完全相同的數據
3)異構系統
將數據划分為大小接近的分片,每個分片的多個副本分布到集群中的任何一個存儲節點,某個節點發生故障,原有的服務將由整個集群而不是某幾個固定的存儲節點來恢復
(二)GFS(google分布式文件存儲)
- 適用場景
1)適當數量大文件(超過100MB),GB以上很常見
2)大量流式讀,小量隨機讀,連續寫,追加寫
3)高帶寬比低延時更重要,要求快速處理大量數據,對單一操作的響應時間無嚴格要求
4)不適合多用戶寫入
- 數據分布
單位:chunk(64MB);一個文件占用多個chunk
優:1)減少client與master交互次數;2)減少client與chunkserver交互次數;3)減少元數據規模
缺:1)內部碎片;2)熱點小文件使chunkserver負載過重
- 負載均衡
1)數據寫入時,通過磁盤利用率、最近創建chunk數量來決定寫哪個chunkserver,並保證chunk所有副本不在同一機架
2)運行過程中的數據遷移,根據吸盤適用率、負載,將>平均的chunk遷到<平均的
- 復制
寫入主副本,再寫入備副本,全部寫完后才返回成功
- 數據一致性
使用租約機制保障在跨多個副本的數據寫入中保持順序一致性。 GFS Master將chunk租約發放給主副本,主副本確定針對該chunk的寫入順序,次副本遵守這個順序,以此保障了全局順序一致性。
- 容錯
master:持久化1)命名空間,文件系統目錄結構&chunk信息;2)文件到chunk之間的映射;log和checkpoint技術,checkpoint相當於全量備份,log記錄元數據的每一次變化
chunk:1)多副本;2)校驗和檢測錯誤數據
- 可擴展性
擴展chunkserver
- 數據讀寫
1)讀數據。客戶端緩存了從master請求的副本位置,直接選擇最優的副本訪問。
2)寫數據。采用流水線方式,分離數據流和控制流。客戶端選擇最佳的網絡拓撲按照流水線技術傳輸數據。主副本決定數據的寫入順序。
(三)TFS(taobao分布式圖片存儲)
- 適用場景
海量小文件(不超過1MB)
- 數據分布
單位:block(64MB);一個block上存儲多個小文件
每個block在整個集群擁有唯一ID=>blockID,由namenode分配
namenode:1)維護每個block與datanode的相關信息and可寫block信息列表;2)dataserver的加入、退出和心跳信息
datanode:1)維護block中每個文件位置信息(blockID,塊內fileID);2)實際數據的存儲和讀寫
- 負載均衡&復制
1)數據寫入時,根據可寫塊,容量,負載決定
2)集群負載輕的時候,namenode對datanode上的block進行均衡;優先選擇統計器的源到目的之間的移動,也就是童泰datanode的不同datanode進程。
- 數據一致性
namenode寫主副本,主副本寫備副本,更新版本號,返回客戶端
- 容錯
1)namenode:主備HA結構。
兩台機器互為熱備,同時運行,一台為主,一台為備。
主機綁定到對外vip,提供服務;當主機宕機后,迅速將vip綁定至備機,切換其為主機。
2)datanode:namenode檢測到備份數減少的block,對這些block重新進行數據復制。
3)故障檢測:心跳,datanode會把自己擁有的block發送給namenode,namenode會根據這些信息重建datanode和block的關系
- 可擴展性
擴展datanode節點。將相應數量的新datanode服務器部署好應用程序后啟動即可。這些datanode服務器會向namenode進行心跳匯報。namenode會根據datanode容量的比率和datanode的負載決定新數據寫往哪台datanode服務器。
- 數據讀寫
1)客戶端將文件名轉換為blockID和fileID信息;
2)在namenode取得該塊所在datanode信息,如果客戶端有該block與datanode緩存,直接從緩存中取;
3)直接與datanode進行讀取操作
(四)Haystack(facebook分布式照片存儲)
- 適用場景
1)大量小文件
2)越新寫入的文件越容易被讀到
3)大量讀,少量寫,幾乎無修改
- 數據分布
單位:colume(100GB);一個邏輯colume對應不同機器上的3個物理colume
每個圖片作為一個needle放在一個物理卷文件中,包含圖片數據和邏輯圖片的元數據;部分元數據裝載到內存中作為index用於圖片查找。
- 核心組件
1)Haystack Store(持久化存儲系統)負責圖片存儲、管理圖片的文件系統元數據。將其下所有吳麗娟的fd緩存在內存中
2)Haystack Directory(目錄)維護邏輯到物理卷的映射、圖片到邏輯卷的映射、某個邏輯卷的空閑空間等。采用Replicated Database做持久化存儲,前面增加一個memcache集群滿足查詢需求。
3)Haystack Cache,類似於系統內部的CDN。可理解為一個分布式Hash Table,使用圖片ID作為key來定位緩存的數據。
- 負載均衡
Directory在分配寫請求到邏輯卷、分配讀請求到物理卷時保證負載均衡。
- 數據一致性
只要寫操作成功,邏輯卷對應的所有物理卷都存在一個有效的照片文件,但照片文件在不同物理卷中的offset可能不同。
- 容錯
1)故障檢測:pitchfork周期性檢測每個store機器的健康度,檢查其每個卷文件的可用性,並嘗試讀取數據。
2)故障恢復:bulk操作使用副本卷文件重置某個store機器的所有數據(對於永久損壞的磁盤)。
- 可擴展性
增加Haystack Store存儲節點。
- 數據讀寫
1)讀數據:瀏覽器->web服務器->Haystack目錄->web服務器->瀏覽器->CDN->Haystack Cache->Haystack Store
2)寫數據:發送到web服務器,web服務器從Directory中請求一個可寫邏輯卷;web服務器為圖片分配一個唯一的ID,然后將其上傳至邏輯卷對應的每個物理卷。
(五)Dynamo(亞馬遜分布式鍵值存儲)
- 適用場景
1)查詢模型:基於K-V模型,而不是SQL關系模型
2)存儲對象較小,通常小於1MB
3)數據存儲的寫是高可用的(將協調沖突的復雜性推給讀,以確保寫永遠不會拒絕)
- 設計考慮
1)增量的可擴展性:水平擴展一台存儲主機,而對系統操作者和系統本身影響很小。
2)對稱性:每個節點與它的對等節點責任相同。
3)去中心化:沒有集中管理的節點。
4)異質性:機器配置異質,負載的分配與各個服務器的能力成正比。
- 數據分布
一致性hash => 虛擬節點
1)一致性hash
在一致性哈希中,哈希函數的輸出范圍為一個圓環,如圖2所示,系統中每個節點映射到環中某個位置,而Key也被Hash到環中某個位置,Key從其被映射的位置開始沿順時針方向找到第一個位置比其大的節點作為其存儲節點,換個角度說,就是每個系統節點負責從其映射的位置起到逆時針方向的第一個系統節點間的區域。
問題:1)熱點數據導致數據分布不均;2)每個節點性能型號不同但無法按照節點能力划分數據
2)虛擬節點
每個節點從邏輯上切分為多個虛擬節點,一個物理節點可以按照其處理能力給其划分多個或者一個虛擬節點。
1)虛擬節點數要遠大於物理節點數
2)加入一個物理節點時,可以從其他多個物理節點均分出虛擬節點給它
- 負載均衡&復制
每個Key被分配到一個協調器(coordinator)節點,協調器節點管理其負責范圍內的復制數據項,其除了在本地存儲其責任范圍內的每個Key外,還復制這些Key到環上順時針方向的N-1個后繼節點。
B負責(A~B)范圍的復制數據項,除了存儲key值到本地,還要在B、C處復制key。
1)由於存在虛擬節點,需要跳過環上某些位置,讓鍵的首選節點列表分別位於不同的物理節點上。
2)首選列表:負責存儲特定鍵的節點列表。
- 數據一致性
允許系統中同一時間出現多個版本的對象,客戶端協調多個沖突版本提供最終一致性
1)使用向量時鍾來標識同一數據在不同節點上多個副本之間的因果關系。向量時鍾實際上就是一個(節點,計數器)列表。
2)讀取過程中的協調。數據版本之間的關系要么是因果關系,要么是平行關系,關系判斷依賴於計數器值大小,如果第一個時鍾對象的計數器小於或等於所有其它時鍾對象的計數器時則是因果關系,那么因是果的祖先可以認為是舊版數據而直接忽略,否則是平行關系,那么就認為數據版本產生了沖突,需要協調並合並。
3)當客戶端要更新一個對象,必須指定要更新哪個版本。
- 容錯
1)對於臨時故障的處理:暗示移交,數據key本來發往A(A臨時故障),發往了D;key被定期掃描,如果A復蘇,D發送key到A,並從本地刪除key。
2)對於永久故障的處理:副本同步。
3)環關系。每個節點每隔一秒隨機選擇一個對等節點,通過gossip協議傳播節點的映射信息,最終每隔節點都知道對等節點所處理范圍。
4)新加節點發現。通過種子節點協調所有節點的成員關系。
5)錯誤檢測。每個節點都可以了解其他節點的加入和離開。
- 可擴展性
一致性hash
- 數據讀寫
三個關鍵參數(N, R, W),其中,N是指數據對象復制到N台主機,協調器負責將數據復制到N-1個節點上,亞馬遜建議N配置為3,R代表一次成功的讀取操作中最小參與節點數量,W代表一次成功的寫操作中最小參與節點數量。 R和W值過小則影響一致性,過大則可用性。
1)寫操作:協調員(首選列表之一)生成向量時鍾並本地寫入新版本=>將新版本發給首選列表中可達節點=>收到W-1個節點響應->成功
2)讀操作:協調員(首選列表之一)請求首選列表所有版本數據=>等待R個響應返回給客戶端沒有因果關系的版本=>不同版本被協調,取代當前版本,寫回
(六)Tair(taobao分布式鍵值存儲)
- 適用場景
分布式鍵值存儲引擎
- 數據分布
單位:主鍵計算哈希值后的桶。
- 負載均衡
Config Server按照一定的策略把每個桶指派到不同的Data Server上,只要保證桶的分布的均衡性,就能保證數據分布的均衡性。
- 容錯
1)Data Server故障,Config Server能檢測到,如果備副本->復制數據到新的Data Server;主副本->提升另外的備副本為主副本,復制數據到新的Data Server。
2)Config Server故障,備Config Server提升為主Config Server對外提供服務,等Config Server修好,成為備的Config Server。
- 可擴展性
添加Data Server機器
- 數據讀寫
客戶端緩存路由表,客戶端可以不需要訪問Config Server,直接訪問對應Data Server。每次路由變更,Config Server都會將新的配置信息推給Data Server。如果客戶端路由表版本過舊,會重新去Config Server獲取新的。