Redis集群:redis cluster方案
redis集群原理之官方的Redis Cluster方案
redis是單線程,但是一般的作為緩存使用的話,redis足夠了,因為它的讀寫速度太快了。
??官方的一個簡單測試:
測試完成了50個并發(fā)執(zhí)行100000個請求。
設(shè)置和獲取的值是一個256字節(jié)字符串。結(jié)果:讀的速度是110000次/s,寫的速度是81000次/s?
在這么快的讀寫速度下,對于一般程序來說足夠用了,但是對于訪問量特別大的網(wǎng)站來說,還是稍有不足。那么,如何提升redis的性能呢?看標(biāo)題就知道了,搭建集群。
3.0版本之前
3.0版本之前的redis是不支持集群的,那個時候,我們的redis如果想要集群的話,就需要一個中間件,然后這個中間件負(fù)責(zé)將我們需要存入redis中的數(shù)據(jù)的key通過一套算法計算得出一個值。然后根據(jù)這個值找到對應(yīng)的redis節(jié)點,將這些數(shù)據(jù)存在這個redis的節(jié)點中。
在取值的時候,同樣先將key進(jìn)行計算,得到對應(yīng)的值,然后就去找對應(yīng)的redis節(jié)點,從對應(yīng)的節(jié)點中取出對應(yīng)的值。
這樣做有很多不好的地方,比如說我們的這些計算都需要在系統(tǒng)中去進(jìn)行,所以會增加系統(tǒng)的負(fù)擔(dān)。還有就是這種集群模式下,某個節(jié)點掛掉,其他的節(jié)點無法知道。而且也不容易對每個節(jié)點進(jìn)行負(fù)載均衡。
?3.0之前也就是客戶端(tomcat)自己進(jìn)行計算hash 或者使用中間件,然后去指定的redis節(jié)點進(jìn)行存取
3.0版本及以后
先來一張redis集群的架構(gòu)圖:
?
在這個圖中,每一個藍(lán)色的圈都代表著一個redis的服務(wù)器節(jié)點。它們?nèi)魏蝺蓚€節(jié)點之間都是相互連通的。客戶端可以與任何一個節(jié)點相連接,然后就可以訪問集群中的任何一個節(jié)點。對其進(jìn)行存取和其他操作。(重定向操作)
那么redis是怎么做到的呢?首先,在redis的每一個節(jié)點上,都有這么兩個東西,一個是插槽(slot)可以理解為是一個可以存儲兩個數(shù)值的一個變量,這個變量的取值范圍是:0-16383(0-1000,5005-10000,12000-16000都可以)。還有一個就是cluster我個人把這個cluster理解為是一個集群管理的插件。當(dāng)我們的存取的key到達(dá)的時候,redis會根據(jù)crc16的算法得出一個結(jié)果,然后把結(jié)果對?16384 求余數(shù),這樣每個?key 都會對應(yīng)一個編號在?0-16383 之間的哈希槽,通過這個值,去找到對應(yīng)的插槽所對應(yīng)的節(jié)點,然后直接自動跳轉(zhuǎn)到這個對應(yīng)的節(jié)點上進(jìn)行存取操作。(如下圖:26384%16384為10000,然后查找有10000的節(jié)點直接跳轉(zhuǎn))
?
還有就是因為如果集群的話,是有好多個redis一起工作的,那么,就需要這個集群不是那么容易掛掉,所以呢,理論上就應(yīng)該給集群中的每個節(jié)點至少一個備用的redis服務(wù)。這個備用的redis稱為從節(jié)點(slave)。
那么這個集群是如何判斷是否有某個節(jié)點掛掉了呢?
首先要說的是,每一個節(jié)點都存有這個集群所有主節(jié)點以及從節(jié)點的信息。
它們之間通過互相的ping-pong判斷是否節(jié)點可以連接上。如果有一半以上的節(jié)點去ping一個節(jié)點的時候沒有回應(yīng),集群就認(rèn)為這個節(jié)點宕機了,然后去連接它的備用節(jié)點。如果某個節(jié)點和所有從節(jié)點全部掛掉,我們集群就進(jìn)入faill狀態(tài)。還有就是如果有一半以上的主節(jié)點宕機,那么我們集群同樣進(jìn)入發(fā)力了狀態(tài)。這就是我們的redis的投票機制,具體原理如下圖所示:
?
?
(1)投票過程是集群中所有master參與,如果半數(shù)以上master節(jié)點與master節(jié)點通信超時(cluster-node-timeout),認(rèn)為當(dāng)前master節(jié)點掛掉.
(2):什么時候整個集群不可用(cluster_state:fail)??
? ? a:如果集群任意master掛掉,且當(dāng)前master沒有slave.集群進(jìn)入fail狀態(tài),也可以理解成集群的slot映射[0-16383]不完整時進(jìn)入fail狀態(tài). ps : redis-3.0.0.rc1加入cluster-require-full-coverage參數(shù),默認(rèn)關(guān)閉,打開集群兼容部分失敗.
? ? b:如果集群超過半數(shù)以上master掛掉,無論是否有slave,集群進(jìn)入fail狀態(tài).
?
2、Redis Cluster主從模式(HA方案)
? ? ? ? ? redis cluster 為了保證數(shù)據(jù)的高可用性,加入了主從模式,一個主節(jié)點對應(yīng)一個或多個從節(jié)點,主節(jié)點提供數(shù)據(jù)存取,從節(jié)點則是從主節(jié)點拉取數(shù)據(jù)備份,當(dāng)這個主節(jié)點掛掉后,就會有這個從節(jié)點選取一個來充當(dāng)主節(jié)點,從而保證集群不會掛掉。
? ? ? 上面那個例子里, 集群有ABC三個主節(jié)點, 如果這3個節(jié)點都沒有加入從節(jié)點,如果B掛掉了,我們就無法訪問整個集群了。A和C的slot也無法訪問。
? ? ?所以我們在集群建立的時候,一定要為每個主節(jié)點都添加了從節(jié)點, 比如像這樣, 集群包含主節(jié)點A、B、C, 以及從節(jié)點A1、B1、C1, 那么即使B掛掉系統(tǒng)也可以繼續(xù)正確工作。
? ? ?B1節(jié)點替代了B節(jié)點,所以Redis集群將會選擇B1節(jié)點作為新的主節(jié)點,集群將會繼續(xù)正確地提供服務(wù)。當(dāng)B重新開啟后,它就會變成B1的從節(jié)點。
? ? 不過需要注意,如果節(jié)點B和B1同時掛了,Redis集群就無法繼續(xù)正確地提供服務(wù)了。
Redis Cluster特性
·????????高性能
·????????支持動態(tài)擴容,對業(yè)務(wù)透明
·????????具備Sentinel的監(jiān)控和自動Failover能力(Cluster架構(gòu)中無Proxy層)
Redis Cluster方式:
Redis 集群中內(nèi)置了 16384 個哈希槽,當(dāng)需要在 Redis 集群中放置一個 key-value時,redis 先對 key 使用 crc16 算法算出一個結(jié)果,然后把結(jié)果對 16384 求余數(shù),這樣每個 key 都會對應(yīng)一個編號在 0-16383 之間的哈希槽,redis會根據(jù)節(jié)點數(shù)量大
致均等的將哈希槽映射到不同的節(jié)點。
Redis 集群沒有使用一致性hash, 而是引入了哈希槽(Slot)的概念。
Redis 集群有16384個哈希槽,每個key通過CRC16校驗后對16384取模來決定放置哪個槽.集群的每個節(jié)點負(fù)責(zé)一部分hash槽。這種結(jié)構(gòu)很容易添加或者刪除節(jié)點,并且無論是添加刪除或者修改某一個節(jié)點,都不會造成集群不可用的狀態(tài)。
使用哈希槽的好處就在于可以方便的添加或移除節(jié)點。
當(dāng)需要增加節(jié)點時,只需要把其他節(jié)點的某些哈希槽挪到新節(jié)點就可以了;
當(dāng)需要移除節(jié)點時,只需要把移除節(jié)點上的哈希槽挪到其他節(jié)點就行了;
在這一點上,我們以后新增或移除節(jié)點的時候不用先停掉所有的 redis 服務(wù)。
?
總結(jié)
以上是生活随笔為你收集整理的Redis集群:redis cluster方案的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Redis集群:哨兵(Sentinel)
- 下一篇: Redis集群:一致性哈希