探索C 之虛擬桶分片

2021-07-24 05:55:48 字數 1575 閱讀 4038

閱讀目錄背景

虛擬桶(virtual buckets)

實現總結

關於資料分片討論最多的是一致性hash,然而它並不是分布式設計中的銀彈百試百靈。 在資料穩定性要求比較高的場景下它的缺點是不能容忍的。

比如在redis分布式快取設計中,使用一致性hash進行key分片儲存,通過虛擬節點最大化降低新增或刪除節點帶來的影響。這裡強調降低二字,即是它還是有影響的,在一般情況下我們還可以接受。

但是某些場景下要求動態擴容無影響就無法滿足了。

上次(探索c#之一致性hash詳解)提到過hash取模的分片演算法,是把資料mod後直接對映到真實節點上面,這造成節點個數和資料的緊密關聯、後期缺乏靈活擴充套件。

而一致性hash分片演算法多增加一層虛擬對映層,資料與虛擬節點對映、虛擬節點與真實節點再對映。

虛擬桶是取模和一致性hash二者的折中辦法。

其執行機制如下:

虛擬桶層採用預設固定數量,比如樓主在專案中預設n=1024。意味之後這個分布式集群最大擴容到1024個節點,帶來的好處就是mod後的值是不變的(非常重要),這保證了第一層對映挖寶去不受實際節點變化的影響。 關於最大數量,可根據實現需要預先定義好即可,比如redis官方的糟最大65000個節點,豌豆莢的codis預設也是1024個節點。 當然如果資料量超過1024節點儲存時,可以再起另外個集群應對。

舉個例子,專案剛開始使用時配置節點對映:

redis server1對應桶的編號為0到500。

redis server2對應桶的編號為500到1024。

快取資料量增長後需要增加新節點,在加之前需要重新分配節點對應虛擬桶的編號。 比如增加server3並配置對應桶的編號400到600,這時對於key對映虛擬桶層完全無影響。  實際上mod 400到600的真實資料還在另外兩台節點上,請求過來後還會發生無法命中的影響。 

這就要求在增加新節點前,需要在後台把另外二台的400到600編號資料拷貝到新節點上面,完成後再新增配置到對映上面。 因為新來請求會命中到新節點,所以另外2臺的400到600編號資料就無用了,需要進行刪除。這種做法就能最大限度(100%)的保證動態擴容後,對快取系統無影響。

演算法實現這塊比較簡單,資料遷移、配置等這塊需要單獨的系統來做。

private dictionaryredisgroups;

private

const

ulong slot = 1024;

public redisgroup getgroup(string

key)

public

ulong md5hash(string

key)

}

採取虛擬桶這種預分片的演算法,可以避免一致性hash擴容時引起的快取不命中。文中使用1024個例項作為最大節點數量,實際中是完全足夠用的。如果以後可能超過這個數量,可以部署另外一套1024節點的集群,最後形成乙個超大規模的redis集群。

關於redis的整套解決方案可以參考使用豌豆莢的codis。

分享了專案中一些使用經驗,希望對大家有所幫助。 

探索C 之虛擬桶分片

閱讀目錄 背景虛擬桶 virtual buckets 實現總結 關於資料分片討論最多的是一致性hash,然而它並不是分布式設計中的銀彈百試百靈。在資料穩定性要求比較高的場景下它的缺點是不能容忍的。比如在redis分布式快取設計中,使用一致性hash進行key分片儲存,通過虛擬節點最大化降低新增或刪除...

探索C 之虛擬桶分片

閱讀目錄 背景虛擬桶 virtual buckets 實現總結 關於資料分片討論最多的是一致性hash,然而它並不是分布式設計中的銀彈百試百靈。在資料穩定性要求比較高的場景下它的缺點是不能容忍的。比如在redis分布式快取設計中,使用一致性hash進行key分片儲存,通過虛擬節點最大化降低新增或刪除...

c語言排序之桶排序

桶排序 bucket sort 或所謂的 箱排序,是乙個 排序演算法 工作的原理是將陣列分到有限數量的桶子裡。每個桶子再個別排序 有可能再使用別的 排序演算法 或是以遞迴方式繼續使用桶排序進行排序 桶排序是 鴿巢排序 的一種歸納 結果。當要被排序的陣列內的數值是均勻分配的時候,桶排序使用線性時間 n...