一鼓寺、主從復(fù)制
0. 從服務(wù)器向主服務(wù)器發(fā)送sync命令班缰,從而開始主從復(fù)制,主要步驟:主服務(wù)器執(zhí)行bgsave蜘矢,在后臺(tái)生成一個(gè)rdb文件枫绅,并用一個(gè)緩沖區(qū)記錄從現(xiàn)在開始的所有寫命令。主服務(wù)器將rdb文件和緩沖區(qū)中的寫命令發(fā)送給從服務(wù)器硼端,從服務(wù)器載入rdb文件并執(zhí)行緩沖區(qū)中的命令從而達(dá)到主從一致。
1. redis 2.8之前不能高效處理斷線后重復(fù)制情況寓搬,但redis2.8新添加的部分重同步功能可以解決這個(gè)問題珍昨。部分重同步是通過主服務(wù)器將主從服務(wù)器連接斷開期間執(zhí)行的寫命令發(fā)送給從服務(wù)器來實(shí)現(xiàn)的。
2. 部分重同步通過復(fù)制偏移量句喷、復(fù)制積壓緩沖區(qū)镣典、服務(wù)器運(yùn)行id三個(gè)部分來實(shí)現(xiàn)。
復(fù)制偏移量記錄了主服務(wù)器和從服務(wù)器當(dāng)前發(fā)送或者接收數(shù)據(jù)的數(shù)量唾琼。當(dāng)主服務(wù)器向從服務(wù)器發(fā)送N個(gè)字節(jié)數(shù)據(jù)后兄春,就將復(fù)制偏移量加N,當(dāng)從服務(wù)器接收到N個(gè)字節(jié)數(shù)據(jù)后锡溯,就將自己的復(fù)制偏移量加N赶舆。
復(fù)制積壓緩沖區(qū)是主服務(wù)器用來保存最近傳播命令的隊(duì)列。同時(shí)它也會(huì)為隊(duì)列中的每個(gè)字節(jié)記錄相應(yīng)的復(fù)制偏移量祭饭。當(dāng)斷線重連后從服務(wù)器會(huì)將自己的復(fù)制偏移量發(fā)送給主服務(wù)器芜茵,如果這個(gè)offset之后的內(nèi)容在復(fù)制積壓緩沖區(qū)的話就執(zhí)行部分重同步,否則就執(zhí)行完全重同步倡蝙。
主服務(wù)器的服務(wù)器id用來標(biāo)識(shí)主服務(wù)器九串,斷線重連后從服務(wù)器將之前保存的主服務(wù)器id發(fā)給當(dāng)前連接上的主服務(wù)器,主服務(wù)器以此判斷之前是否是和自己進(jìn)行的同步。如果之前是和自己進(jìn)行的同步猪钮,則可以繼續(xù)進(jìn)行部分重同步品山,否則就進(jìn)行完全重同步。
3. 復(fù)制是通過從服務(wù)器向主服務(wù)器發(fā)送命令來實(shí)現(xiàn)的烤低。
4. 主服務(wù)器通過向從服務(wù)器傳播命令來更新從服務(wù)器的狀態(tài)肘交,保持主從服務(wù)器一致,而從服務(wù)器會(huì)向主服務(wù)器發(fā)送心跳檢測拂玻,一方面檢測主從服務(wù)器的網(wǎng)絡(luò)狀態(tài)酸些,一方面獲取從服務(wù)器的偏移量。
二檐蚜、哨兵模式
1. 哨兵本質(zhì)上是一個(gè)運(yùn)行在特殊模式下的redis服務(wù)器魄懂,它有一些和普通redis服務(wù)器不同的功能。
sentinel和主服務(wù)器以及從服務(wù)器之間有命令連接和訂閱連接闯第。
2. sentinel向主服務(wù)器發(fā)送info命令能夠獲取到主服務(wù)器的信息及其所屬的從服務(wù)器信息市栗。
3. 每個(gè)sentinel通過向每個(gè)master和slave的發(fā)布/訂閱頻道__sentinel__:hello每秒發(fā)送一次消息,來宣布它的存在咳短。每個(gè)sentinel也訂閱了每個(gè)master和slave的頻道__sentinel__:hello的內(nèi)容填帽,來發(fā)現(xiàn)未知的sentinel,當(dāng)檢測到了新的sentinel咙好,則將其加入到自身維護(hù)的master監(jiān)控列表中篡腌。
4. sentinel以每秒一次的頻率向主從服務(wù)器、其他sentinel發(fā)送PING命令勾效,并根據(jù)對方對PING的回復(fù)來判斷對方是否在線嘹悼,如果在設(shè)置的時(shí)間內(nèi)連續(xù)收到無效回復(fù)則認(rèn)為對方下線。當(dāng)一個(gè)sentinel判斷某個(gè)主服務(wù)器下線后层宫,會(huì)詢問其他服務(wù)器是否也認(rèn)為該主服務(wù)器下線杨伙,在得到一個(gè)數(shù)量的肯定答復(fù)后會(huì)將該主服務(wù)器判定為客觀下線,并執(zhí)行故障轉(zhuǎn)移萌腿。
5.?當(dāng)一個(gè)主服務(wù)器被判斷為客觀下線時(shí)限匣,監(jiān)視這個(gè)下線主服務(wù)器的各個(gè)sentinel會(huì)進(jìn)行協(xié)商,選舉出領(lǐng)頭sentinel進(jìn)行故障轉(zhuǎn)移毁菱。leader會(huì)在slaves中選擇一個(gè)作為新的master米死。leader向master發(fā)送slaveof on one,向其他slaves發(fā)送slaveof ip port(新的master的ip和port)贮庞,slaves就會(huì)復(fù)制新的master中的數(shù)據(jù)哲身。
leader會(huì)選擇哪一個(gè)slave作為新的master呢?
1)排除斷線的slaves
2)選擇優(yōu)先級(jí)最高的
3)選擇復(fù)制偏移量最大的
4)選擇run_id最小的
三贸伐、集群
redis集群是通過分片方式來實(shí)現(xiàn)的分布式方案勘天。
節(jié)點(diǎn)通過CLUSTER MEET命令將其他節(jié)點(diǎn)加入到自己的集群中。
1.?節(jié)點(diǎn)通過握手來將其他節(jié)點(diǎn)添加到自己所處的集群中。
2.?集群中共有16384個(gè)槽脯丝,當(dāng)這些槽都完成指派后集群處于上線狀態(tài)商膊,否則處于下線狀態(tài)。每個(gè)節(jié)點(diǎn)會(huì)通過消息將自己負(fù)責(zé)的槽信息發(fā)送給其他節(jié)點(diǎn)宠进,每個(gè)節(jié)點(diǎn)都會(huì)記錄哪些槽指派給了自己晕拆,哪些槽指派給了其他節(jié)點(diǎn)。
3.?節(jié)點(diǎn)接到一個(gè)客戶端發(fā)送的命令后材蹬,會(huì)先檢查這個(gè)命令請求要處理的鍵所處理的槽是否由自己負(fù)責(zé)实幕,如果不是的話就向客戶端返回一個(gè)MOVED,并轉(zhuǎn)入所在的節(jié)點(diǎn)堤器。
4.?節(jié)點(diǎn)通過 CRC16(KEY) & 16383?來計(jì)算鍵屬于哪個(gè)槽昆庇。
5.?可以對集群進(jìn)行重新分片來將任意數(shù)量已經(jīng)分配給某個(gè)節(jié)點(diǎn)的槽改為指派給其他節(jié)點(diǎn),槽所屬的鍵值對也會(huì)被移動(dòng)到目標(biāo)節(jié)點(diǎn)闸溃。
6.?在進(jìn)行重新分片時(shí)整吆,如果鍵所屬的槽正在遷移往其他節(jié)點(diǎn),則會(huì)返回一個(gè)ASK指令辉川,指向新的節(jié)點(diǎn)表蝙。與MOVED的永久轉(zhuǎn)向不同的是,該指令只會(huì)對下一次的訪問轉(zhuǎn)向乓旗。
7.?故障轉(zhuǎn)移
集群中的每個(gè)節(jié)點(diǎn)都會(huì)定期地向集群中其它節(jié)點(diǎn)發(fā)送ping消息府蛇,以此來檢測對方是否在線。如果在規(guī)定時(shí)間內(nèi)沒有收到pong回復(fù)屿愚。則認(rèn)為目標(biāo)節(jié)點(diǎn)標(biāo)記為疑似下線(PFAIL)欲诺。
當(dāng)一個(gè)從節(jié)點(diǎn)發(fā)現(xiàn)自己正在復(fù)制的主節(jié)點(diǎn)進(jìn)入了已下線時(shí),從節(jié)點(diǎn)將開始對已下線的主節(jié)點(diǎn)進(jìn)行故障轉(zhuǎn)移操作渺鹦,以下是故障轉(zhuǎn)移的執(zhí)行步驟:
下線的主節(jié)點(diǎn)的所有從節(jié)點(diǎn)里面,會(huì)進(jìn)行選舉蛹含,選舉出一個(gè)新的主節(jié)點(diǎn)毅厚。
被選中的從節(jié)點(diǎn)會(huì)執(zhí)行 slave no one命令,成為新的主節(jié)點(diǎn)浦箱。
新的主節(jié)點(diǎn)會(huì)撤銷所有對已下線主節(jié)點(diǎn)的槽指派吸耿,并將這些槽指派給自己。
新的主節(jié)點(diǎn)向集群廣播一條pong消息酷窥,這條pong消息可以讓集群中的其他節(jié)點(diǎn)立即知道這個(gè)節(jié)點(diǎn)已經(jīng)由從節(jié)點(diǎn)變成了主節(jié)點(diǎn)咽安,并且這個(gè)主節(jié)點(diǎn)已經(jīng)接管了原本由已下線節(jié)點(diǎn)處理的槽。
新的主節(jié)點(diǎn)開始接受和自己負(fù)責(zé)處理的槽有關(guān)的命令請求蓬推,故障轉(zhuǎn)移操作完成妆棒。
8. redis cluster默認(rèn)不是高可用的,要為每個(gè)主節(jié)點(diǎn)設(shè)置從節(jié)點(diǎn)來實(shí)現(xiàn)高可用。