分佈式文件存儲系統-集羣管理

這篇文章比預期來的要晚一點,第一遍接近完成時,腦子一熱去清理了一下草稿箱,然後右手一抖就把它給刪了,然後又不得不來第二遍。。。。這個時候分佈式備份就顯得尤爲重要!!!

言歸正傳,本文對分佈式文件系統的集羣管理功能進行闡述,對其進行歸納和整理,認爲分佈式文件系統的集羣管理功能需要做到以下幾點:

  • 維護系統的物理模型
  • 維護系統的邏輯模型
  • 維護邏輯模型到物理模型的映射

對於分佈式系統爲了提高容錯性,我們常常會將物理存儲介質做劃分和隔離,以磁盤作爲最小存儲單位,構成一個存儲服務器,再由多臺服務器構成一個機架,我們把這些關係抽象成模型就可描述爲分佈式文件系統的物理模型。這樣的劃分和隔離,可以增加系統的可靠性,同時也可以簡化運維操作。

對於分佈式文件系統而言,解決的主要問題是從文件到最終存儲介質的映射關係。這一過程我們可稱做爲是數據定位,數據定位的過程可以理解爲是數據流,而本文要說道的集羣管理屬於管理流,爲了能讓數據流能正常流通,集羣管理必不可缺。如下圖1所示即爲分佈式文件系統集羣管理功能需要完成的工作,本文主要圍繞下圖展開。

 

圖1

1. 模型的定義

1.1 物理模型

在分佈式文件系統中,存儲介質從磁盤、機器、機架到機房,從模型的角度來看它們的從屬關係如下:

 

採用樹形結構來表示更爲直觀,如下圖所示

圖二

  • dev: 物理服務器上的一塊磁盤,我們看做分佈式文件系統的最小物理存儲單位,所說的存儲節點多也以一塊磁盤作爲最小管理單位。
  • node: 物理服務器,磁盤的集合。
  • zone: 物理服務器的集合,引入zone可增加數據的可靠性,我們將數據的不同副本位於不同的域,在物理位置上隔離,可減少數據丟失的可能性。
  • region: 更高級別的集合,理解爲地區,可對數據進行異地災備等。

1.2 邏輯模型

分佈式文件系統中,文件的存儲也會以集合的形式存儲,即文件目錄稱作分區,每個分區有唯一的ID即PartitionID。而邏輯模型定義的就是文件ID到PartitionID的映射關係,客戶端通過這個邏輯模型可以進行文件位置的第一步定位,找到文件目錄號。

 

1.3 邏輯模型到物理模型的映射

分佈式文件系統中,邏輯模型到物理模型的映射完成文件的第二步定位,找到文件的物理存儲位置。從邏輯模型到物理模型的映射如下表示,根據DocID查找其所屬的PartitionID,以存儲三副本爲例,每個Partition會同時存儲三份到不同的磁盤上,所以PartitionID到存儲磁盤的映射一對多的關係。

 

2. 模型的實現

梳理好分佈式文件系統的模型,然後對於有中心管理節點和無中心管理節點的系統對於模型的實現進行分別描述。

案例一 有中心管理節點

維護系統物理模型

對於有中心管理節點,最直接簡單的方式就是用數據庫實現物理模型,爲了提高中心節點的性能,減少數據庫的頻繁讀操作,常常會使用內存緩存模型及數據,由後臺線程定期維護內存模型數據和數據庫持久化數據保持一致。

創建region,zone,node和dev等表結構,通過id將其關聯起來,用於表示此物理模型。在系統初始化時模型建立後,引起模型狀態變化的操作主要有兩類,一種是人工運維操作,如增加、刪除dev或節點等常規操作;另外一種是自動運維,即監測節點或者磁盤的狀態,一旦發現節點異常,自動將其移出系統。所以中心管理節點需要實現以下功能:

管理工具模塊,給管理員提供模型中的變量region、zone、node及dev的增刪改操作,本質也就變成了數據庫的增刪改查的操作。

集羣狀態監測模塊,中心管理節點通過Zookeeper很容易實現此功能。在中心管理節點啓動時在Zookeeper目錄下創建MasterNode節點,DataNode管理一個磁盤設備,它在上線時會將自己註冊在子節點目錄下,MasterNode後臺線程監聽ZooKeeper目錄變化,獲取和更新當前集羣節點的狀態(上下線事件)和信息,保證系統模型狀態的正確性

