超詳細(xì),多圖文介紹redis集群方式并搭建redis偽集群
超多圖文循诉,對(duì)新手友好度極好横辆。敲命令的過(guò)程中,難免會(huì)敲錯(cuò)茄猫,但為了截好一張合適的圖狈蚤,一旦出現(xiàn)一點(diǎn)問(wèn)題,為了好的演示效果划纽,就要從頭開(kāi)始敲脆侮。且看且珍惜。
再認(rèn)識(shí)redis集群前勇劣,若想先知道redis單機(jī)版的可查看靖避,springboot整合redis潭枣。好了,下面開(kāi)始了幻捏。
每個(gè)redis實(shí)例可稱(chēng)為一個(gè)節(jié)點(diǎn)盆犁,安裝redis并以默認(rèn)端口啟動(dòng)是節(jié)點(diǎn),不關(guān)閉篡九,以另一個(gè)端口啟動(dòng)蚣抗,是一個(gè)新節(jié)點(diǎn)。在另一臺(tái)機(jī)器安裝redis并啟動(dòng)瓮下,也是一個(gè)新節(jié)點(diǎn)。
節(jié)點(diǎn)分為主節(jié)點(diǎn) (master) 钝域,從節(jié)點(diǎn) (slave) 讽坏,數(shù)據(jù)從主節(jié)點(diǎn)向多個(gè)從節(jié)點(diǎn)上同步 。
redis3.0開(kāi)始支持集群例证,redis集群是沒(méi)有統(tǒng)一的入口的路呜,客戶(hù)端(client)連接集群的時(shí)候連接集群中的任意節(jié)點(diǎn)(node)即可,集群內(nèi)部的節(jié)點(diǎn)是相互通信的(PING-PONG機(jī)制)织咧。
@[toc]
一胀葱,集群方式
1,主從模式
一個(gè)master可以擁有多個(gè)slave笙蒙,但是一個(gè)slave只能對(duì)應(yīng)一個(gè)master抵屿。這樣,當(dāng)某個(gè)slave掛了不影響其他slave的讀和master的讀和寫(xiě)捅位,重新啟動(dòng)后會(huì)轧葛,數(shù)據(jù)會(huì)從master上同步過(guò)來(lái)。
在主從模式下艇搀,因?yàn)橹挥幸粋€(gè)主節(jié)點(diǎn)可以寫(xiě)尿扯,而主,從節(jié)點(diǎn)都可以讀焰雕,所以通常主節(jié)點(diǎn)負(fù)責(zé)寫(xiě)衷笋,從節(jié)點(diǎn)負(fù)責(zé)讀。
但是矩屁,當(dāng)唯一的master掛了以后辟宗,雖然這樣并不影響slave的讀,但redis也不再提供寫(xiě)服務(wù)档插,需要將master重啟后慢蜓,redis才重新對(duì)外提供寫(xiě)服務(wù)。
2郭膛,Sentinel模式
sentinel模式是建立在主從模式的基礎(chǔ)上晨抡,避免單個(gè)master掛了以后,redis不能提供寫(xiě)服務(wù)。因?yàn)閺墓?jié)點(diǎn)上備份了主節(jié)點(diǎn)的所有數(shù)據(jù)耘柱,那么當(dāng)master掛了以后如捅,sentinel會(huì)在slave中選擇一個(gè)做為master,并修改它們的配置文件调煎,其他slave的配置文件也會(huì)被修改镜遣,比如slaveof屬性會(huì)指向新的master,比如之前配置的密碼士袄。此時(shí)悲关,客戶(hù)端就不是直接連接Redis,而是連接sentinel的ip和port娄柳,由sentinel來(lái)提供具體Redis服務(wù)寓辱。
把之前掛了的master重新啟動(dòng)后,它將不再是master而是做為slave接收新的master的同步數(shù)據(jù)赤拒。
3秫筏,Cluster模式
Cluster模式是建立在Sentinel模式的基礎(chǔ)上的,當(dāng)數(shù)據(jù)多到需要?jiǎng)討B(tài)擴(kuò)容的時(shí)候挎挖,前面兩種就不行了这敬,需要對(duì)數(shù)據(jù)進(jìn)行分片,根據(jù)一定的規(guī)則把redis數(shù)據(jù)分配到多臺(tái)機(jī)器蕉朵。
該模式就支持動(dòng)態(tài)擴(kuò)容崔涂,可以在線增加或刪除節(jié)點(diǎn),而且客戶(hù)端可以連接任何一個(gè)主節(jié)點(diǎn)進(jìn)行讀寫(xiě)墓造,不過(guò)此時(shí)的從節(jié)點(diǎn)僅僅只是備份的作用堪伍。至于為何能做到動(dòng)態(tài)擴(kuò)容,主要是因?yàn)镽edis 集群沒(méi)有使用一致性hash, 而是使用的哈希槽觅闽。Redis 集群會(huì)有16384個(gè)哈希槽帝雇,每個(gè)key通過(guò)CRC16校驗(yàn)后對(duì)16384取模來(lái)決定放置哪個(gè)槽,而集群的每個(gè)節(jié)點(diǎn)負(fù)責(zé)一部分hash槽蛉拙。
那么這樣就很容易添加或者刪除節(jié)點(diǎn)尸闸, 比如如果我想新添加個(gè)新節(jié)點(diǎn), 我只需要從已有的節(jié)點(diǎn)中得部分槽到過(guò)來(lái)孕锄;如果我想移除某個(gè)節(jié)點(diǎn)吮廉,就只需要將該節(jié)點(diǎn)的槽移到其它節(jié)點(diǎn)上,然后將沒(méi)有任何槽的A節(jié)點(diǎn)從集群中移除即可畸肆。由于從一個(gè)節(jié)點(diǎn)將哈希槽移動(dòng)到另一個(gè)節(jié)點(diǎn)并不會(huì)停止服務(wù)宦芦,所以無(wú)論添加刪除或者改變某個(gè)節(jié)點(diǎn)的哈希槽的數(shù)量都不會(huì)造成集群不可用的狀態(tài)。
需要注意的是轴脐,該模式下不支持同時(shí)處理多個(gè)key(如MSET/MGET)调卑,因?yàn)閞edis需要把key均勻分布在各個(gè)節(jié)點(diǎn)上抡砂,并發(fā)量很高的情況下同時(shí)創(chuàng)建key-value會(huì)降低性能并導(dǎo)致不可預(yù)測(cè)的行為。
二恬涧,搭建集群
這里就直接搭建較為復(fù)雜的Cluster模式集群注益,也是企業(yè)級(jí)開(kāi)發(fā)過(guò)程中使用最多的。
1溯捆,準(zhǔn)備工作
Linux可以連接外網(wǎng)丑搔,有wget(用于在線下載redis),系統(tǒng)安裝好gcc環(huán)境提揍,(不然編譯redis會(huì)報(bào)錯(cuò))啤月。
2,下載劳跃、解壓顽冶、移到指定目錄,編譯Redis
wget http://download.redis.io/releases/redis-5.0.4.tar.gz
tar xzf redis-5.0.4.tar.gz
mv redis-5.0.4 /usr/local/redis
cd /usr/local/redis/redis-5.0.4
make
make install
安裝完成售碳,在/usr/local/bin/
目錄下就會(huì)看見(jiàn)
3,建redis各節(jié)點(diǎn)目錄
mkdir /usr/local/redis-cluster
cd /usr/local/redis-cluster
mkdir -p 9001/data 9002/data 9003/data 9004/data 9005/data 9006/data
mkdir bin
最終目錄結(jié)構(gòu)如下
4绞呈,redis集群的運(yùn)行腳本
把之前安裝好的redis的src目錄下運(yùn)行腳本拷貝過(guò)來(lái)贸人,每個(gè)redis版本的運(yùn)行腳本有細(xì)微差異,請(qǐng)以你自己的版本為準(zhǔn)佃声,就是下圖綠色部分艺智。
cd /usr/local/redis/redis-5.0.4/src
cp mkreleasehdr.sh redis-benchmark redis-check-aof redis-check-rdb redis-cli redis-sentinel redis-server redis-trib.rb /usr/local/redis-cluster/bin
最終效果如下圖所示
5,批量復(fù)制redis實(shí)例
cp /usr/local/redis/redis-5.0.4/* /usr/local/redis-cluster/9001
cp /usr/local/redis/redis-5.0.4/* /usr/local/redis-cluster/9002
cp /usr/local/redis/redis-5.0.4/* /usr/local/redis-cluster/9003
cp /usr/local/redis/redis-5.0.4/* /usr/local/redis-cluster/9004
cp /usr/local/redis/redis-5.0.4/* /usr/local/redis-cluster/9005
cp /usr/local/redis/redis-5.0.4/* /usr/local/redis-cluster/9006
最終效果圖如下所示
6圾亏,逐個(gè)修改redis配置
以 9001 的為例子十拣,其余五個(gè)類(lèi)似。
cd /usr/local/redis-cluster/9001
vi redis.conf
打開(kāi)配置文件志鹃,按
i
進(jìn)入編輯模式夭问,按照出現(xiàn)的順序,主要需要修改的地方是
- bind 192.168.119.128(綁定當(dāng)前電腦的 IP曹铃,這是我虛擬機(jī)的缰趋,你綁定成你虛擬機(jī)的ip)
- port 9001(因?yàn)槲疫@是一臺(tái)機(jī)器運(yùn)行6個(gè)redis實(shí)例,所以要啟動(dòng)6個(gè)實(shí)例陕见,得為它配置6個(gè)不同的端口秘血,若你是6臺(tái)機(jī)器,默認(rèn)的端口就行评甜,無(wú)需更改)
- daemonize yes(這是設(shè)置是否后臺(tái)啟動(dòng) Redis灰粮,默認(rèn) no 告希,但是生產(chǎn)環(huán)境肯定要默認(rèn)就開(kāi)啟 Redis锤躁,所以這里設(shè)置為 yes 。)
- pidfile /var/run/redis_9001.pid(_9001這個(gè)一定要和第一個(gè)配置的端口一樣)
- dir /usr/local/redis-cluster/9001/data/(數(shù)據(jù)文件存放位置绰疤,我換成指定目錄下存放)
- appendonly yes
- cluster-enabled yes(啟動(dòng)集群模式)
- cluster-config-file nodes9001.conf(9001這個(gè)也要和之前的端口對(duì)應(yīng))
- cluster-node-timeout 15000(超時(shí)時(shí)間)
完成以上修改,Esc退出編輯模式蓖乘,輸入:wq
保存并退出锤悄。 類(lèi)似同樣的操作操作再來(lái)五次。
若是對(duì)redis的配置文件有興趣嘉抒,我在學(xué)習(xí)的過(guò)程中找到個(gè)詳細(xì)的翻譯版零聚,可點(diǎn)擊鏈接進(jìn)去學(xué)習(xí)。
7些侍,逐個(gè)啟動(dòng)redis節(jié)點(diǎn)
cd /usr/local/redis-cluster
/usr/local/bin/redis-server /usr/local/redis-cluster/9001/redis.conf
/usr/local/bin/redis-server /usr/local/redis-cluster/9002/redis.conf
/usr/local/bin/redis-server /usr/local/redis-cluster/9003/redis.conf
/usr/local/bin/redis-server /usr/local/redis-cluster/9004/redis.conf
/usr/local/bin/redis-server /usr/local/redis-cluster/9005/redis.conf
/usr/local/bin/redis-server /usr/local/redis-cluster/9006/redis.conf
運(yùn)行效果如圖所示
現(xiàn)在檢查一下是否成功開(kāi)啟隶症,如下圖所示,都開(kāi)啟成功岗宣。
ps -el | grep redis
8蚂会,搭建集群
此時(shí)的節(jié)點(diǎn)雖然都啟動(dòng)成功了,但他們還不在一個(gè)集群里面耗式,不能互相發(fā)現(xiàn)胁住,測(cè)試會(huì)報(bào)錯(cuò):(error) CLUSTERDOWN Hash slot not served
。
/usr/local/redis-cluster/bin/redis-cli -h 192.168.119.128 -p 9001
keys *
set name mafly
如下圖所示
解決報(bào)錯(cuò)刊咳,如果你是redis5.0以前的彪见,你需要安裝集群所需的ruby相關(guān)依賴(lài)
yum install ruby
yum install rubygems
cd /usr/local/redis-cluster/
gem install redis
這步若安裝報(bào)錯(cuò),請(qǐng)查看Could not find a valid gem 'redis'
如果你是redis5.0及之后的娱挨,無(wú)需安裝ruby依賴(lài)余指,redis安裝目錄里內(nèi)置了集群命令行工具 redis-trib ,它是一個(gè) Ruby 程序跷坝, 這個(gè)程序通過(guò)向?qū)嵗l(fā)送特殊命令來(lái)完成創(chuàng)建新集群酵镜, 檢查集群, 或者對(duì)集群進(jìn)行重新分片工作柴钻。
redis-cli --cluster create 192.168.119.128:9001 192.168.119.128:9002 192.168.119.128:9003 192.168.119.128:9004 192.168.119.128:9005 192.168.119.128:9006 --cluster-replicas 1
--cluster-replicas 1 這個(gè)指的是從機(jī)的數(shù)量淮韭,表示我們希望為集群中的每個(gè)主節(jié)點(diǎn)創(chuàng)建一個(gè)從節(jié)點(diǎn)。
紅色選框是給三個(gè)主節(jié)點(diǎn)分配的共16384個(gè)槽點(diǎn)贴届。
黃色選框是主從節(jié)點(diǎn)的分配情況缸濒。
藍(lán)色選框是各個(gè)節(jié)點(diǎn)的詳情。
9粱腻,測(cè)試
現(xiàn)在通過(guò)客戶(hù)端命令連接上庇配,通過(guò)集群命令看一下?tīng)顟B(tài)和節(jié)點(diǎn)信息等
/usr/local/redis-cluster/bin/redis-cli -c -h 192.168.119.128 -p 9001
cluster info
cluster nodes
效果圖如下,集群搭建成功绍些。
現(xiàn)在往9001這個(gè)主節(jié)點(diǎn)寫(xiě)入一條信息捞慌,我們可以在9002這個(gè)主節(jié)點(diǎn)取到信息,集群間各個(gè)節(jié)點(diǎn)可以通信柬批。
現(xiàn)在往9001這個(gè)主節(jié)點(diǎn)寫(xiě)入一條信息啸澡,我們可以在9002這個(gè)主節(jié)點(diǎn)取到信息袖订,集群間各個(gè)節(jié)點(diǎn)可以通信。
set name lgx
get name
三嗅虏,故障轉(zhuǎn)移
1洛姑,故障轉(zhuǎn)移機(jī)制詳解
集群中的節(jié)點(diǎn)會(huì)向其它節(jié)點(diǎn)發(fā)送PING消息(該P(yáng)ING消息會(huì)帶著當(dāng)前集群和節(jié)點(diǎn)的信息),如果在規(guī)定時(shí)間內(nèi)皮服,沒(méi)有收到對(duì)應(yīng)的PONG消息楞艾,就把此節(jié)點(diǎn)標(biāo)記為疑似下線。
當(dāng)被分配了slot槽位的主節(jié)點(diǎn)中有超過(guò)一半的節(jié)點(diǎn)都認(rèn)為此節(jié)點(diǎn)疑似下線(就是其它節(jié)點(diǎn)以更高的頻次龄广,更頻繁的與該節(jié)點(diǎn)PING-PONG)硫眯,那么該節(jié)點(diǎn)就真的下線。
其它節(jié)點(diǎn)收到某節(jié)點(diǎn)已經(jīng)下線的廣播后择同,把自己內(nèi)部的集群維護(hù)信息也修改為該節(jié)點(diǎn)已事實(shí)下線两入。
節(jié)點(diǎn)資格審查:然后對(duì)從節(jié)點(diǎn)進(jìn)行資格審查,每個(gè)從節(jié)點(diǎn)檢查最后與主節(jié)點(diǎn)的斷線時(shí)間敲才,如果該值超過(guò)配置文件的設(shè)置裹纳,那么取消該從節(jié)點(diǎn)的資格。
準(zhǔn)備選舉時(shí)間:這里使用了延遲觸發(fā)機(jī)制紧武,主要是給那些延遲低的更高的優(yōu)先級(jí)痊夭,延遲低的讓它提前參與被選舉,延遲高的讓它靠后參與被選舉脏里。(延遲的高低是依據(jù)之前與主節(jié)點(diǎn)的最后斷線時(shí)間確定的)
選舉投票:當(dāng)從節(jié)點(diǎn)獲取選舉資格后,會(huì)向其他帶有slot槽位的主節(jié)點(diǎn)發(fā)起選舉請(qǐng)求虹曙,由它們進(jìn)行投票迫横,優(yōu)先級(jí)越高的從節(jié)點(diǎn)就越有可能成為主節(jié)點(diǎn),當(dāng)從節(jié)點(diǎn)獲取的票數(shù)到達(dá)一定數(shù)值時(shí)(如集群內(nèi)有N個(gè)主節(jié)點(diǎn)酝碳,那么只要有一個(gè)從節(jié)點(diǎn)獲得了N/2+1的選票即認(rèn)為勝出)矾踱,就會(huì)替換成為主節(jié)點(diǎn)。
替換主節(jié)點(diǎn):被選舉出來(lái)的從節(jié)點(diǎn)會(huì)執(zhí)行slaveof no one把自己的狀態(tài)從slave變成master疏哗,然后執(zhí)行clusterDelSlot操作撤銷(xiāo)故障主節(jié)點(diǎn)負(fù)責(zé)的槽呛讲,并執(zhí)行 clusterAddSlot把這些槽分配給自己,之后向集群廣播自己的pong消息返奉,通知集群內(nèi)所有的節(jié)點(diǎn)贝搁,當(dāng)前從節(jié)點(diǎn)已變?yōu)橹鞴?jié)點(diǎn)。
接管相關(guān)操作:新的主節(jié)點(diǎn)接管了之前故障的主節(jié)點(diǎn)的槽信息芽偏,接收和處理與自己槽位相關(guān)的命令請(qǐng)求雷逆。
2,故障轉(zhuǎn)移測(cè)試
這是之前集群中具體節(jié)點(diǎn)的情況污尉,我簡(jiǎn)化成如下膀哲,可以向上回看圖片中的集群信息往产。
這里關(guān)閉該9001端口的進(jìn)程,即模擬該主節(jié)點(diǎn)掛掉某宪。
netstat -tunlp | grep 9001
kill 15705
登錄掛掉的redis節(jié)點(diǎn)仿村,會(huì)被拒絕服務(wù),通過(guò)還在正常運(yùn)行的某個(gè)主節(jié)點(diǎn)進(jìn)入兴喂,然后再次查看集群中的信息
/usr/local/redis-cluster/bin/redis-cli -c -h 192.168.119.128 -p 9001
/usr/local/redis-cluster/bin/redis-cli -c -h 192.168.119.128 -p 9002
cluster nodes
簡(jiǎn)而言之蔼囊,就是之前的集群信息變成了如下所示
現(xiàn)在,我重啟剛才掛掉的主節(jié)點(diǎn)瞻想,重新查看集群內(nèi)部的節(jié)點(diǎn)情況压真,具體情況如下圖所示。
cd /usr/local/redis-cluster/
/usr/local/bin/redis-server /usr/local/redis-cluster/9001/redis.conf
/usr/local/redis-cluster/bin/redis-cli -c -h 192.168.119.128 -p 9002
cluster nodes
簡(jiǎn)而言之蘑险,現(xiàn)在集群內(nèi)的節(jié)點(diǎn)情況如下