1. 程式人生 > >基於partition的儲存模型-聊聊partition的方式

基於partition的儲存模型-聊聊partition的方式

本文主要聊一下開源主流產品的partition方式。

partition

一般來說,資料庫的繁忙體現在:不同使用者需要訪問資料集中的不同部分,這種情況下,我們把資料的各個部分存放在不同的伺服器/節點中,每個伺服器/節點負責自身資料的讀取與寫入操作,以此實現橫向擴充套件,這種技術成為分片,即sharding。

理想情況下,不同的節點服務於不同的使用者,每個使用者只需要與一個節點通訊,並且很快就能獲得伺服器的響應。當然理想情況比較罕見,為了獲得近乎理想的效果,必須保證需要同時訪問的那些資料都存放在同一個節點上,而且節點必須排布好這些資料塊,使得訪問速度最優。

分片可以極大地提高讀取效能,但對於要頻繁寫的應用,幫助不大。另外,分片對改善故障恢復能力並沒有幫助,但是它減少了故障範圍,只有訪問這個節點的那些使用者才會受影響,其餘使用者可以正常訪問。雖然資料缺失了一部分,但是還是其餘部分還是可以正常運轉。

問題點

1.怎樣分片/路由

怎樣存放資料,才能保證使用者基本上只需要從一個節點獲取它。如果使用的是面向聚合的資料庫而非面向元組的資料庫,那麼就非常容易解決了。之所以設計聚合這一結構,就是為了把那些經常需要同時訪問的資料存放在一起。因此,可以把聚合作為分佈資料的單元。

另外還要考慮的是:如何保持負載均衡。即如何把聚合資料均勻地分佈在各個節點中,讓它們需要處理的負載量相等。負載分佈情況可能隨著時間變化,因此需要一些領域特定的規則。比如有的需要按字典順序,有的需要按逆域名序列等。
很多NoSQL都提供自動分片(auto-sharding)功能,可以讓資料庫自己負責把資料分佈到各個分片,並且將資料訪問請求引導到適當的分片上。

2.怎樣rebalance

在動態增減機器或partition的情況下,如果重新rebalance,使資料分佈均勻或者避免熱點訪問

分片方式

這裡主要分為兩大類,一類是雜湊分片(hash based partitionning),一類是範圍分片(range based partitioning)

1.雜湊分片(hash based partitionning)

通過雜湊函式來進行資料分片,主要有Round Robbin、虛擬桶、一致性雜湊三種演算法。

A、Round Robbin
俗稱雜湊取模演算法,H(key) = hash(key) mode K(其中對物理機進行從0到K-1編號,key為某個記錄的主鍵,H(key)為儲存該資料的物理機編號)。好處是簡單,缺點是增減機器要重新hash,缺乏靈活性。它實際上是將物理機和資料分片兩個功能點合二為一了,因而缺乏靈活性。
B、虛擬桶
membase在待儲存記錄和物理機之間引入了虛擬桶,形成兩級對映。其中key-partition對映採用雜湊函式,partition-machine採用表格管理實現。新加入機器時,只需要將原來一些虛擬桶劃分給新的機器,只要修改partition-machine對映即可,具有靈活性。
C、一致性雜湊
一致性雜湊是分散式雜湊表的一種實現演算法,將雜湊數值空間按照大小組成一個首尾相接的環狀序列,對於每臺機器,可以根據IP和埠號經過雜湊函式對映到雜湊數值空間內。通過有向環順序查詢或路由表(Finger Table)來查詢。對於一致性雜湊可能造成的各個節點負載不均衡的情況,可以採用虛擬節點的方式來解決。一個物理機節點虛擬成若干虛擬節點,對映到環狀結構的不同位置。

雜湊分片的好處是可以使資料均勻分佈,但是可能造成資料無序不方便range

mongo2.4版本+支援hash partition

2.範圍分片(range based partitioning)

這個是根據key排序來分佈的,比如字典按24個首字母來分,這個的好處是方便range,但是容易造成資料分佈不均勻以及熱點訪問問題(比如個別節點的資料訪問量/查詢/計算量大,造成負載特別高)。

Bigtable,hbase、2.4版本之前的mongo都使用此方式。

索引分片策略(secondary indexes)

除了資料本身要分片外,索引也需要分片。比較著名的兩個反向索引分片策略就是document-based partitioning以及term-based partitioning。然後再此兩個基本的策略之上衍生出了hybrid的方案。

1.local index(document-based partitioning)

也稱作document-based partitioning.在每個partition本地維護一份關於本地資料的反向索引。這種方式的話,主要使用的是scatter/gather模式,即每次查詢需要傳送請求給所有的partition,然後每個partition根據本地的索引檢索返回,之後彙總得出結果。

  • 好處
    簡單好維護
  • 缺點
    查詢比較費勁,比如有n個partition,要查top k,則每個partition都要查top k,總共需要n*k份文件被彙總。