圖3

維護系統邏輯模型

DocID到PartitionID的映射關係,如果都存於中心管理節點,那麼會導致中心管理節點佔用存儲量增大,且每次讀操作都需要查詢中心節點,性能消耗較大。所以分佈式文件系統的邏輯模型中的映射關係一般不會採用存儲查詢的方式,而是通過計算的方式實現。有個比較簡單直接的辦法就是將PartitionID信息包含在DocID中。在寫操作時,系統分配一個全局唯一DocID,DocID中包含該文件所存儲的Partition的信息,在讀操作時,可直接通過DocID獲取Partition的信息。這樣中心管理節點只需存儲Partition的信息,極大減少中心管理節點的存儲佔用量。

這裏需要提到的一點是邏輯模型中Partition何時創建的問題,對於中心管理節點的系統一般不會採用靜態的方式,即在系統初始化的時候就將所有Partition全部創建,而是在系統運行時根據系統當前的狀態採用動態異步創建的方式,會更加靈活可控,這樣做的好處時,Partition的數量可以隨着物理存儲磁盤的增加無限擴展增加,也減少了因爲物理模型的改變導致Partition數據會頻繁遷移。

維護邏輯模型到物理模型的映射

對於中心管理節點,解決邏輯模型到物理模型的映射關係很簡單,在Partition表中增加一個字段存儲三備份存儲的磁盤ID即可。但由於物理模型狀態會受到人工操作或者節點狀態變化而改變,所以中心管理節點需要維護邏輯模型到物理模型的映射關係動態變化,才能維護系統的高可靠和高可用特性。

中心管理節點在給Partition分配設備需要根據系統運行時物理模型當時的狀態,根據一定的策略和原則來進行分配:

  • 儘量將三個Partition副本放在不同的region、zone、node上,提高數據的可靠性
  • 根據dev設置的權重來選擇,一般根據Dev的容量權重來進行Partition副本的選擇,儘可能讓有存儲能力強的dev分配到更多的Partition

除了維護Partition到Dev的映射關係,中心管理節點還有個重要的作用就是選主,本質上就是解決模型中{dev1,dev2,dev3}的主從關係,當三備份中主節點dev1發生故障時,爲了保證數據的一致性,中心管理節點將該Partition變爲只讀,客戶端重試寫入Partition保證可用性。由於主從節點採用的是強一致性協議,所以中心管理節點選擇其中從節點作爲主即可。在後面的異常處理章節,對各種異常情況系統如何處理展開細述。

案例二 無中心管理節點

對於無中心管理節點來說,也需要有一個數據結構來存儲上述的模型關係,不同的是存儲的方式不是採用集中存儲的形式,而是集羣中的各個節點都需要保存這麼一個模型結構。下面也從以下幾點,以Swift爲例說明,其核心結構Ring實現了以上的模型定義及維護。

Ring實現了集羣管理的功能,但它承擔的責任遠不僅此,作爲Swift系統的靈魂,對數據定位以及部分數據複製等功能都起到了至關重要的作用。Ring的原理和實現對於學習分佈式文件系統的同學來說,還是值得深入瞭解的,所以下篇會根據代碼從多個維度分析Swift的Ring結構,本篇暫且只說到Ring在集羣管理功能上的實現。

維護系統邏輯模型

Swift的Ring在一開始管理員創建時,完成了集羣的邏輯模型的建立,如下管理員通過swift-ring-builder命令行工具,在Ring中創建了集羣需要的所有Partition,Partition的數量爲2的<part_power>次方個,備份爲3備份,Partition被連續移動兩次之間的最小時間間隔是<min_part_hour>。

swift-ring-builder <builder_file> create <part_power> <replicas><min_part_hours>

Swift的文件到PartitionID的映射關係採用的是計算的方式,計算文件名MD5的hash值,再取part_power位作爲PartitionID。對於Ring的Partition數量是固定的,在Ring的初始化時part_power決定了集羣可以有多少個partition,從而Swift集羣最終可以有多少個物理節點也受此限制。

維護系統物理模型

Swift的Ring結構中Ring._devs列表用於存儲系統所有存儲設備的的信息,每一個存儲設備包括如下的信息,這樣整個系統從region到dev的物理模型也就定義好了

