Redis3.0以后的版本雖然有了集群功能间雀,提供了比之前版本的哨兵模式更高的性能與可用性,但是集群的水平擴(kuò)展卻比較麻煩,今天就來(lái)帶大家看看redis高可用集群如何做水平擴(kuò)展叽粹,原始集群(見(jiàn)下圖)由6個(gè)節(jié)點(diǎn)組成,6個(gè)節(jié)點(diǎn)分布在三臺(tái)機(jī)器上却舀,采用三主三從的模式
啟動(dòng)集群
啟動(dòng)整個(gè)集群
/export/huey/redis-5.0.2_cluster/redis-5.0.2/src/redis-server /export/huey/redis-5.0.2_cluster/900*/redis.conf
客戶端連接8001端口的redis實(shí)例
/export/huey/redis-5.0.2_cluster/redis-5.0.2/src/redis-cli -a huey -c -h 192.168.59.2 -p 900*
查看集群狀態(tài)
192.168.59.2:9001> cluster nodes
從上圖可以看出,整個(gè)集群運(yùn)行正常锤灿,三個(gè)master節(jié)點(diǎn)和三個(gè)slave節(jié)點(diǎn)挽拔,9001端口的實(shí)例節(jié)點(diǎn)存儲(chǔ)0-5460這些hash槽,9006端口的實(shí)例節(jié)點(diǎn)存儲(chǔ)5461-10922這些hash槽但校,9003端口的實(shí)例節(jié)點(diǎn)存儲(chǔ)10923-16383這些hash槽螃诅,這三個(gè)master節(jié)點(diǎn)存儲(chǔ)的所有hash槽組成redis集群的存儲(chǔ)槽位,slave點(diǎn)是每個(gè)主節(jié)點(diǎn)的備份從節(jié)點(diǎn),不顯示存儲(chǔ)槽位 (之前自己vagarnt宕機(jī)的問(wèn)題導(dǎo)致主從發(fā)生了如此的變化)
集群操作***
我們?cè)谠技夯A(chǔ)上再增加一主(9007)一從(9008)术裸,增加節(jié)點(diǎn)后的集群參見(jiàn)下圖倘是,新增節(jié)點(diǎn)用虛線框表示 (這里在任意一臺(tái)加了,環(huán)境有限)
增加redis實(shí)例
在/usr/local/redis-cluster下創(chuàng)建8007和8008文件夾袭艺,并拷貝8001文件夾下的redis.conf文件到8007和8008這兩個(gè)文件夾下
mkdir 8007
mkdir 8008
cd 8001
cp redis.conf /usr/local/redis-cluster/8007/
cp redis.conf /usr/local/redis-cluster/8008/
修改8007文件夾下的redis.conf配置文件
vim /usr/local/redis-cluster/8007/redis.conf
修改如下內(nèi)容:
port:8007
dir /usr/local/redis-cluster/8007/
cluster-config-file nodes-8007.conf
修改8008文件夾下的redis.conf配置文件
vim /usr/local/redis-cluster/8008/redis.conf
修改內(nèi)容如下:
port:8008
dir /usr/local/redis-cluster/8008/
cluster-config-file nodes8008.conf
啟動(dòng)8007和8008倆個(gè)服務(wù)并查看服務(wù)狀態(tài)
/usr/local/redis-5.0.2/src/redis-server /usr/local/redis-cluster/8007/redis.conf
/usr/local/redis-5.0.2/src/redis-server /usr/local/redis-cluster/8008/redis.conf
ps -el | grep redis
- 查看redis集群的命令幫助
cd /usr/local/redis-5.0.2
src/redis-cli --cluster help
1.create:創(chuàng)建一個(gè)集群環(huán)境host1:port1 ... hostN:portN
2.call:可以執(zhí)行redis命令
3.add-node:將一個(gè)節(jié)點(diǎn)添加到集群里搀崭,第一個(gè)參數(shù)為新節(jié)點(diǎn)的ip:port,第二個(gè)參數(shù)為集群中任意一個(gè)已經(jīng)存在的節(jié)點(diǎn)的ip:port
4.del-node:移除一個(gè)節(jié)點(diǎn)
5.reshard:重新分片
6.check:檢查集群狀態(tài)
配置9007為集群主節(jié)點(diǎn)
使用add-node命令新增一個(gè)主節(jié)點(diǎn)9007(master)猾编,前面為新增節(jié)點(diǎn)瘤睹,后面為已知存在節(jié)點(diǎn),看到日志最后有"[OK] New node added correctly"提示代表新節(jié)點(diǎn)加入成功
./redis-5.0.2/src/redis-cli -a huey --cluster add-node 192.168.59.2:9007 192.168.59.2:9001
查看集群狀態(tài)
注意:當(dāng)添加節(jié)點(diǎn)成功以后答倡,新增的節(jié)點(diǎn)不會(huì)有任何數(shù)據(jù)轰传,因?yàn)樗€沒(méi)有分配任何的slot(hash槽),我們需要為新節(jié)點(diǎn)手工分配hash槽
使用redis-cli命令為9007分配hash槽瘪撇,找到集群中的任意一個(gè)主節(jié)點(diǎn)(紅色位置表示集群中的任意一個(gè)主節(jié)點(diǎn))获茬,對(duì)其進(jìn)行重新分片工作。
./redis-5.0.2/src/redis-cli -a huey --cluster reshard 192.168.59.2:9001
輸出如下:
... ...
How many slots do you want to move (from 1 to 16384)? 600
(ps:需要多少個(gè)槽移動(dòng)到新的節(jié)點(diǎn)上倔既,自己設(shè)置恕曲,比如600個(gè)hash槽)
What is the receiving node ID? eb57a5700ee6f9ff099b3ce0d03b1a50ff247c3c
(ps:把這600個(gè)hash槽移動(dòng)到哪個(gè)節(jié)點(diǎn)上去,需要指定節(jié)點(diǎn)id)
Please enter all the source node IDs.
Type 'all' to use all the nodes as source nodes for the hash slots.
Type 'done' once you entered all the source nodes IDs.
Source node 1:all
(ps:輸入all為從所有主節(jié)點(diǎn)(9001,9003,9006)中分別抽取相應(yīng)的槽數(shù)指定到新節(jié)點(diǎn)中叉存,抽取的總槽數(shù)為600個(gè)码俩,也可以用done 從某個(gè))
... ...
Do you want to proceed with the proposed reshard plan (yes/no)? yes
(ps:輸入yes確認(rèn)開(kāi)始執(zhí)行分片任務(wù))
... ...
查看下最新的集群狀態(tài)
如上圖所示,現(xiàn)在我們的9007已經(jīng)有hash槽了歼捏,也就是說(shuō)可以在9007上進(jìn)行讀寫數(shù)據(jù)啦稿存!到此為止我們的9007已經(jīng)加入到集群中,并且是主節(jié)點(diǎn)(Master)
配置9008為9007的從節(jié)點(diǎn)
添加從節(jié)點(diǎn)8008到集群中去并查看集群狀態(tài)
./redis-5.0.2/src/redis-cli -a huey --cluster add-node 192.168.59.2:9008 192.168.59.2:9001
如圖所示瞳秽,還是一個(gè)master節(jié)點(diǎn)瓣履,沒(méi)有被分配任何的hash槽。
我們需要執(zhí)行replicate命令來(lái)指定當(dāng)前節(jié)點(diǎn)(從節(jié)點(diǎn))的主節(jié)點(diǎn)id為哪個(gè),首先需要連接新加的9008節(jié)點(diǎn)的客戶端练俐,然后使用集群命令進(jìn)行操作袖迎,把當(dāng)前的9008(slave)節(jié)點(diǎn)指定到一個(gè)主節(jié)點(diǎn)下(這里使用之前創(chuàng)建的9007主節(jié)點(diǎn),紅色表示節(jié)點(diǎn)id)
./redis-5.0.2/src/redis-cli -c -h 192.168.59.2 -p 9008
192.168.59.2:9008> cluster replicate a19e39e2893c8b278bdf8e9351167e54903d6869
查看集群狀態(tài)腺晾,9008節(jié)點(diǎn)已成功添加為9007節(jié)點(diǎn)的從節(jié)點(diǎn)
刪除9008從節(jié)點(diǎn)
用del-node刪除從節(jié)點(diǎn)9008燕锥,指定刪除節(jié)點(diǎn)ip和端口,以及節(jié)點(diǎn)id
./redis-5.0.2/src/redis-cli -a huey --cluster del-node 192.168.59.2:9008 2bfced0a31a9c61ab01e3ead59cbb05c3a8f0097
再次查看集群狀態(tài)悯蝉,如下圖所示归形,8008這個(gè)slave節(jié)點(diǎn)已經(jīng)移除,并且該節(jié)點(diǎn)的redis服務(wù)也已被停止
刪除9007主節(jié)點(diǎn)
最后鼻由,我們嘗試刪除之前加入的主節(jié)點(diǎn)9007暇榴,這個(gè)步驟相對(duì)比較麻煩一些厚棵,因?yàn)橹鞴?jié)點(diǎn)的里面是有分配了hash槽的,所以我們這里必須先把9007里的hash槽放入到其他的可用主節(jié)點(diǎn)中去蔼紧,然后再進(jìn)行移除節(jié)點(diǎn)操作婆硬,不然會(huì)出現(xiàn)數(shù)據(jù)丟失問(wèn)題(目前只能把master的數(shù)據(jù)遷移到一個(gè)節(jié)點(diǎn)上,暫時(shí)做不了平均分配功能)奸例,執(zhí)行命令如下:
./redis-5.0.2/src/redis-cli -a huey --cluster reshard 192.168.59.2:9007
輸出如下:
... ...
How many slots do you want to move (from 1 to 16384)? 600
What is the receiving node ID? deedad3c34e8437baa6ff013fd3d1461a0c2e761
(ps:這里是需要把數(shù)據(jù)移動(dòng)到哪彬犯?9001的主節(jié)點(diǎn)id)
Please enter all the source node IDs.
Type 'all' to use all the nodes as source nodes for the hash slots.
Type 'done' once you entered all the source nodes IDs.
Source node 1:eb57a5700ee6f9ff099b3ce0d03b1a50ff247c3c
(ps:這里是需要數(shù)據(jù)源,也就是我們的8007節(jié)點(diǎn)id)
Source node 2:done
(ps:這里直接輸入done 開(kāi)始生成遷移計(jì)劃)
... ...
Do you want to proceed with the proposed reshard plan (yes/no)? Yes
(ps:這里輸入yes開(kāi)始遷移)
至此哩至,我們已經(jīng)成功的把9007主節(jié)點(diǎn)的數(shù)據(jù)遷移到9001上去了躏嚎,我們可以看一下現(xiàn)在的集群狀態(tài)如下圖,你會(huì)發(fā)現(xiàn)8007下面已經(jīng)沒(méi)有任何hash槽了菩貌,證明遷移成功卢佣!
最后我們直接使用del-node命令刪除9007主節(jié)點(diǎn)即可。
[root@node2 redis-5.0.2_cluster]# ./redis-5.0.2/src/redis-cli -a huey --cluster del-node 192.168.59.2:9007 a19e39e2893c8b278bdf8e9351167e54903d6869
查看集群狀態(tài)箭阶,一切還原為最初始狀態(tài)啦虚茶!大功告成!
Redis集群選舉原理分析***
當(dāng)slave發(fā)現(xiàn)自己的master變?yōu)镕AIL狀態(tài)時(shí)仇参,便嘗試進(jìn)行Failover嘹叫,以期成為新的master。由于掛掉的master可能會(huì)有多個(gè)slave诈乒,從而存在多個(gè)slave競(jìng)爭(zhēng)成為master節(jié)點(diǎn)的過(guò)程罩扇, 其過(guò)程如下:
1.slave發(fā)現(xiàn)自己的master變?yōu)镕AIL
2.將自己記錄的集群currentEpoch加1,并廣播FAILOVER_AUTH_REQUEST 信息
3.其他節(jié)點(diǎn)收到該信息怕磨,只有master響應(yīng)喂饥,判斷請(qǐng)求者的合法性,并發(fā)送FAILOVER_AUTH_ACK肠鲫,對(duì)每一個(gè)epoch只發(fā)送一次ack
4.嘗試failover的slave收集FAILOVER_AUTH_ACK
5.超過(guò)半數(shù)后變成新Master.
6.廣播Pong通知其他集群節(jié)點(diǎn)员帮。
從節(jié)點(diǎn)并不是在主節(jié)點(diǎn)一進(jìn)入 FAIL 狀態(tài)就馬上嘗試發(fā)起選舉,而是有一定延遲导饲,一定的延遲確保我們等待FAIL狀態(tài)在集群中傳播捞高,slave如果立即嘗試選舉,其它masters或許尚未意識(shí)到FAIL狀態(tài)渣锦,可能會(huì)拒絕投票
?延遲計(jì)算公式:
DELAY = 500ms + random(0 ~ 500ms) + SLAVE_RANK * 1000ms
?SLAVE_RANK表示此slave已經(jīng)從master復(fù)制數(shù)據(jù)的總量的rank硝岗。Rank越小代表已復(fù)制的數(shù)據(jù)越新。這種方式下袋毙,持有最新數(shù)據(jù)的slave將會(huì)首先發(fā)起選舉(理論上)辈讶。
總結(jié)
根據(jù)業(yè)務(wù)并發(fā)量可動(dòng)態(tài)擴(kuò)展節(jié)點(diǎn)。生產(chǎn)直接可以用
參考
官網(wǎng):https://redis.io/