本文為分布式redis深度歷險系列的第三篇,主要內(nèi)容為Redis的Cluster,也就是Redis集群功能。
為天河等地區(qū)用戶提供了全套網(wǎng)頁設計制作服務,及天河網(wǎng)站建設行業(yè)解決方案。主營業(yè)務為成都網(wǎng)站制作、做網(wǎng)站、外貿(mào)營銷網(wǎng)站建設、天河網(wǎng)站設計,以傳統(tǒng)方式定制建設網(wǎng)站,并提供域名空間備案等一條龍服務,秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務。我們深信只要達到每一位用戶的要求,就會得到認可,從而選擇與我們長期合作。這樣,我們也可以走得更遠!
Redis集群是Redis官方提供的分布式方案,整個集群通過將所有數(shù)據(jù)分成16384個槽來進行數(shù)據(jù)共享。
一個集群由多個Redis節(jié)點組成,不同的節(jié)點通過CLUSTER MEET
命令進行連接:
CLUSTER MEET <ip> <port>
收到命令的節(jié)點會與命令中指定的目標節(jié)點進行握手,握手成功后目標節(jié)點會加入到集群中,看個例子,圖片來自于Redis的設計與實現(xiàn):
一個集群的所有數(shù)據(jù)被分為16384個槽,可以通過CLUSTER ADDSLOTS
命令將槽指派給對應的節(jié)點。當所有的槽都有節(jié)點負責時,集群處于上線狀態(tài),否則處于下線狀態(tài)不對外提供服務。
clusterNode的位數(shù)組slots代表一個節(jié)點負責的槽信息。
struct?clusterNode?{ ????unsigned?char?slots[16384/8];?/*?slots?handled?by?this?node?*/ ????int?numslots;???/*?Number?of?slots?handled?by?this?node?*/ ????... }
看個例子,下圖中1、3、5、8、9、10位的值為1,代表該節(jié)點負責槽1、3、5、8、9、10。
每個Redis Server上都有一個ClusterState的對象,代表了該Server所在集群的信息,其中字段slots記錄了集群中所有節(jié)點負責的槽信息。
typedef?struct?clusterState?{ ????//?負責處理各個槽的節(jié)點 ????//?例如?slots[i]?=?clusterNode_A?表示槽?i?由節(jié)點?A?處理 ????//?slots[i]?=?null?代表該槽目前沒有節(jié)點負責 ????clusterNode?*slots[REDIS_CLUSTER_SLOTS]; }
可以通過redis-trib工具對槽重新分配,重分配的實現(xiàn)步驟如下:
通知目標節(jié)點準備好接收槽
通知源節(jié)點準備好發(fā)送槽
向源節(jié)點發(fā)送命令:CLUSTER GETKEYSINSLOT <slot> <count>
從源節(jié)點獲取最多count個槽slot的key
對于步驟3的每個key,都向源節(jié)點發(fā)送一個MIGRATE <target_ip> <target_port> <key_name> 0 <timeout>?
命令,將被選中的鍵原子的從源節(jié)點遷移至目標節(jié)點。
重復步驟3、4。直到槽slot的所有鍵值對都被遷移到目標節(jié)點
將槽slot指派給目標節(jié)點的信息發(fā)送到整個集群。
在槽重分配的過程中,槽中的一部分數(shù)據(jù)保存著源節(jié)點,另一部分保存在目標節(jié)點。這時如果要客戶端向源節(jié)點發(fā)送一個命令,且相關數(shù)據(jù)在一個正在遷移槽中,源節(jié)點處理步驟如圖:
當客戶端收到一個ASK錯誤的時候,會根據(jù)返回的信息向目標節(jié)點重新發(fā)起一次請求。
ASK和MOVED的區(qū)別主要是ASK是一次性的,MOVED是永久性的,有點像Http協(xié)議中的301和302。
我們來看cluster下一次命令的請求過程,假設執(zhí)行命令?get testKey
cluster client在運行前需要配置若干個server節(jié)點的ip和port。我們稱這些節(jié)點為種子節(jié)點。
cluster的客戶端在執(zhí)行命令時,會先通過計算得到key的槽信息,計算規(guī)則為:getCRC16(key) & (16384 - 1)
,得到槽信息后,會從一個緩存map中獲得槽對應的redis server信息,如果能獲取到,則調(diào)到第4步
向種子節(jié)點發(fā)送slots
命令以獲得整個集群的槽分布信息,然后跳轉到第2步重試命令
向負責該槽的server發(fā)起調(diào)用
server處理如圖:
客戶端如果收到MOVED錯誤,則根據(jù)對應的地址跳轉到第4步重新請求,
客戶段如果收到ASK錯誤,則根據(jù)對應的地址跳轉到第4步重新請求,并在請求前帶上ASKING標識。
以上步驟大致就是redis cluster下一次命令請求的過程,但忽略了一個細節(jié),如果要查找的數(shù)據(jù)鎖所在的槽正在重分配怎么辦?
集群中每個Redis節(jié)點都會定期的向集群中的其他節(jié)點發(fā)送PING消息,如果目標節(jié)點沒有在有效時間內(nèi)回復PONG消息,則會被標記為疑似下線。同時將該信息發(fā)送給其他節(jié)點。當一個集群中有半數(shù)負責處理槽的主節(jié)點都將某個節(jié)點A標記為疑似下線后,那么A會被標記為已下線,將A標記為已下線的節(jié)點會將該信息發(fā)送給其他節(jié)點。
比如說有A,B,C,D,E 5個主節(jié)點。E有F、G兩個從節(jié)點。
當E節(jié)點發(fā)生異常后,其他節(jié)點發(fā)送給A的PING消息將不能得到正常回復。當過了最大超時時間后,假設A,B先將E標記為疑似下線;之后C也會將E標記為疑似下線,這時C發(fā)現(xiàn)集群中由3個節(jié)點(A、B、C)都將E標記為疑似下線,超過集群復制槽的主節(jié)點個數(shù)的一半(>2.5)則會將E標記為已下線,并向集群廣播E下線的消息。
當F、G(E的從節(jié)點)收到E被標記已下線的消息后,會根據(jù)Raft算法選舉出一個新的主節(jié)點,新的主節(jié)點會將E復制的所有槽指派給自己,然后向集群廣播消息,通知其他節(jié)點新的主節(jié)點信息。
選舉新的主節(jié)點算法與選舉Sentinel頭節(jié)點的過程很像:
集群的配置紀元是一個自增計數(shù)器,它的初始值為0.
當集群里的某個節(jié)點開始一次故障轉移操作時,集群配置紀元的值會被增一。
對于每個配置紀元,集群里每個負責處理槽的主節(jié)點都有一次投票的機會,而第一個向主節(jié)點要求投票的從節(jié)點將獲得主節(jié)點的投票。
檔從節(jié)點發(fā)現(xiàn)自己正在復制的主節(jié)點進入已下線狀態(tài)時,從節(jié)點會想集群廣播一條CLUSTER_TYPE_FAILOVER_AUTH_REQUEST消息,要求所有接收到這條消息、并且具有投票權的主節(jié)點向這個從節(jié)點投票。
如果一個主節(jié)點具有投票權(它正在負責處理槽),并且這個主節(jié)點尚未投票給其他從節(jié)點,那么主節(jié)點將向要求投票的從節(jié)點返回一條CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK消息,表示這個主節(jié)點支持從節(jié)點成為新的主節(jié)點。
每個參與選舉的從節(jié)點都會接收CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK消息,并根據(jù)自己收到了多少條這種消息來同濟自己獲得了多少主節(jié)點的支持。
如果集群里有N個具有投票權的主節(jié)點,那么當一個從節(jié)點收集到大于等于N/2+1張支持票時,這個從節(jié)點就會當選為新的主節(jié)點。
因為在每一個配置紀元里面,每個具有投票權的主節(jié)點只能投一次票,所以如果有N個主節(jié)點進行投票,那么具有大于等于N/2+1張支持票的從節(jié)點只會有一個,這確保了新的主節(jié)點只會有一個。
如果在一個配置紀元里面沒有從節(jié)點能收集到足夠多的支持票,那么集群進入一個新的配置紀元,并再次進行選舉,知道選出新的主節(jié)點為止。
最后,聊聊redis集群的其他兩種實現(xiàn)方案。
客戶端做路由,采用一致性hash算法,將key映射到對應的redis節(jié)點上。
其優(yōu)點是實現(xiàn)簡單,沒有引用其他中間件。
缺點也很明顯:是一種靜態(tài)分片方案,擴容性差。
Jedis中的ShardedJedis是該方案的實現(xiàn)。
該方案在client與redis之間引入一個代理層。client的所有操作都發(fā)送給代理層,由代理層實現(xiàn)路由轉發(fā)給不同的redis服務器。
其優(yōu)點是: 路由規(guī)則可自定義,擴容方便。
缺點是: 代理層有單點問題,多一層轉發(fā)的網(wǎng)絡開銷
?
網(wǎng)頁標題:分布式Redis深度歷險-Cluster
當前鏈接:http://jinyejixie.com/article32/posdsc.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站、網(wǎng)站制作、全網(wǎng)營銷推廣、網(wǎng)站建設、面包屑導航、網(wǎng)站內(nèi)鏈
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)