===============================================================
id                 unique integer identifier amongst devices
index              offset into the primary node list for the partition
weight             a float of the relative weight of this device as compared to
                   others; this indicates how many partitions the builder will try
                   to assign to this device
region             -
zone               integer indicating which zone the device is in; a given
                   partition will not be assigned to multiple devices within the
                   same zone
ip                 the ip address of the device
port               the tcp port of the device
device             the device's name on disk (sdb1, for example)
meta               general use 'extra' field; for example: the online date, the
                   hardware description

replication_ip     -
replication_port   -
===============================================================

Swift提供了管理工具模塊swift-ring-builder,用於dev的增刪改操作,設置備份數量,修改dev的權重等常規運維操作,實質即修改了Ring中的_devs數組的元素。add或remove設備的操作都不會導致Partition到Dev的映射關係發生改變的,只是作用於_devs數據結構,只有在運行了rebalance操作後纔會進行Partition的重新分配。

 swift-ring-builder <builder_file> add
  --region <region> --zone <zone> --ip <ip or hostname> --port <port>
  --device <device_name> --weight <weight>

  swift-ring-builder <builder_file> remove
  --region <region> --zone <zone> --ip <ip or hostname> --port <port>

Swift沒有集羣狀態監測模塊,實時地去檢測並移除有問題的存儲節點,如果有節點出現故障,只能通過報警通知管理員,管理員通過swift-ring-builder去移除有問題的設備。由此可以看出Swift的物理模型只能一個入口導致其狀態變化。這樣的設計和實現有一定的優點,但同時帶來了另外一個問題,如果管理員沒有及時移除,那麼對於有問題的節點的讀寫操作,客戶端都會做多次重試才能保證數據的可靠性。

這裏可以多提一點的是,另外一個無中心管理節點的分佈式文件系統Ceph對此問題做了改進和優化,增加了Monitor節點用於存儲和更新存儲節點狀態信息,實現了集羣狀態監測和自動更新的功能。之前因爲這個點,將其歸類到了中心管理節點的分佈式文件系統,後經過熱心的網友提示,才仔細一想確實如此。Ceph對於整個數據定位的實現,從文件名到最終存儲設備的映射都是通過計算獲得,Monitor只是輕量級的維護了系統的節點信息,所以不能完全歸類於中心管理節點的分佈式文件系統的範疇。

維護邏輯模型到物理模型的映射

Ring中的_replica2part2dev結構定義了邏輯模型到物理模型的映射的關係,它是一個數組的數組,如下所示:

  • 3個array表示的是Ring構建的是一個三備份的存儲集羣
  • 每個array的index表示的是partition_id
  • 同一個index對應的元素則爲三個備份存儲的dev_id
                dev_id
                      |          
         |   +--------|-----------------------------+
         | 0 | array([1, 3, 1, 5, 5, 3, 2, 1,.....])
replica  | 1 | array([0, 2, 4, 2, 6, 4, 3, 4,.....])
         | 2 | array([2, 1, 6, 4, 7, 5, 6, 5,.....])
         |   +--------------------------------------+
              0 1 2 3 4 5 6 7.....................
             -------------------------------------->
             partition

_replica2part2dev結構只有在運行了swift-ring-builder rebalance命令後纔會生成數據或者改變。Ring的rebalance的過程本質就是根據Ring定義的物理模型和邏輯模型狀態變化重新計算和生成_replica2part2dev映射關係的過程,增/刪dev或修dev權重,更改備份數量等都會引起Ring的模型狀態發生變化,進而需要rebalance,重新計算和分配每個dev的Partition,生成新的Ring數據。然後管理員將其更新至集羣的所有節點,系統的不同進程服務會利用最新的Ring數據實現數據定位和數據遷移操作。

最後再回到文章開頭提到的圖,結合文章分析可以得出,不管是有中心管理節點還是無中心管理節點的分佈式文件存儲系統在對於集羣管理功能需要解決的問題是一致的,所以涉及到的系統模型定義也是大體相同的,在模型數據存儲的方式,以及邏輯模型到物理模型的映射關係的計算方式有一些區別。

以上,希望對分佈式文件存儲系統的理解有所幫助。篇幅有限,後續再分析swift的Ring的rebalance過程的細節。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章