大數據日知錄--數據分片與路由

  1. 概念
        目前主流的大數據存儲與計算系統通常採用橫向擴展(Scale Out)的方式支持系統可擴展性,即通過增加機器數目來獲得水平擴展能力。對於待存儲處理的海量數據,需要通過數據分片(Shard/partition)來將數據進行切分並分配到各個機器中去,數據分片後如何找到某條記錄的存儲位置就成爲必然要解決的問題,這一般被稱爲數據路由(Data Routing)。數據分片和數據路由的抽象模型如下圖所示:

    這裏寫圖片描述

  2. 哈希分片(Hash Partition)
    最爲常見的3種哈希分片方式分別爲:Round Robin、虛擬桶和一致性哈希方法。

    • Round Robin
          Round Robin就是常用的哈希取模法,利用哈希函數將數據映射到編號從0到k-1的物理機上。
      H(key)=hash(key) mod K

      這種分片方式的優點是實現簡單,缺點是缺乏靈活性,無法進行橫向擴展。
    • 虛擬桶(Virtual Buckets)
          虛擬桶機制將所有記錄首先通過哈希函數映射到虛擬桶,記錄和虛擬桶是多對一的關係,第二層映射是虛擬桶和物理機之間的映射,也是多對一的關係,其具體實現方式是通過查表來實現的,以Membase爲例,虛擬桶運行機制如下圖所示:
      這裏寫圖片描述
    • 一致性哈希(Consistent Hashing)
          一致性哈希算法被廣泛的應用於分佈式系統架構中,一致性哈希算法將哈希數值空間按照大小組成一個首尾相接的環狀序列。對於不同物理機根據其IP和端口號經過哈希函數映射到哈希空間內,這樣不同的機器就構成了環狀序列中的不同節點,而每個節點負責存儲落在一段有序哈希空間中的數據。如下圖是一個哈希空間爲32(m=5,2^5=32)的一致性哈希算法示意圖,例如N14節點就存儲6 < Hash(key) < 14的數據。同時,每個節點記錄環中的前趨節點和後繼節點地址位置,使之成爲一個真正的有向環。
      這裏寫圖片描述

(1)路由問題
    通過以上方式就可以將海量數據分不到集羣中的不同節點中,實現數據分片功能。那麼如何根據key和哈希函數H來定位到記錄內容呢?
    一種直觀的解決辦法就是沿着有向環順序查找,如果H(key)在本節點管理範圍內就返回結果,如果不在則將其交給後繼節點繼續查找,這樣最多遍歷所有節點就可以給出結果。
    很明顯以上方法是一個低效的查找方式,爲例加快查找速度,可以爲每個節點配置路由表。路由表存儲m條路由信息(m爲哈希空間的二進制數值比特位長度,即哈希空間長度=2^m),其中第i項存儲距離當前節點距離爲2^i的數據節點。如N14的節點路由表如下所示:

距離 1(2^0) 2(2^1) 4(2^2) 8(2^3) 16(2^4)
機器節點 N20 N20 N20 N25 N5


算法:假設當前執行操作的節點爲Nc,其初始值爲Ni,Nc的後繼節點爲Ns,重複執行下列步驟。
步驟1,判斷是否c < j <= s,如果爲真,則結束查找,說明key如果存在,則在Nc的後繼節點Ns上,Ns返回結果。
步驟2,否則,Nc查找路由表,找到小於j的最大編號節點Nh(如果所有路由項都大於j,則選擇第m-1項作爲Nh),Nc向Nh發送消息,由Nh代爲查找,Nh此時作爲新的Nc繼續按照步驟1,步驟2遞歸進行查找。
此算法的時間複雜度爲O(logn),類似於二分查找。

下圖爲N14節點接收到H(key)=27時的查找過程:

這裏寫圖片描述

(2)加入新節點
    如果P2P網絡加入一個新節點Nnew,首先Nnew能夠和任意節點Nx進行通信,通過Nx按照“路由算法”查詢Nnew的對應哈希值H(Nnew)=new,找到Nnew的後繼節點Ns,假設Ns的前趨節點爲Np,那麼需要做兩件事將Nnew加入網絡:
