redis集群 第一節(jié) 節(jié)點

一個Redis集群通常由多個節(jié)點組成蔑鹦,在剛開始的時候,每個節(jié)點都是相互獨立的,它們都處于一個只包含自己的集群當中拳亿,要組件一個真正可工作的集群,我們必須將各個獨立的節(jié)點連接起來愿伴,構(gòu)成一個包含多個節(jié)點的集群肺魁。
連接各個節(jié)點的工作可以使用CLUSTER MEET命令來完成,該命令的格式如下:

CLUSTER MEET <ip> <port>

向一個節(jié)點node發(fā)送CLUSTER MEET命令公般,可以讓node節(jié)點與ip和port所指定的節(jié)點進行握手(handshake)万搔,當握手成功時,node節(jié)點就會將ip和port所指定的節(jié)點添加到當前所在的集群中官帘。

1.1 啟動節(jié)點

一個節(jié)點就是一個運行在集群模式下的Redis服務(wù)器瞬雹,Redis服務(wù)器在啟動時會根據(jù)cluster-enabled配置選項是否為yes來決定是否開啟服務(wù)器的集群模式。
節(jié)點(運行在集群模式下的Redis服務(wù)器)會繼續(xù)使用所有在單機模式中使用的服務(wù)器組件刽虹,比如說:

  • 節(jié)點會繼續(xù)使用文件事件處理器來處理命令請求和返回命令回復酗捌。
  • 節(jié)點會繼續(xù)使用時間事件處理器來執(zhí)行serverCron函數(shù),而serverCron函數(shù)又會調(diào)用集群模式特有的clusterCron函數(shù)涌哲。clusterCron函數(shù)負責執(zhí)行在集群模式下需要執(zhí)行的常規(guī)操作胖缤,例如向集群中的其他節(jié)點發(fā)送Gossip消息,檢查節(jié)點是否斷線阀圾,或者檢查是否需要對下線節(jié)點進行自動故障轉(zhuǎn)移等哪廓。
  • 節(jié)點會繼續(xù)使用數(shù)據(jù)庫來保存鍵值對數(shù)據(jù),鍵值對依然會是各種不同類型的對象初烘。
  • 節(jié)點會繼續(xù)使用RDB持久化模塊和AOF持久化模塊來執(zhí)行持久化工作涡真。
  • 節(jié)點會繼續(xù)使用發(fā)布與訂閱模塊來執(zhí)行PUBLISH分俯、SUBSCRIBE等命令。
  • 節(jié)點會繼續(xù)使用復制模塊來進行節(jié)點的復制工作哆料。
  • 節(jié)點會繼續(xù)使用Lua腳本環(huán)境來執(zhí)行客戶端輸入的Lua腳本缸剪。
  • 節(jié)點會繼續(xù)使用redisServer結(jié)構(gòu)來保存服務(wù)器的狀態(tài),使用redisClient結(jié)構(gòu)來保存客戶端的狀態(tài)东亦,至于那些只有在集群模式下才會用到的數(shù)據(jù)杏节,節(jié)點將它們保存到了cluster.h/clusterNode結(jié)構(gòu)、cluster.h/clusterLink結(jié)構(gòu)典阵,以及cluster.h/clusterState結(jié)構(gòu)里面奋渔。

1.2 集群數(shù)據(jù)結(jié)構(gòu)

clusterNode結(jié)構(gòu)保存了一個節(jié)點的當前狀態(tài),比如節(jié)點的創(chuàng)建時間壮啊、節(jié)點的名字卒稳、節(jié)點當前的配置紀元、節(jié)點的IP地址和端口號等等他巨。
每個節(jié)點斗湖使用一個clusterNode結(jié)構(gòu)來記錄自己的狀態(tài)充坑,并為集群中的所有其他節(jié)點(包括主節(jié)點和從節(jié)點)都創(chuàng)建一個相應(yīng)的clusterNode結(jié)構(gòu),以此來記錄其他節(jié)點的狀態(tài)染突。

struct clusterNode {
// 創(chuàng)建節(jié)點的時間
mstime_t ctime捻爷;
// 節(jié)點的名字,由40個十六進制字符組成
// 例如例如 68eef66df23420a5862208ef5b1a7005b806f2ff
char name[REDIS_CLUSTER_NAMELEN];
// 節(jié)點標識
// 使用各種不同的標識值記錄節(jié)點的角色(比如主節(jié)點或者從節(jié)點)份企,
// 以及節(jié)點目前所處的狀態(tài)(比如在線或下線)也榄。
int flags;
// 節(jié)點當前的配置紀元,用于實現(xiàn)故障轉(zhuǎn)移
uint64_t configEpoch;
// 節(jié)點的IP地址
char ip[REDIS_IP_STR_LEN];
// 節(jié)點的端口號
int port;
// 保存連接節(jié)點所需的有關(guān)信息
clusterLink *link;
// ...
}司志;

clusterNode結(jié)構(gòu)的link屬性是一個clusterLink結(jié)構(gòu)甜紫,該結(jié)構(gòu)保存了連接節(jié)點所需的有關(guān)信息,比如套接字描述符骂远,輸入緩沖區(qū)和輸出緩存區(qū):

typedef struct clusterLink {
// 連接的創(chuàng)建時間
mstime_t ctime;
// 套接字描述符
int fd;
// 輸出緩沖區(qū)囚霸,保存著等待發(fā)送給其他節(jié)點的消息(message)。
sds sndbuf;
// 輸入緩沖區(qū)激才,保存著從其他節(jié)點接收到的消息拓型。
sds rcvbuf;
// 與這個連接相關(guān)聯(lián)的其他節(jié)點,如果沒有的話就為NULL
struct clusterNode *node;
} clusterLink;

