成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

分布式Redis深度歷險-Cluster

本文為分布式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ù)共享。

?

集群基礎實現(xiàn)

一個集群由多個Redis節(jié)點組成,不同的節(jié)點通過CLUSTER MEET命令進行連接:

CLUSTER MEET <ip> <port>

收到命令的節(jié)點會與命令中指定的目標節(jié)點進行握手,握手成功后目標節(jié)點會加入到集群中,看個例子,圖片來自于Redis的設計與實現(xiàn):

分布式Redis深度歷險-Cluster

分布式Redis深度歷險-Cluster

分布式Redis深度歷險-Cluster

分布式Redis深度歷險-Cluster

分布式Redis深度歷險-Cluster

?

槽分配

一個集群的所有數(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)步驟如下:

  1. 通知目標節(jié)點準備好接收槽

  2. 通知源節(jié)點準備好發(fā)送槽

  3. 向源節(jié)點發(fā)送命令:CLUSTER GETKEYSINSLOT <slot> <count>從源節(jié)點獲取最多count個槽slot的key

  4. 對于步驟3的每個key,都向源節(jié)點發(fā)送一個MIGRATE <target_ip> <target_port> <key_name> 0 <timeout>?命令,將被選中的鍵原子的從源節(jié)點遷移至目標節(jié)點。

  5. 重復步驟3、4。直到槽slot的所有鍵值對都被遷移到目標節(jié)點

  6. 將槽slot指派給目標節(jié)點的信息發(fā)送到整個集群。

在槽重分配的過程中,槽中的一部分數(shù)據(jù)保存著源節(jié)點,另一部分保存在目標節(jié)點。這時如果要客戶端向源節(jié)點發(fā)送一個命令,且相關數(shù)據(jù)在一個正在遷移槽中,源節(jié)點處理步驟如圖:
分布式Redis深度歷險-Cluster

當客戶端收到一個ASK錯誤的時候,會根據(jù)返回的信息向目標節(jié)點重新發(fā)起一次請求。

ASK和MOVED的區(qū)別主要是ASK是一次性的,MOVED是永久性的,有點像Http協(xié)議中的301和302。

?

一次命令執(zhí)行過程

我們來看cluster下一次命令的請求過程,假設執(zhí)行命令?get testKey

  1. cluster client在運行前需要配置若干個server節(jié)點的ip和port。我們稱這些節(jié)點為種子節(jié)點。

  2. cluster的客戶端在執(zhí)行命令時,會先通過計算得到key的槽信息,計算規(guī)則為:getCRC16(key) & (16384 - 1),得到槽信息后,會從一個緩存map中獲得槽對應的redis server信息,如果能獲取到,則調(diào)到第4步

  3. 向種子節(jié)點發(fā)送slots命令以獲得整個集群的槽分布信息,然后跳轉到第2步重試命令

  4. 向負責該槽的server發(fā)起調(diào)用
    server處理如圖:
    分布式Redis深度歷險-Cluster

  5. 客戶端如果收到MOVED錯誤,則根據(jù)對應的地址跳轉到第4步重新請求,

  6. 客戶段如果收到ASK錯誤,則根據(jù)對應的地址跳轉到第4步重新請求,并在請求前帶上ASKING標識。

以上步驟大致就是redis cluster下一次命令請求的過程,但忽略了一個細節(jié),如果要查找的數(shù)據(jù)鎖所在的槽正在重分配怎么辦?

?

Redis故障轉移

疑似下線與已下線

集群中每個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下線的消息。

?

選取新的主節(jié)點

當F、G(E的從節(jié)點)收到E被標記已下線的消息后,會根據(jù)Raft算法選舉出一個新的主節(jié)點,新的主節(jié)點會將E復制的所有槽指派給自己,然后向集群廣播消息,通知其他節(jié)點新的主節(jié)點信息。

選舉新的主節(jié)點算法與選舉Sentinel頭節(jié)點的過程很像:

  1. 集群的配置紀元是一個自增計數(shù)器,它的初始值為0.

  2. 當集群里的某個節(jié)點開始一次故障轉移操作時,集群配置紀元的值會被增一。

  3. 對于每個配置紀元,集群里每個負責處理槽的主節(jié)點都有一次投票的機會,而第一個向主節(jié)點要求投票的從節(jié)點將獲得主節(jié)點的投票。

  4. 檔從節(jié)點發(fā)現(xiàn)自己正在復制的主節(jié)點進入已下線狀態(tài)時,從節(jié)點會想集群廣播一條CLUSTER_TYPE_FAILOVER_AUTH_REQUEST消息,要求所有接收到這條消息、并且具有投票權的主節(jié)點向這個從節(jié)點投票。

  5. 如果一個主節(jié)點具有投票權(它正在負責處理槽),并且這個主節(jié)點尚未投票給其他從節(jié)點,那么主節(jié)點將向要求投票的從節(jié)點返回一條CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK消息,表示這個主節(jié)點支持從節(jié)點成為新的主節(jié)點。

  6. 每個參與選舉的從節(jié)點都會接收CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK消息,并根據(jù)自己收到了多少條這種消息來同濟自己獲得了多少主節(jié)點的支持。

  7. 如果集群里有N個具有投票權的主節(jié)點,那么當一個從節(jié)點收集到大于等于N/2+1張支持票時,這個從節(jié)點就會當選為新的主節(jié)點。

  8. 因為在每一個配置紀元里面,每個具有投票權的主節(jié)點只能投一次票,所以如果有N個主節(jié)點進行投票,那么具有大于等于N/2+1張支持票的從節(jié)點只會有一個,這確保了新的主節(jié)點只會有一個。

  9. 如果在一個配置紀元里面沒有從節(jié)點能收集到足夠多的支持票,那么集群進入一個新的配置紀元,并再次進行選舉,知道選出新的主節(jié)點為止。

?

Redis常用分布式實現(xiàn)方案

最后,聊聊redis集群的其他兩種實現(xiàn)方案。

client做分片

客戶端做路由,采用一致性hash算法,將key映射到對應的redis節(jié)點上。
其優(yōu)點是實現(xiàn)簡單,沒有引用其他中間件。
缺點也很明顯:是一種靜態(tài)分片方案,擴容性差。

Jedis中的ShardedJedis是該方案的實現(xiàn)。

proxy做分片

該方案在client與redis之間引入一個代理層。client的所有操作都發(fā)送給代理層,由代理層實現(xiàn)路由轉發(fā)給不同的redis服務器。

分布式Redis深度歷險-Cluster

其優(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)

成都定制網(wǎng)站建設
台中市| 巴中市| 宁波市| 大宁县| 安远县| 尤溪县| 九江市| 长治市| 牙克石市| 新蔡县| 平安县| 那曲县| 资源县| 临清市| 固阳县| 滦南县| 屏东县| 泰安市| 镇沅| 凤山县| 大田县| 比如县| 寿阳县| 河池市| 小金县| 景谷| 宁乡县| 江川县| 黄龙县| 浏阳市| 巴南区| 清新县| 玉溪市| 蒙山县| 荣昌县| 柘城县| 乐陵市| 平定县| 富顺县| 亳州市| 柳林县|