一. 改變Np、Nnew和Ns的前趨後繼節點記錄,以體現新的網絡架構。
二. 數據的重新分片與分佈,將Ns節點中存儲的應該由Nnew承載的數據(Ns節點上哈希值小於等於new的記錄)遷移到Nnew節點上。
    在非併發環境中以上事務較易完成,但是在併發環境中,可能Np和Ns之間同時有多個節點加入,爲了避免出現問題,需按照以下兩個步驟完成:
一. 將Nnew的後繼節點設置爲null。
二. 這一步並非爲新加入節點設立的,而是所有節點週期性自動完成,穩定性檢測。

  • 穩定性檢測

算法:
步驟1,假設Ns爲Nc的後繼節點,Nc向Ns詢問其前趨節點Np,Ns向Ns答覆,一般情況下,如果Np=Nc則轉入第4步。
步驟2,如果Np介於Nc和Ns之間,Nc記錄下Np爲其後繼節點。
步驟3,令Nx是Nc的後繼節點,其可能是Ns或者Np,這取決於步驟2的判斷結果。如果Nx的前趨節點爲空或者Nc位於Nx和它的前趨節點之間,那麼Nc給Nx發消息告訴Nx,Nc就是Nx的前趨節點,Nx將其前趨節點設置爲Nc。
步驟4,Nx將其部分數據遷移到Nc上,即將Nx上哈希值小於等於c的記錄遷移到Nc上。

示例,將N8加入上述網絡
1.根據步驟一,將N8的後繼節點設爲N14,前趨節點置爲null,如下圖所示:

這裏寫圖片描述

2.N8進行穩定性檢測,步驟1中,N8發現N14的前趨節點不是自己,進入步驟2,由於N5沒有介於N8和N14之間,所以直接進入步驟3,因爲N8位於N5和N14之間,所以N8向N14發消息,告知N14的前趨節點改爲N8,N14的前趨指向N8,如下圖所示:
這裏寫圖片描述

3.進入步驟4,N14將部分數據遷移到N8。

一段時間後,N5開始進行穩定性檢測,經過步驟N5被告知,N14的前趨節點是N8而不是自己,所以進入步驟2,由於N8介於N5和N14之間,所以N5將後繼節點改爲N8,如下圖所示:

這裏寫圖片描述

進入步驟3,由於N8的前趨節點爲空,所以N5通知N8其前趨節點爲N5,所以N8將前趨節點置爲N5,如下圖所示:
這裏寫圖片描述

進入步驟4,N8沒有需要向N5遷移的數據,結束。
這樣,N8節點就順利的加入了網絡。

(3)當前節點離開網絡
    當前節點離開網絡有兩種方式:正常離開和異常離開。正常離開的節點在離開前可以做些準備工作,包括通知相應節點修改前趨後繼以及將持有數據遷移到相應機器上。異常離開通常是由於機器故障導致,爲避免數據丟失,可以採用將數據備份的方式解決。
關於路由表失效問題,可以通過對每個節點定期檢查路由表的方式解決。
(4)虛擬節點
    上述一致性哈希算法存在兩個問題,一個是數據映射是隨機的,可能導致集羣的負載不均衡,另一個是集羣中的節點存在性能上的差異,可能會導致低性能節點高負載的情況,而且新節點加入時只能緩解其後繼一個節點的容量飽和問題,不能有效的緩解集羣中其他節點的容量飽和問題。針對以上問題,引入“虛擬節點”的概念,即將一臺物理機器虛擬成若干個虛擬節點,分別映射到一致性哈希環的不同位置。這樣就解決了上述問題。

3 . 範圍分片(Range Partition)
    範圍分片首先將所有記錄主鍵進行排序,然後在排好序的主鍵空間裏將記錄劃分成數據分片,每個數據分片存儲有序的主鍵空間片段內的所有記錄。保持一個數據分片的映射表,表中每一項記在數據分片的最小主鍵及其對應的物理機地址,在對記錄進行增刪改時,查找映射表找到其對應的物理機,置於分片數據在物理機的管理方式往往採用LSM樹(Log Structured Merge Trees),這是一種高效的數據索引結構。範圍分片的模型如下圖所示:

這裏寫圖片描述

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