redisClient結(jié)構(gòu)和clusterLink結(jié)構(gòu)都有自己的套接字描述符和輸入瘸恼、輸出緩沖區(qū)劣挫,這兩個結(jié)構(gòu)區(qū)別在于,redisClient結(jié)構(gòu)中的套接字和緩沖區(qū)是用于連接客戶端的东帅,而clusterLink結(jié)構(gòu)中的套接字和緩沖區(qū)則是用于連接節(jié)點的压固。
最后,每個節(jié)點都保存著一個clusterState結(jié)構(gòu)靠闭,這個結(jié)構(gòu)記錄了在當前節(jié)點的視角下帐我,集群目前所處的狀態(tài)刘莹,例如集群是在線還是下線,集群包含多少個節(jié)點焚刚,集群當前的配置紀元,諸如此類:

typedef struct clusterState {
// 指向當前節(jié)點的指針
clusterNode *myself;
// 集群當前的配置紀元扇调,用于實現(xiàn)故障轉(zhuǎn)移
uint64_t currentEpoch;
// 集群當前的狀態(tài):是在線還是下線
int state;
// 集群中至少處理著一個槽的節(jié)點的數(shù)量
int size;
// 集群節(jié)點名單(包括myself節(jié)點)
// 字典的鍵為節(jié)點的名字矿咕,字典的值為節(jié)點對應(yīng)的clusterNode結(jié)構(gòu)
dit *nodes;
} clusterState;

1.3 CLUSTER MEET命令的實現(xiàn)

通過向節(jié)點A發(fā)送CLUSTER MEET命令,客戶端可以讓接收命令的節(jié)點A將另一個節(jié)點B添加到節(jié)點A當前所在的集群里面:

CLUSTER MEET <ip> <port>

收到命令的節(jié)點A將與節(jié)點B進行握手(handshake)狼钮,以此來確認彼此的存在碳柱,并為將來的進一步通信打好基礎(chǔ):

  • 節(jié)點A會為節(jié)點B創(chuàng)建一個clusterNode結(jié)構(gòu),并將該結(jié)構(gòu)添加到自己的clusterState.nodes字典里面
  • 之后熬芜,節(jié)點A將根據(jù)CLUSTER MEET命令給定的IP地址和端口號莲镣,向節(jié)點B發(fā)送一條MEET消息(message)
  • 如果一切順利,節(jié)點B將接收到節(jié)點A發(fā)送的MEET消息涎拉,節(jié)點B會為節(jié)點A創(chuàng)建一個clusterNode結(jié)構(gòu)瑞侮,并將該結(jié)構(gòu)添加到自己的clusterState.nodes字典里面
  • 之后,節(jié)點B將向節(jié)點A返回一條PONG消息
  • 如果一切順利鼓拧,節(jié)點A將接收到節(jié)點B返回的PONG消息半火,通過這條PONG消息節(jié)點A可以知道節(jié)點B已經(jīng)成地接收了自己發(fā)送的MEET消息
  • 之后,節(jié)點A將向節(jié)點B返回一條PING消息
  • 如果一切順利季俩,節(jié)點B將接收到節(jié)點A返回的PING消息钮糖,通過這條PING消息節(jié)點B可以知道節(jié)點A已經(jīng)成功地接收到了自己返回的PONG消息,握手完成酌住。
  • 之后店归,節(jié)點A會將節(jié)點B的信息通過Gossip協(xié)議傳播給集群中的其他節(jié)點,讓其他節(jié)點也與節(jié)點B進行握手酪我,最終消痛,經(jīng)過一段時間之后,節(jié)點B會被集群中的所有節(jié)點認識都哭。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末肄满,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子质涛,更是在濱河造成了極大的恐慌稠歉,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件汇陆,死亡現(xiàn)場離奇詭異怒炸,居然都是意外死亡,警方通過查閱死者的電腦和手機毡代,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進店門阅羹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來勺疼,“玉大人,你說我怎么就攤上這事捏鱼≈绰” “怎么了?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵导梆,是天一觀的道長轨淌。 經(jīng)常有香客問我,道長看尼,這世上最難降的妖魔是什么递鹉? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮藏斩,結(jié)果婚禮上躏结,老公的妹妹穿的比我還像新娘。我一直安慰自己狰域,他們只是感情好媳拴,可當我...
    茶點故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著兆览,像睡著了一般禀挫。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上拓颓,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天语婴,我揣著相機與錄音,去河邊找鬼驶睦。 笑死砰左,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的场航。 我是一名探鬼主播缠导,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼溉痢!你這毒婦竟也來了僻造?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤孩饼,失蹤者是張志新(化名)和其女友劉穎髓削,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體镀娶,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡立膛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片宝泵。...
    茶點故事閱讀 40,505評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡好啰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出儿奶,到底是詐尸還是另有隱情框往,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布闯捎,位于F島的核電站椰弊,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏隙券。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一闹司、第九天 我趴在偏房一處隱蔽的房頂上張望娱仔。 院中可真熱鬧,春花似錦游桩、人聲如沸牲迫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽盹憎。三九已至,卻和暖如春铐刘,著一層夾襖步出監(jiān)牢的瞬間陪每,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工镰吵, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留檩禾,地道東北人。 一個月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓疤祭,卻偏偏與公主長得像盼产,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子勺馆,可洞房花燭夜當晚...
    茶點故事閱讀 45,515評論 2 359

推薦閱讀更多精彩內(nèi)容