mongo,cassandra,es,solr採用此方案

2.global index(term-based partitioning)

也稱作term-based partitioning,這種方式的話,建立的索引不是基於partition的部分資料,而是基於所有資料來索引的。只不過這些全域性索引使用range-based partitioning的方式再分佈到各個節點上。

  • 好處
    讀取效率高,因為索引是有序的,基於range parititioning,非常快速找到索引,而且這些索引是全域性的,立馬就可以定位到文件的位置。
  • 缺點
    寫入成本比較高,每個文件的寫入都需要維護/更新全域性的索引。另外一個缺點就是range-partitioning本身的帶來的缺點,容易造成資料分佈不均勻,造成熱點,影響吞吐量。

dynamodb,riak支援此方案

rebalance

當partition所在節點壞掉,或者新增機器的時候,這個時候就涉及到partition的rebalance。原來本應該請求這個node的,現在都需要轉移請求另外一個node的過程叫做rebalancing。

rebalancing的目標

  • 均分資料儲存以及讀寫請求,避免熱點
  • rebalancing期間不影響正常讀寫
  • 要儘量快而且儘量少的網路及IO負載來完成

rebalance策略

直接雜湊(模數固定)

即key-machine的直接對映,這個的缺點就是:增減機器要重新hash,缺乏靈活性。

兩級對映(partition hashing,固定partition數目)

為了提升直接雜湊的靈活性,引入了兩級對映,即key-partition,partition-matchine/node這樣兩級,通過partition來解耦key跟machine/node的關聯。對於新加入機器時,只需要將原來各個node的一些partition劃分給新的機器,只要修改partition-machine對映即可,具有靈活性。

  • 好處
    相對於直接雜湊來講,節點增減的時候,只需要調整partiton-matchine的對映關係,客戶端無需重新路由。
  • 缺點
    固定partition的話,需要一個合理的數目,每個partition大小需要合理確定。相當於這些固定數目的partition要均分整個資料集。如果資料集不斷增長的話,如果原來partition個數太少,則每個partition大小則不斷增加,造成節點恢復/rebalance相對耗時。如果原來partition個數太多,而資料集後續增長不多,則可能造成有些partition的資料量過少,無法達到均分效果。

Elasticsearch採用此方案,在建立索引的時候需指定shard/partition數目以及replication的數目
Couchbase引入了vBucket的概念在這裡可以理解為虛擬的paritition。

 

動態partition

partition的數目是動態變化的,根據設定的partition大小的閾值,來進行動態的分裂或合併。

hbase採用的就是這種方式

一致性雜湊(hash ring)

一致性雜湊與前兩者有些不同,因為該演算法把machine/node也一起進行了hash,然後與key的雜湊值一起進行區間匹配,來確定key落在哪個machine/node上面。分散式快取用到的比較多,比如redis就是用了一致性雜湊。

具體如下:

  • 將環形空間總共分成2^32個區
  • 將key跟machine採用某種雜湊演算法轉化為一個32位的二進位制數,然後落到對應的區間範圍內
  • 每一個key的順時針方向最近節點,就是key所歸屬的儲存節點。
  • 好處
    節點增減的時候,整個環形空間的對映仍然會保持一致性雜湊的順時針規則,所以有一小部分key的歸屬會受到影響。當節點掛掉的時候,相當於快取未命中,下次訪問的時候重新快取。
  • 缺點
    使用一般的hash函式的話,machine的對映分佈非常不均勻,可能造成熱點,對於這種情況,引入虛擬節點來解決。也就是借鑑了兩級對映的模式,key-vnode,vnode-machine。將一個machine對映為多個vnode,然後分散到環形結構上,這樣可以使得vnode分佈均勻,然後最後每個machine的儲存也相對均勻

不過引入虛擬節點也會有問題,當新增machine的時候,也就相當於新增多個vnode分散到環上,但是這樣子就會造成更多的範圍的key需要rebalance。

1、提升單調性(通過環形演算法減少增減節點時cache的遷移成本) 2、提升平衡性(通過虛擬節點,儘可能減少節點增減帶來的cache分佈不均勻問題)

小結

產品 partition方式 索引分片策略
redis 一致性雜湊 -
elasticsearch 固定partition兩級對映 local index
mongo 2.4版本之前是範圍分片,2.4+支援hash分片 local index
kafka 固定partition -

kafka的key到partition的對映高版本支援自定義策略,如果cluster增減node,對之前建立的topic不生效,需要呼叫reassign-partitions重新分佈,避免熱點

doc

 

原文地址:https://segmentfault.com/a/1190000011704687