本發(fā)明涉及計(jì)算機(jī)技術(shù)領(lǐng)域,更具體地,涉及一種基于一致性哈希算法進(jìn)行redis橫向擴(kuò)展的方法。
背景技術(shù):
目前,目前web應(yīng)用系統(tǒng)為了解決高并發(fā)帶來的性能問題,都會在web應(yīng)用系統(tǒng)與數(shù)據(jù)庫之間采取緩存層,使用最為廣泛的就是Redis(Redis本質(zhì)上是一個鍵-值類型的內(nèi)存數(shù)據(jù)庫)。Redis由于它的高性能和簡單的操作命令,完全可以作為軟件和傳統(tǒng)數(shù)據(jù)庫之間的緩沖作用,在保證了數(shù)據(jù)有效性的情況下,同時(shí)也保證了高性能。
Redis本身不提供分布式支持,所以在部署多臺Redis服務(wù)器時(shí),就需要解決如何把數(shù)據(jù)分散到各個服務(wù)器的問題,并且在服務(wù)器數(shù)量變化時(shí),能做到最大程度的不令數(shù)據(jù)重新分布。
通常使用的分布式方法是根據(jù)所要存儲數(shù)據(jù)的鍵的hash值與服務(wù)器數(shù)量N,按hash%N取模的算法來將數(shù)據(jù)分布到各個服務(wù)器。該算法的優(yōu)點(diǎn)是足夠簡單,而且數(shù)據(jù)分布均勻。但是一旦服務(wù)器數(shù)量N發(fā)生變化的時(shí)候,緩存命中率會瞬間跌入谷底,因?yàn)榻^大多數(shù)的數(shù)據(jù)需要重新分布。此時(shí)會有巨大的壓力涌向后端服務(wù),可能會導(dǎo)致性能故障和服務(wù)故障,甚至宕機(jī)。
因此,期望提供一種更有效地實(shí)現(xiàn)Redis橫向擴(kuò)展的方法。
技術(shù)實(shí)現(xiàn)要素:
本發(fā)明提供一種克服上述問題或者至少部分地解決上述問題的方法。
根據(jù)本發(fā)明的一個方面,提供了一種redis橫向擴(kuò)展的方法,包括以下步驟:步驟1,基于redis各服務(wù)器節(jié)點(diǎn)信息,利用哈希函數(shù),獲得所述redis服務(wù)器各節(jié)點(diǎn)的哈希值;將所述redis服務(wù)器各節(jié)點(diǎn)的哈希值分布在一個具有2^32個均勻排布點(diǎn)的圓環(huán)上;
步驟2,基于需要存儲數(shù)據(jù)的鍵信息,利用哈希函數(shù),獲得所述需要存儲數(shù)據(jù)各鍵的哈希值;將所述需要存儲數(shù)據(jù)各鍵的哈希值映射到所述圓環(huán)上;
步驟3,分別從需要存儲數(shù)據(jù)各鍵映射在所述圓環(huán)上的位置開始順時(shí)針查找分布在所述圓環(huán)上的服務(wù)器節(jié)點(diǎn),并將所述需要存儲數(shù)據(jù)保存在查找到的第一個服務(wù)器節(jié)點(diǎn)上。
本申請?zhí)岢隽艘环Nredis橫向擴(kuò)展的方法,利用一致性哈希函數(shù),將需要存儲的數(shù)據(jù)均勻的分散到各個服務(wù)器上,并且同時(shí)實(shí)現(xiàn)故障服務(wù)器節(jié)點(diǎn)數(shù)據(jù)快速轉(zhuǎn)移的技術(shù)效果。
附圖說明
圖1為根據(jù)本發(fā)明一種redis橫向擴(kuò)展的方法的總體流程示意圖;
圖2為根據(jù)本發(fā)明一種redis橫向擴(kuò)展的方法中哈希圓環(huán)的示意圖。
具體實(shí)施方式
下面結(jié)合附圖和實(shí)施例,對本發(fā)明的具體實(shí)施方式作進(jìn)一步詳細(xì)描述。以下實(shí)施例用于說明本發(fā)明,但不用來限制本發(fā)明的范圍。
如圖1,在本發(fā)明一個具體實(shí)施例中,示出一種redis橫向擴(kuò)展的方法整體流程示意圖。整體上,包括:步驟1,基于redis各服務(wù)器節(jié)點(diǎn)信息,利用哈希函數(shù),獲得所述redis服務(wù)器各節(jié)點(diǎn)的哈希值;將所述redis服務(wù)器各節(jié)點(diǎn)的哈希值分布在一個具有2^32個均勻排布點(diǎn)的圓環(huán)上;步驟2,基于需要存儲數(shù)據(jù)的鍵信息,利用哈希函數(shù),獲得所述需要存儲數(shù)據(jù)各鍵的哈希值;將所述需要存儲數(shù)據(jù)各鍵的哈希值映射到所述圓環(huán)上;步驟3,分別從需要存儲數(shù)據(jù)各鍵映射在所述圓環(huán)上的位置開始順時(shí)針查找分布在所述圓環(huán)上的服務(wù)器節(jié)點(diǎn),并將所述需要存儲數(shù)據(jù)保存在查找到的第一個服務(wù)器節(jié)點(diǎn)上。
本發(fā)明另一個具體實(shí)施例中,一種redis橫向擴(kuò)展的方法,由于哈希(hash)算法結(jié)果一般為unsigned int型,因此對于hash函數(shù)的結(jié)果應(yīng)該均勻分布在[0,2^32-1]區(qū)間,如果我們把一個圓環(huán)用2^32個點(diǎn)來進(jìn)行均勻切割,首先按照hash(key)函數(shù)算出服務(wù)器節(jié)點(diǎn)的哈希值,并將其分布到0~2^32的圓環(huán)上。
用同樣的hash(key)函數(shù)求出需要存儲數(shù)據(jù)的鍵的哈希值,并映射到圓環(huán)上。然后從數(shù)據(jù)映射到的位置開始順時(shí)針查找,將數(shù)據(jù)保存到找到的第一個服務(wù)器(節(jié)點(diǎn))上。如圖2所示,key1、key2、key3和server1、server2通過hash都能在這個圓環(huán)上找到自己的位置,并且通過順時(shí)針的方式來將key定位到server。按上圖來說,key1和key2存儲到server1,而key3存儲到server2。如果新增一臺server,hash后在key1和key2之間,則只會影響key1(key1將會存儲在新增的server上),其它則不變。
本發(fā)明另一個具體實(shí)施例中,一種redis橫向擴(kuò)展的方法,所述步驟1還包括:基于redis服務(wù)器各節(jié)點(diǎn)設(shè)定至少一個虛擬服務(wù)器節(jié)點(diǎn),利用哈希函數(shù),獲得所述各虛擬服務(wù)器節(jié)點(diǎn)的哈希值;將所述各虛擬服務(wù)器節(jié)點(diǎn)的哈希值分布在所述具有2^32個均勻排布點(diǎn)的圓環(huán)上。
本發(fā)明另一個具體實(shí)施例中,一種redis橫向擴(kuò)展的方法,在圖2中,很容易看出一個問題,沿順時(shí)針方向看,server2到server1之間的區(qū)間跨度大,而server1到server2的區(qū)間跨度小,這就會導(dǎo)致一個問題:數(shù)據(jù)分布不均勻。大部分?jǐn)?shù)據(jù)都分配到server1了,只有小部分?jǐn)?shù)據(jù)分布在server2。在服務(wù)器數(shù)據(jù)很少的時(shí)候,數(shù)據(jù)不均勻會表現(xiàn)的非常明顯。解決這個問題的方法是使用虛擬節(jié)點(diǎn),一個真實(shí)服務(wù)器對應(yīng)多個虛擬節(jié)點(diǎn),所有虛擬節(jié)點(diǎn)按hash值分布在一致性哈希圓環(huán)上。
本發(fā)明另一個具體實(shí)施例中,一種redis橫向擴(kuò)展的方法,所述步驟3后還包括:當(dāng)某個或者多個服務(wù)器節(jié)點(diǎn)出現(xiàn)故障時(shí),將所述故障服務(wù)器上的數(shù)據(jù)存放到其他正常工作的服務(wù)器上。
本發(fā)明另一個具體實(shí)施例中,一種redis橫向擴(kuò)展的方法,所述步驟1中基于redis服務(wù)器各節(jié)點(diǎn)設(shè)定至少一個虛擬服務(wù)器節(jié)點(diǎn)還包括:為真實(shí)redis服務(wù)器設(shè)置虛擬服務(wù)器節(jié)點(diǎn)數(shù)量,然后根據(jù)各redis真實(shí)服務(wù)器IP和端口號再加上一個遞增的索引數(shù)計(jì)算hash值。
本發(fā)明另一個具體實(shí)施例中,一種redis橫向擴(kuò)展的方法,所述虛擬服務(wù)器節(jié)點(diǎn)數(shù)量可以按真實(shí)服務(wù)器的數(shù)量調(diào)節(jié),真實(shí)服務(wù)器多則副本數(shù)量可以設(shè)置少一點(diǎn),真實(shí)服務(wù)器少則副本數(shù)量需要設(shè)置多一點(diǎn)。
本發(fā)明另一個具體實(shí)施例中,一種redis橫向擴(kuò)展的方法,在虛擬服務(wù)器節(jié)點(diǎn)數(shù)量很大時(shí),利用二分法查找需要存儲數(shù)據(jù)各鍵對應(yīng)的虛擬節(jié)點(diǎn)。一個優(yōu)化的算法是不論副本數(shù)量設(shè)置為10、100還是10000的時(shí)候,對查找所需要的時(shí)間基本是沒有影響的。
本發(fā)明另一個具體實(shí)施例中,一種redis橫向擴(kuò)展的方法,所述步驟當(dāng)某個或者多個服務(wù)器節(jié)點(diǎn)出現(xiàn)故障時(shí),將所述故障服務(wù)器上的數(shù)據(jù)存放到其他正常工作的服務(wù)器上還包括:檢測故障真實(shí)服務(wù)器并記錄,在一次性哈希圓環(huán)上沿順時(shí)針方向順移一步,并判斷是不是所述被記錄的故障真實(shí)服務(wù)器;如果是,則直接查找下一個虛擬節(jié)點(diǎn),直到找到可用的服務(wù)器將數(shù)據(jù)存儲上去。
本發(fā)明另一個具體實(shí)施例中,一種redis橫向擴(kuò)展的方法,根據(jù)key查找到的虛擬節(jié)點(diǎn)所對應(yīng)的真實(shí)服務(wù)器故障的時(shí)候,在一次性哈希圓環(huán)上沿順時(shí)針方向順移一步,找到下一點(diǎn)虛擬節(jié)點(diǎn)對應(yīng)的真實(shí)服務(wù)器,將所要存儲的數(shù)據(jù)存放上去。很有可能下一個虛擬節(jié)點(diǎn)所對應(yīng)的真實(shí)服務(wù)器與前一個虛擬節(jié)點(diǎn)相同,還是那臺故障的服務(wù)器,而每次嘗試連接故障的redis服務(wù)是一個很大的性能開銷。所以在第一次檢測到故障服務(wù)器的時(shí)候就需要記錄下來,然后在順移到下一個虛擬節(jié)點(diǎn)的時(shí)候先判斷是不是之前那一臺故障的服務(wù)器,如果是那就不要再嘗試進(jìn)行連接,直接查找下一個虛擬節(jié)點(diǎn),直到找到可用的服務(wù)器將數(shù)據(jù)存儲上去。
最后,本申請的方法僅為較佳的實(shí)施方案,并非用于限定本發(fā)明的保護(hù)范圍。凡在本發(fā)明的精神和原則之內(nèi),所作的任何修改、等同替換、改進(jìn)等,均應(yīng)包含在本發(fā)明的保護(hù)范圍之內(nèi)。