閱讀目錄背景
虛擬桶(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;採取虛擬桶這種預分片的演算法,可以避免一致性hash擴容時引起的快取不命中。文中使用1024個例項作為最大節點數量,實際中是完全足夠用的。如果以後可能超過這個數量,可以部署另外一套1024節點的集群,最後形成乙個超大規模的redis集群。private
const
ulong slot = 1024;
public redisgroup getgroup(string
key)
public
ulong md5hash(string
key)
}
關於redis的整套解決方案可以參考使用豌豆莢的codis。
分享了專案中一些使用經驗,希望對大家有所幫助。
探索C 之虛擬桶分片
閱讀目錄 背景虛擬桶 virtual buckets 實現總結 關於資料分片討論最多的是一致性hash,然而它並不是分布式設計中的銀彈百試百靈。在資料穩定性要求比較高的場景下它的缺點是不能容忍的。比如在redis分布式快取設計中,使用一致性hash進行key分片儲存,通過虛擬節點最大化降低新增或刪除...
探索C 之虛擬桶分片
閱讀目錄 背景虛擬桶 virtual buckets 實現總結 關於資料分片討論最多的是一致性hash,然而它並不是分布式設計中的銀彈百試百靈。在資料穩定性要求比較高的場景下它的缺點是不能容忍的。比如在redis分布式快取設計中,使用一致性hash進行key分片儲存,通過虛擬節點最大化降低新增或刪除...
c語言排序之桶排序
桶排序 bucket sort 或所謂的 箱排序,是乙個 排序演算法 工作的原理是將陣列分到有限數量的桶子裡。每個桶子再個別排序 有可能再使用別的 排序演算法 或是以遞迴方式繼續使用桶排序進行排序 桶排序是 鴿巢排序 的一種歸納 結果。當要被排序的陣列內的數值是均勻分配的時候,桶排序使用線性時間 n...