????本文主要會圍繞,redis分布式算法的原理以及環(huán)境配置搭建票髓,和服務(wù)端客戶端啟動。我們會封裝一個分布式Shard Redis API铣耘,最后驗證一下Redis分布式環(huán)境驗證洽沟。另外會解釋一下,集群和分布式的概念蜗细。 ? (參考慕課geely課程:
來一波地址:https://coding.imooc.com/learn/list/162.html)?
? ? 一裆操、分布式算法原理
? ? 1.1傳統(tǒng)的分布式算法.
? ??原始的做法是對緩存項的鍵進行哈希,將hash后的結(jié)果對緩存服務(wù)器的數(shù)量進行取模操作炉媒,通過取模后的結(jié)果踪区,決定緩存項將會緩存在哪一臺服務(wù)器上。例如一個圖片選擇存哪臺服務(wù)器的一個過程吊骤,
? ? 這樣Hash取模的方式是有弊端的缎岗,就是在我們業(yè)務(wù)擴展的時候,新增服務(wù)器節(jié)點白粉,會導(dǎo)致一部分數(shù)據(jù)不能準確的在緩存服務(wù)器中找到传泊。換句話說鼠渺,當服務(wù)器數(shù)量發(fā)生變化的時候,所有緩存在一點時間內(nèi)是失效的眷细,當應(yīng)用無法從緩存中獲取數(shù)據(jù)時拦盹,則會向后端服務(wù)器請求數(shù)據(jù),造成了緩存的雪崩薪鹦,整個系統(tǒng)很有可能被壓垮掌敬,所以,我們應(yīng)該想辦法不讓這種糟糕的情況出現(xiàn)池磁,但是由于Hash算法本身的緣故奔害,使用取模法進行緩存時,這種情況是無法避免的地熄,為了解決這些問題而出現(xiàn)一致性哈希算法誕生华临。
????1.2Consistent hashing一致性算法原理
? ? 這和算法有一個環(huán)形hash空間的概念,通常hash算法都是將value映射在一個32位的key值當中端考,那么把數(shù)據(jù)首尾相接就會形成一個圓形雅潭,取值范圍為0 ~ 2^32-1,這個圓環(huán)就是環(huán)形hash空間却特。
我們來看如何把對象映射到環(huán)形hash空間:
? ? *只考慮4個對象Object1~Object4
? ? *首先通過hash函數(shù)計算出這四個對象的hash值key扶供,這些對象的hash值肯定是會落在上述中的環(huán)形hash空間范圍上的,對象的hash對應(yīng)的環(huán)形hash空間上的哪一個key值那么該對象就會映射到那個位置上裂明,這樣對象就映射到hash空間上
????然后就是把cache映射到環(huán)形hash空間椿浓,cache就是我們redis服務(wù)器,采用跟對象一樣的hash算法闽晦。
????可以看到扳碍,Cache和Obejct都映射到這個環(huán)形hash空間中了,那么接下來要考慮的就是如何將object映射到cache中仙蛉。其實在這個環(huán)形hash空間進行一個順時針的計算即可笋敞,例如key1順時針遇到的第一個cache是cacheA,所以就將key1映射到cacheA中荠瘪,key2順時針遇到的第一個cache是cacheC夯巷,那么就將key2映射到cacheC中,以此類推哀墓。
????如果某一個cache被移除之后鞭莽,那么object會繼續(xù)順時針尋找下一個cache進行映射。例如麸祷,cacheB被移除了澎怒,映射在cacheB中的object4就會順時針往下找到cacheC,然后映射到cacheC上。
????所以當移除一個cacheB時所影響的object范圍就是cacheB與cacheA之間的那一段范圍喷面,這個范圍是比較小的星瘾。如下圖所標出的范圍:
????而當增加一個cache節(jié)點時也是同理琳状,例如,在acheC和cacheB之間增加了一個cacheD節(jié)點盒齿,那么object2在順時針遇到的第一個cache就是cacheD念逞,此時就會將obejct2映射到cacheD中。如下圖:
????同樣的边翁,增加cache節(jié)點所影響的范圍也就是cacheD和cacheB之間的那一段范圍翎承。如下圖所標出的范圍:
1.3Hash傾斜性
? ? 上面一致性hash算法分析的都很美好,我們假設(shè)了所有的cache節(jié)點都在環(huán)形hash空間上均勻分布符匾,但是很有可能會出現(xiàn)cache節(jié)點無法均勻分布在環(huán)形hash空間上叨咖。
????可以看到,A啊胶、B甸各、C節(jié)點都擠在了一塊,按順時針來計算焰坪,就會有大量的數(shù)據(jù)(object)映射到A節(jié)點上趣倾,從上圖中來看就會有一大半的數(shù)據(jù)都映射到A節(jié)點上,那么A節(jié)點所承載的數(shù)據(jù)壓力會十分大某饰,B儒恋、C節(jié)點則無法得到很好的利用,幾乎等同閑著沒事干露乏。這就是Hash傾斜性所導(dǎo)致的現(xiàn)象碧浊,無法保證在環(huán)形hash空間上絕對的分布均勻涂邀。
? ? 1.4虛擬節(jié)點
? ??為了解決Hash傾斜性的問題瘟仿,redis引入了虛擬節(jié)點的概念,虛擬節(jié)點相當于是實際節(jié)點的一個影子或者說分身比勉,而且虛擬節(jié)點一般都比實際節(jié)點的數(shù)量要多(可能一下多好幾百倍劳较,這個hash的環(huán)上都是密密麻麻的虛擬節(jié)點【默認的一個實際redis節(jié)點有160個虛擬節(jié)點,如果給redis實際節(jié)點配置了權(quán)重的話(默認權(quán)重是1)浩聋,那虛擬節(jié)點的個數(shù)就是權(quán)重*160】)观蜗。引入虛擬節(jié)點后,object不再直接映射到實際的cache節(jié)點中衣洁,而是先映射到虛擬節(jié)點中墓捻。然后虛擬節(jié)點會再進行一個hash計算,最后才映射到實際的cache節(jié)點中坊夫。所以虛擬節(jié)點就是對我們的實際節(jié)點進行一個放大砖第,如下圖:
? ? 先把對象hash到虛擬節(jié)點上,在將虛擬節(jié)點重新hash到真是的redis節(jié)點上梧兼。如下圖所示:
? ? 1.5Consistent hashing命中率
? ? 命中率=(1 - n /(n+m))*100%(注釋: ? ? n = 現(xiàn)有的節(jié)點數(shù)量放吩;m = 新增的節(jié)點數(shù)量)