一、復(fù)制
1. 主從復(fù)制
a,方式一者吁、新增 redis6380.conf, 加入 slaveof 192.168.42.111 6379, 在 6379 啟動完后再啟 6380伯襟,完成配置苍狰;
b,方式二沸呐、redis-server --slaveof 192.168.42.111 6379
c,查看狀態(tài):info replication
d,斷開主從復(fù)制:在 slave 節(jié)點(diǎn)断部,執(zhí)行 6380:>slaveof no one
e,斷開后再變成主從復(fù)制:6380:> slaveof 192.168.42.111 6379
f,數(shù)據(jù)較重要的節(jié)點(diǎn)优训,主從復(fù)制時使用密碼驗證: requirepass
g,從節(jié)點(diǎn)建議用只讀模式 slave-read-only=yes, 若從節(jié)點(diǎn)修改數(shù)據(jù)朵你,主從數(shù)據(jù)不一致
h,傳輸延遲:主從一般部署在不同機(jī)器上,復(fù)制時存在網(wǎng)絡(luò)延時問題揣非,redis 提供repl-disable-tcp-nodelay 參數(shù)決定是否關(guān)閉 TCP_NODELAY,默認(rèn)為關(guān)閉抡医;
參數(shù)關(guān)閉時:無論大小都會及時發(fā)布到從節(jié)點(diǎn),占帶寬早敬,適用于主從網(wǎng)絡(luò)好的場景忌傻;
參數(shù)啟用時:主節(jié)點(diǎn)合并所有數(shù)據(jù)成 TCP 包節(jié)省帶寬,默認(rèn)為 40 毫秒發(fā)一次搞监,取決于內(nèi)核水孩,主從的同步延遲 40 毫秒,適用于網(wǎng)絡(luò)環(huán)境復(fù)雜或帶寬緊張琐驴,如跨機(jī)房
2.主從拓?fù)洌褐С謫螌踊蚨鄬?/h4>
A,一主一從:用于主節(jié)點(diǎn)故障轉(zhuǎn)移從節(jié)點(diǎn)俘种,當(dāng)主節(jié)點(diǎn)的“寫”命令并發(fā)高且需要持久化,可以只在從節(jié)點(diǎn)開啟 AOF(主節(jié)點(diǎn)不需要)绝淡,這樣即保證了數(shù)據(jù)的安全性宙刘,也避免持久化對主節(jié)點(diǎn)的影響;
B, 一主多從:針對“讀”較多的場景牢酵,“讀”由多個從節(jié)點(diǎn)來分擔(dān)悬包,但節(jié)點(diǎn)越多,主節(jié)點(diǎn)同步到多節(jié)點(diǎn)的次數(shù)也越多馍乙,影響帶寬布近,也加重主節(jié)點(diǎn)的穩(wěn)定;
C,樹狀主從:一主多從的缺點(diǎn)(主節(jié)點(diǎn)推送次數(shù)多壓力大)可用些方案解決潘拨,主節(jié)點(diǎn)只推送一次數(shù)據(jù)到從節(jié)點(diǎn) 1吊输,再由從節(jié)點(diǎn) 2 推送到 1,減輕主節(jié)點(diǎn)推送的壓力铁追。
3. 復(fù)制原理
執(zhí)行 slave master port 后季蚂,與主節(jié)點(diǎn)連接,同步主節(jié)點(diǎn)的數(shù)據(jù),6380:>info replication:查看主從及同步信息
4.數(shù)據(jù)同步
redis 2.8 版本以上使用 psync 命令完成同步,過程分“全量”與“部分”復(fù)制 扭屁;
全量復(fù)制:一般用于初次復(fù)制場景(第一次建立 SLAVE 后全量)
部分復(fù)制:網(wǎng)絡(luò)出現(xiàn)問題算谈,從節(jié)占再次連主時,主節(jié)點(diǎn)補(bǔ)發(fā)缺少的數(shù)據(jù)料滥,每次數(shù)據(jù)增加同步
心跳:主從有長連接心跳然眼,主節(jié)點(diǎn)默認(rèn)每 10S 向從節(jié)點(diǎn)發(fā) ping 命令,repl-ping-slave-period 控制發(fā)送頻率 葵腹。
二高每、哨兵機(jī)制
1,為什么要講哨兵機(jī)制践宴?
A鲸匿,我們學(xué)習(xí)了 redis 的主從復(fù)制,但如果說主節(jié)點(diǎn)出現(xiàn)問題不能提供服務(wù)阻肩,需要人工重新把從節(jié)點(diǎn)設(shè)為主節(jié)點(diǎn)带欢,還要通知我們的應(yīng)用程序更新了主節(jié)點(diǎn)的地址,這種處理方式不是科學(xué)的烤惊,耗時費(fèi)事
B乔煞,同時主節(jié)點(diǎn)的寫能力是單機(jī)的,能力能限
C柒室,而且主節(jié)點(diǎn)是單機(jī)的渡贾,存儲能力也有限其中 2,3 的問題在后面 redis 集群課會講伦泥,第 1 個問題我們用哨兵機(jī)制來解決
2,主從故障如何故障轉(zhuǎn)移(不滿足高可用):
A剥啤,主節(jié)點(diǎn)(master)故障,從節(jié)點(diǎn) slave-1 端執(zhí)行 slaveof no one 后變成新主節(jié)點(diǎn)
B不脯,其它的節(jié)點(diǎn)成為新主節(jié)點(diǎn)的從節(jié)點(diǎn)府怯,并從新節(jié)點(diǎn)復(fù)制數(shù)據(jù)
3,哨兵機(jī)制(sentinel)的高可用:
A防楷,原理:當(dāng)主節(jié)點(diǎn)出現(xiàn)故障時牺丙,由 redis sentinel 自動完成故障發(fā)現(xiàn)和轉(zhuǎn)移,并通知應(yīng)用方复局,實(shí)現(xiàn)高可用性冲簿。
其實(shí)整個過程只需要一個哨兵節(jié)點(diǎn)來完成,首先使用 Raft 算法(感興趣的可以查一下亿昏,其實(shí)就是個選舉算法)實(shí)現(xiàn)選舉機(jī)制峦剔,選出一個哨兵節(jié)點(diǎn)來完成轉(zhuǎn)移和通知哨兵,有三個定時監(jiān)控任務(wù)完成對各節(jié)點(diǎn)的發(fā)現(xiàn)和監(jiān)控:
任務(wù) 1角钩,每個哨兵節(jié)點(diǎn)每 10 秒會向主節(jié)點(diǎn)和從節(jié)點(diǎn)發(fā)送 info 命令獲取最拓?fù)浣Y(jié)構(gòu)圖吝沫,哨兵配置時只要配置對主節(jié)點(diǎn)的監(jiān)控即可呻澜,通過向主節(jié)點(diǎn)發(fā)送 info,獲取從節(jié)點(diǎn)的信息惨险,并當(dāng)有新的從節(jié)點(diǎn)加入時可以馬上感知到 羹幸;
任務(wù) 2,每個哨兵節(jié)點(diǎn)每隔 2 秒會向 redis 數(shù)據(jù)節(jié)點(diǎn)的指定頻道上發(fā)送該哨兵節(jié)點(diǎn)對于主節(jié)點(diǎn)的判斷以及當(dāng)前哨兵節(jié)點(diǎn)的信息辫愉,同時每個哨兵節(jié)點(diǎn)也會訂閱該頻道栅受,來了解其它哨兵節(jié)點(diǎn)的信息及對主節(jié)點(diǎn)的判斷,其實(shí)就是通過消息 publish 和 subscribe 來完成的恭朗;
任務(wù) 3屏镊,每隔 1 秒每個哨兵會向主節(jié)點(diǎn)、從節(jié)點(diǎn)及其余哨兵節(jié)點(diǎn)發(fā)送一次 ping 命令做一次心跳檢測痰腮,這個也是哨兵用來判斷節(jié)點(diǎn)是否正常的重要依據(jù)闸衫;
主觀下線和客觀下線:
主觀下線:剛我知道知道哨兵節(jié)點(diǎn)每隔 1 秒對主節(jié)點(diǎn)和從節(jié)點(diǎn)、其它哨兵節(jié)點(diǎn)發(fā)送 ping做心跳檢測诽嘉,當(dāng)這些心跳檢測時間超過 down-after-milliseconds 時,哨兵節(jié)點(diǎn)則認(rèn)為該節(jié)點(diǎn)錯誤或下線弟翘,這叫主觀下線虫腋;這可能會存在錯誤的判斷。
客觀下線:當(dāng)主觀下線的節(jié)點(diǎn)是主節(jié)點(diǎn)時稀余,此時該哨兵 3 節(jié)點(diǎn)會通過指令 sentinelis-masterdown-by-addr 尋求其它哨兵節(jié)點(diǎn)對主節(jié)點(diǎn)的判斷悦冀,當(dāng)超過 quorum(法定人數(shù))個數(shù),此時哨兵節(jié)點(diǎn)則認(rèn)為該主節(jié)點(diǎn)確實(shí)有問題睛琳,這樣就客觀下線了盒蟆,大部分哨兵節(jié)點(diǎn)都同意下線操作,也就說是客觀下線师骗。
領(lǐng)導(dǎo)者哨兵選舉流程:
a,每個在線的哨兵節(jié)點(diǎn)都可以成為領(lǐng)導(dǎo)者历等,當(dāng)它確認(rèn)(比如哨兵 3)主節(jié)點(diǎn)下線時,會向其它哨兵發(fā) is-master-down-by-addr 命令辟癌,征求判斷并要求將自己設(shè)置為領(lǐng)導(dǎo)者寒屯,由領(lǐng)導(dǎo)者處理故障轉(zhuǎn)移;
b,當(dāng)其它哨兵收到此命令時黍少,可以同意或者拒絕它成為領(lǐng)導(dǎo)者寡夹;
c,如果哨兵 3 發(fā)現(xiàn)自己在選舉的票數(shù)大于等于 num(sentinels)/2+1 時,將成為領(lǐng)導(dǎo)者厂置,如果沒有超過菩掏,繼續(xù)選舉…………
4,故障轉(zhuǎn)移機(jī)制
A昵济,由 Sentinel 節(jié)點(diǎn)定期監(jiān)控發(fā)現(xiàn)主節(jié)點(diǎn)是否出現(xiàn)了故障sentinel 會向 master 發(fā)送心跳 PING 來確認(rèn) master 是否存活智绸,如果 master 在“一定時間范圍”內(nèi)不回應(yīng) PONG 或者是回復(fù)了一個錯誤消息野揪,那么這個 sentinel 會主觀地(單方面地)認(rèn)為這個 master 已經(jīng)不可用了;
B传于,當(dāng)主節(jié)點(diǎn)出現(xiàn)故障囱挑,此時 3 個 Sentinel 節(jié)點(diǎn)共同選舉了 Sentinel3 節(jié)點(diǎn)為領(lǐng)導(dǎo),負(fù)載處理主節(jié)點(diǎn)的故障轉(zhuǎn)移沼溜;
C平挑,由 Sentinel3 領(lǐng)導(dǎo)者節(jié)點(diǎn)執(zhí)行故障轉(zhuǎn)移,過程和主從復(fù)制一樣系草,但是自動執(zhí)行通熄;
流程: 1,將 slave-1 脫離原從節(jié)點(diǎn)找都,升級主節(jié)點(diǎn)
2唇辨,將從節(jié)點(diǎn) slave-2 指向新的主節(jié)點(diǎn)
3,通知客戶端主節(jié)點(diǎn)已更換
4能耻,將原主節(jié)點(diǎn)(oldMaster)變成從節(jié)點(diǎn)赏枚,指向新的主節(jié)點(diǎn)
D,故障轉(zhuǎn)移后的 redis sentinel 的拓?fù)浣Y(jié)構(gòu)圖晓猛。
5饿幅,哨兵機(jī)制-故障轉(zhuǎn)移詳細(xì)流程
A,過濾掉不健康的(下線或斷線)戒职,沒有回復(fù)過哨兵 ping 響應(yīng)的從節(jié)點(diǎn)
B栗恩,選擇 slave-priority 從節(jié)點(diǎn)優(yōu)先級最高(redis.conf)
C,選擇復(fù)制偏移量最大洪燥,指復(fù)制最完整的從節(jié)點(diǎn)
6磕秤,如何安裝和部署 Reids Sentinel?
我們以 3 個 Sentinel 節(jié)點(diǎn)、2 個從節(jié)點(diǎn)捧韵、1 個主節(jié)點(diǎn)為例進(jìn)行安裝部署市咆。
1,前提:先搭好一主兩從 redis 的主從復(fù)制纫版,和之前復(fù)制搭建一樣床绪,搭建方式如下:
A 主節(jié)點(diǎn) 6379 節(jié)點(diǎn)(/usr/local/bin/conf/redis6379.conf):修改 requirepass 12345678,注釋掉#bind 127.0.0.1
B 從節(jié)點(diǎn) redis6380.conf 和 redis6381.conf:修改 requirepass 12345678 ,注釋掉#bind 127.0.0.1, 加上 masterauth 12345678 ,加上 slaveof 127.0.0.1 6379
注意:當(dāng)主從起來后其弊,主節(jié)點(diǎn)可讀寫癞己,從節(jié)點(diǎn)只可讀不可寫
2,redis sentinel 哨兵機(jī)制核心配置(也是 3 個節(jié)點(diǎn)):
/usr/local/bin/conf/sentinel_26379.conf
/usr/local/bin/conf/sentinel_26380.conf
/usr/local/bin/conf/sentinel_26381.conf
將三個文件的端口改成: 26379? ? 26380? ? ?26381
然后:sentinel monitor mymaster 190.168.1.111 6379 2? ? ?//監(jiān)聽主節(jié)點(diǎn) 6379
sentinel auth-pass mymaster 12345678? ? ? ? ? ? ?//連接主節(jié)點(diǎn)時的密碼三個配置除端口外梭伐,其它一樣痹雅。
3,哨兵其它的配置:只要修改每個 sentinel.conf 的這段配置即可:sentinel monitor mymaster 192.168.1.10 6379 2? ? ? ? ? ? ? ? //監(jiān)控主節(jié)點(diǎn)的 IP 地址端口糊识,sentinel 監(jiān)控的 master 的名字叫做 mymaster
2 代表绩社,當(dāng)集群中有 2 個 sentinel 認(rèn)為 master 死了時摔蓝,才能真正認(rèn)為該 master已經(jīng)不可用了;
sentinel auth-pass mymaster 12345678? ? ? ? ? ? ? //sentinel 連主節(jié)點(diǎn)的密碼
sentinel config-epoch mymaster 2? ? ? ? ? ?//故障轉(zhuǎn)移時最多可以有 2 從節(jié)點(diǎn)同時對新主節(jié)點(diǎn)進(jìn)行數(shù)據(jù)同步
sentinel leader-epoch mymaster 2
sentinel failover-timeout mymasterA 180000? ? //故障轉(zhuǎn)移超時時間 180s愉耙,
a,如果轉(zhuǎn)移超時失敗贮尉,下次轉(zhuǎn)移時時間為之前的 2 倍;
b,從節(jié)點(diǎn)變主節(jié)點(diǎn)時朴沿,從節(jié)點(diǎn)執(zhí)行 slaveof no one 命令一直失敗的話猜谚,當(dāng)時間超過 180S 時,則故障轉(zhuǎn)移失敹脑魏铅;
c,從節(jié)點(diǎn)復(fù)制新主節(jié)點(diǎn)時間超過 180S 轉(zhuǎn)移失敗。
sentinel down-after-milliseconds mymasterA 300000? ? ? ?//sentinel 節(jié)點(diǎn)定期向主節(jié)點(diǎn)ping 命令坚芜,當(dāng)超過了 300S 時間后沒有回復(fù)览芳,可能就認(rèn)定為此主節(jié)點(diǎn)出現(xiàn)故障了……
sentinel parallel-syncs mymasterA 1? ? ? ? ? ? ? //故障轉(zhuǎn)移后,1 代表每個從節(jié)點(diǎn)按順序排隊一個一個復(fù)制主節(jié)點(diǎn)數(shù)據(jù)鸿竖,如果為 3沧竟,指 3 個從節(jié)點(diǎn)同時并發(fā)復(fù)制主節(jié)點(diǎn)數(shù)據(jù),不會影響阻塞缚忧,但存在網(wǎng)絡(luò)和 IO 開銷
4屯仗,啟動 sentinel 服務(wù):
./redis-sentinel conf/sentinel_26379.conf &
./redis-sentinel conf/sentinel_26380.conf &
./redis-sentinel conf/sentinel_26381.conf &
關(guān)閉:./redis-cli -h 192.168.42.111 -p 26379 shutdown
5,測試:kill -9 6379 殺掉 6379 的 redis 服務(wù)
看日志是分配 6380 還是 6381 做為主節(jié)點(diǎn)搔谴,當(dāng) 6379 服務(wù)再啟動時,已變成從節(jié)點(diǎn)桩撮;
假設(shè) 6380 升級為主節(jié)點(diǎn):進(jìn)入 6380>info replication? ? ?可以看到 role:master敦第;
打開 sentinel_26379.conf 等三個配置,sentinel monitor mymaster 127.0.0.1 6380 2 店量;
打開 redis6379.conf 等三個配置, slaveof 192.168.42.111 6380,也變成了 6380 芜果;
注意:生產(chǎn)環(huán)境建議讓 redis Sentinel 部署到不同的物理機(jī)上。
重 要: sentinel monitor mymaster 192.168.42.111 6379 2? ? ? ? ? ? //切 記 將 IP 不 要 寫 成127.0.0.1融师,不然使用 JedisSentinelPool 取 jedis 連接的時候會變成取 127.0.0.1 6379 的錯誤地址
注:我們稍后要啟動四個 redis 實(shí)例右钾,其中端口為 6379 的 redis 設(shè)為 master,其他兩個設(shè)為 slave 旱爆。所以 mymaster 后跟的是 master 的 ip 和端口舀射,最后一個’2’代表只要有 2 個 sentinel 認(rèn)為 master 下線,就認(rèn)為該 master 客觀下線怀伦,選舉產(chǎn)生新的 master脆烟。
通常最后一個參數(shù)不能多于啟動的 sentinel 實(shí)例數(shù)。
哨兵 sentinel 個數(shù)為奇數(shù)房待,選舉嘛邢羔,奇數(shù)哨兵個才能選舉成功驼抹,一般建議 3 個。
6拜鹤,RedisSentinel 如何監(jiān)控 2 個 redis 主節(jié)點(diǎn)呢框冀?
sentinel monitor mymasterB 192.168.1.20 6379 2 ……與上面一樣…………。
7敏簿,部署建議:
a明也,sentinel 節(jié)點(diǎn)應(yīng)部署在多臺物理機(jī)(線上環(huán)境)
b,至少三個且奇數(shù)個 sentinel 節(jié)點(diǎn)
c极谊,通過以上我們知道诡右,3 個 sentinel 可同時監(jiān)控一個主節(jié)點(diǎn)或多個主節(jié)點(diǎn)監(jiān)聽 N 個主節(jié)點(diǎn)較多時,如果 sentinel 出現(xiàn)異常轻猖,會對多個主節(jié)點(diǎn)有影響帆吻,同時還會造成 sentinel 節(jié)點(diǎn)產(chǎn)生過多的網(wǎng)絡(luò)連接,一般線上建議還是咙边, 3個sentinel 監(jiān)聽一個主節(jié)點(diǎn)
8猜煮,sentinel 哨兵的 API
命令:redis-cli -p 26379 //進(jìn)入哨兵的命令模式,使用 redis-cli 進(jìn)入败许;
26379>sentinel masters 或 sentinel master mymaster //查看 redis 主節(jié)點(diǎn)相關(guān)信息
26379>sentinel slaves mymaster //查看從節(jié)點(diǎn)狀態(tài)與相關(guān)信息
26379>sentinel sentinels mymaster //查 sentinel 節(jié)點(diǎn)集合信息(不包括當(dāng)前 26379)
26379>sentinel failover mymaster //對主節(jié)點(diǎn)強(qiáng)制故障轉(zhuǎn)移王带,沒和其它節(jié)點(diǎn)協(xié)商
9,客戶端連接(redis-sentinel 例子工程)
遠(yuǎn)程客戶端連接時市殷,要打開 protected-mode no 愕撰;
./redis-cli -p 26380 shutdown? ? ? //關(guān)閉
在使用工程 redis-sentinel,調(diào)用 jedis 查詢的流程如下:
1醋寝,將三個 sentinel 的 IP 和地址加入 JedisSentinelPool
2搞挣,根據(jù) IP 和地址創(chuàng)建 JedisSentinelPool 池對象
3,在這個對象創(chuàng)建完后音羞,此時該對象已把 redis 的主節(jié)點(diǎn)
// ( 此 時 sentinel monitor mymaster 必 須 寫 成 192.168.42.111 6379 2 囱桨, 不 能 為127.0.0.1,不然查詢出來的主節(jié)點(diǎn)的 IP 在客戶端就變成了 127.0.0.1嗅绰,拿不到連接了)查詢出來了舍肠,當(dāng)客戶準(zhǔn)備發(fā)起查詢請求時,調(diào)用 pool.getResource()借用一個 jedis 對象窘面,內(nèi)容包括主節(jié)點(diǎn)的 IP 和端口翠语;
4,將得到 jedis 對象后财边,可執(zhí)行 jedis.get(“age”)指令了……啡专。
三、redis 集群
RedisCluster 是 redis 的分布式解決方案制圈,在 3.0 版本后推出的方案们童,有效地解決了Redis 分布式的需求畔况,當(dāng)遇到單機(jī)內(nèi)存、并發(fā)等瓶頸時慧库,可使用此方案來解決這些問題.
8.1 分布式數(shù)據(jù)庫概念
1跷跪,分布式數(shù)據(jù)庫把整個數(shù)據(jù)按分區(qū)規(guī)則映射到多個節(jié)點(diǎn),即把數(shù)據(jù)劃分到多個節(jié)點(diǎn)上齐板,每個節(jié)點(diǎn)負(fù)責(zé)整體數(shù)據(jù)的一個子集;比如我們庫有 900 條用戶數(shù)據(jù)吵瞻,有 3 個 redis 節(jié)點(diǎn),將 900 條分成 3 份甘磨,分別存入到 3 個 redis 節(jié)點(diǎn);
2橡羞,分區(qū)規(guī)則:
常見的分區(qū)規(guī)則哈希分區(qū)和順序分區(qū),redis 集群使用了哈希分區(qū)济舆,順序分區(qū)暫用不到卿泽,不做具體說明;
rediscluster 采用了哈希分區(qū)的“虛擬槽分區(qū)”方式(哈希分區(qū)分節(jié)點(diǎn)取余滋觉、一致性哈希分區(qū)和虛擬槽分區(qū))签夭,其它兩種也不做介紹,有興趣可以百度了解一下椎侠。
3第租,虛擬槽分區(qū)(槽:slot)
RedisCluster 采用此分區(qū),所有的鍵根據(jù)哈希函數(shù)(CRC16[key]&16383)映射到 0 -16383 槽內(nèi)我纪,共 16384 個槽位慎宾,每個節(jié)點(diǎn)維護(hù)部分槽及槽所映射的鍵值數(shù)據(jù);
哈希函數(shù): Hash()=CRC16[key]&16383? ? ? ? ?
槽與節(jié)點(diǎn)的關(guān)系如下:
redis 用虛擬槽分區(qū)原因:1,解耦數(shù)據(jù)與節(jié)點(diǎn)關(guān)系浅悉,節(jié)點(diǎn)自身維護(hù)槽映射關(guān)系璧诵,分布式存儲
4,redisCluster 的缺陷:
a仇冯,鍵的批量操作支持有限,比如 mset, mget族操,如果多個鍵映射在不同的槽苛坚,就不支持了
b,鍵事務(wù)支持有限色难,當(dāng)多個 key 分布在不同節(jié)點(diǎn)時無法使用事務(wù)泼舱,同一節(jié)點(diǎn)是支持事務(wù)
c,鍵是數(shù)據(jù)分區(qū)的最小粒度枷莉,不能將一個很大的鍵值對映射到不同的節(jié)點(diǎn)
d娇昙,不支持多數(shù)據(jù)庫,只有 0笤妙,select 0
e冒掌,復(fù)制結(jié)構(gòu)只支持單層結(jié)構(gòu)噪裕,不支持樹型結(jié)構(gòu)银还。
8.2 集群環(huán)境搭建
1伏嗜,在/usr/local/redis/clusterconf 目錄,
6389 為 6379 的從節(jié)點(diǎn)弄匕,6390 為 6380 的從節(jié)點(diǎn)佑吝,6391 為 6381 的從節(jié)點(diǎn)幽崩。
2田篇,分別修改 6379峦椰、 6380徒扶、 7381趣席、 6389兵志、 6390、 6391 配置文件宣肚;
port 6379? ? ? ? //節(jié)點(diǎn)端口
cluster-enabled yes? ? ? ? ?//開啟集群模式
cluster-node-timeout 15000? ? ? ? ? //節(jié)點(diǎn)超時時間(接收pong消息回復(fù)的時間)
cluster-config-file /usrlocalbin/cluster/data/nodes-6379.conf 集群內(nèi)部配置文件想罕,其它節(jié)點(diǎn)的配置和這個一致,改端口即可
3钉寝,配置完后弧呐,啟動 6 個 redis 服務(wù)
4,自動安裝模式:
在/usr/local 新建目錄:ruby
下載好ruby-2.3.1.tar.gz 和 redis-3.3.0.gem嵌纲,然后進(jìn)行解壓:tar -zxvf ruby-2.3.1.tar.gz俘枫。
a, cd ruby-2.3.1
b, ./configure -prefix=/usr/local/ruby
c, make && make install //過程會有點(diǎn)慢,大概 5-10 分鐘
d, 然后 gem install -l redis-3.3.0.gem //沒有 gem 需要安裝 yum install gem
e, 準(zhǔn) 備 好 6 個 節(jié) 點(diǎn) 逮走,( 注 意 不 要 設(shè) 置 requirepass ) , 將/usr/local/bin/clusterconf/data 的 config-file 刪 除 鸠蚪; 依 次 啟 動 6 個 節(jié)點(diǎn):./redis-server clusterconf/redis6379.conf ;
如果之前 redis 有數(shù)據(jù)存在师溅,flushall 清空茅信;(坑:不需要 cluster meet ..)
f, 進(jìn)入 cd /usr/local/bin, 執(zhí)行以下:1 代表從節(jié)點(diǎn)的個數(shù),
./redis-trib.rb create --replicas 1 192.168.0.111:6379 192.168.0.111:6380 192.168.0.111:6381 192.168.0.111:6389 192.168.0.111:6390 192.168.0.111:6391
主從分配墓臭,6379 是 6389 的從節(jié)點(diǎn)蘸鲸;
貌似只有主節(jié)點(diǎn)可讀寫,從節(jié)點(diǎn)不可以窿锉;主節(jié)點(diǎn)死后酌摇,從節(jié)點(diǎn)變成主節(jié)點(diǎn)。
e,集群健康檢測:
redis-trib.rb check 192.168.42.111:6379 (注:redis 先去注釋掉 requirepass嗡载,不然連不上)
如此出現(xiàn)了這個問題窑多,表示6379 的 5798 槽位號被打開了;
解決如下:
6379洼滚,6380埂息,6381 的有部分槽位被打開了,分別進(jìn)入這幾個節(jié)點(diǎn),執(zhí)行
6380:>cluster setslot 1180 stable
>cluster setslot 2998 stable
>cluster setslot 11212 stable
其它也一樣千康,分別執(zhí)行修復(fù)完后:
此時修復(fù)后的健康正常享幽;當(dāng)停掉 6379 后,過會 6389 變成主節(jié)點(diǎn)吧秕。
注意:使用客戶端工具查詢時要加-c琉闪,
./redis-cli -h 192.168.42.111 -p 6379 -c
mset aa bb cc dd,批設(shè)置對應(yīng)在不同的 solt 上,缺點(diǎn):
5,集群正常啟動后砸彬,在每個 redis.conf 里加上:
masterauth “12345678”
requiredpass “12345678”?
當(dāng)主節(jié)點(diǎn)下線時颠毙,從節(jié)點(diǎn)會變成主節(jié)點(diǎn),用戶和密碼是很有必要的砂碉,設(shè)置成一致蛀蜜。
6,這上面是一主一從,那能不能一主多從呢增蹭?
./redis-trib.rb create --replicas 2
192.168.42.111:6379 192.168.42.111:6380 192.168.42.111:6381
192.168.42.111:6479 192.168.42.111:6480 192.168.42.111:6481
192.168.42.111:6579 192.168.42.111:6580 192.168.42.111:6581
8.3 節(jié)點(diǎn)之間的通信
1滴某,節(jié)點(diǎn)之間采用 Gossip 協(xié)議進(jìn)行通信,Gossip 協(xié)議就是指節(jié)點(diǎn)彼此之間不斷通信交換信息滋迈;
當(dāng)主從角色變化或新增節(jié)點(diǎn)霎奢,彼此通過 ping/pong 進(jìn)行通信知道全部節(jié)點(diǎn)的最新狀態(tài)并達(dá)到集群同步。
2,Gossip 協(xié)議
Gossip 協(xié)議的主要職責(zé)就是信息交換饼灿,信息交換的載體就是節(jié)點(diǎn)之間彼此發(fā)送的 Gossip 消息幕侠,常用的 Gossip 消息有 ping 消息、pong 消息碍彭、meet 消息晤硕、fail 消息;
meet 消息:用于通知新節(jié)點(diǎn)加入庇忌,消息發(fā)送者通知接收者加入到當(dāng)前集群舞箍,meet消息通信完后,接收節(jié)點(diǎn)會加入到集群中皆疹,并進(jìn)行周期性 ping pong 交換疏橄;
ping 消息:集群內(nèi)交換最頻繁的消息,集群內(nèi)每個節(jié)點(diǎn)每秒向其它節(jié)點(diǎn)發(fā) ping 消息略就,用于檢測節(jié)點(diǎn)是在在線和狀態(tài)信息捎迫,ping 消息發(fā)送封裝自身節(jié)點(diǎn)和其他節(jié)點(diǎn)的狀態(tài)數(shù)據(jù);
pong 消息残制,當(dāng)接收到 ping meet 消息時,作為響應(yīng)消息返回給發(fā)送方掖疮,用來確認(rèn)正常通信初茶,pong 消息也封閉了自身狀態(tài)數(shù)據(jù);
fail 消息:當(dāng)節(jié)點(diǎn)判定集群內(nèi)的另一節(jié)點(diǎn)下線時,會向集群內(nèi)廣播一個 fail 消息恼布,后面會講到螺戳。……
3,消息解析流程
所有消息格式為:消息頭折汞、消息體倔幼,消息頭包含發(fā)送節(jié)點(diǎn)自身狀態(tài)數(shù)據(jù)(比如節(jié)點(diǎn)ID、槽映射爽待、節(jié)點(diǎn)角色损同、是否下線等),接收節(jié)點(diǎn)根據(jù)消息頭可以獲取到發(fā)送節(jié)點(diǎn)的相關(guān)數(shù)據(jù)鸟款。
消息解析流程:
4,選擇節(jié)點(diǎn)并發(fā)送 ping 消息:
Gossip 協(xié)議信息的交換機(jī)制具有天然的分布式特性膏燃,但 ping pong 發(fā)送的頻率很高,可以實(shí)時得到其它節(jié)點(diǎn)的狀態(tài)數(shù)據(jù)何什,但頻率高會加重帶寬和計算能力组哩,因此每次都會有目的性地選擇一些節(jié)點(diǎn); 但是節(jié)點(diǎn)選擇過少又會影響故障判斷的速度处渣,redis 集群的 Gossip 協(xié)議兼顧了這兩者的優(yōu)缺點(diǎn)伶贰,看下圖:
不難看出:節(jié)點(diǎn)選擇的流程可以看出消息交換成本主要體現(xiàn)在發(fā)送消息的節(jié)點(diǎn)數(shù)量和每個消息攜帶的數(shù)據(jù)量。
流程說明:
A罐栈,選擇發(fā)送消息的節(jié)點(diǎn)數(shù)量:集群內(nèi)每個節(jié)點(diǎn)維護(hù)定時任務(wù)默認(rèn)為每秒執(zhí)行 10次黍衙,每秒會隨機(jī)選取 5 個節(jié)點(diǎn),找出最久沒有通信的節(jié)點(diǎn)發(fā)送 ping 消息悠瞬,用來保證信息交換的隨機(jī)性们豌,每 100 毫秒都會掃描本地節(jié)點(diǎn)列表,如果發(fā)現(xiàn)節(jié)點(diǎn)最近一次接受 pong 消息的時間大于 cluster-node-timeout/2 則立刻發(fā)送 ping 消息浅妆,這樣做目的是防止該節(jié)點(diǎn)信息太長時間沒更新望迎,當(dāng)我們寬帶資源緊張時,在可redis.conf 將 cluster-node-timeout 15000 改成 30 秒凌外,但不能過度加大辩尊;
B,消息數(shù)據(jù):節(jié)點(diǎn)自身信息和其他節(jié)點(diǎn)信息
5康辑,集群擴(kuò)容
這也是分布式存儲最常見的需求摄欲,當(dāng)我們存儲不夠用時,要考慮擴(kuò)容
擴(kuò)容步驟如下:
A疮薇,準(zhǔn)備好新節(jié)點(diǎn)
B胸墙,加入集群,遷移槽和數(shù)據(jù)
1),同目錄下新增 redis6382.conf、redis6392.conf 兩啟動兩個新 redis 節(jié)點(diǎn):
./redis-server clusterconf/redis6382.conf & (新主節(jié)點(diǎn))
./redis-server clusterconf/redis6392.conf & (新從節(jié)點(diǎn))
2),新增主節(jié)點(diǎn)
./redis-trib.rb add-node 192.168.42.111:6382 192.168.42.111:6379
6379 是原存在的主節(jié)點(diǎn)按咒,6382 是新的主節(jié)點(diǎn)
3),添加從節(jié)點(diǎn)
redis-trib.rb? ? ?add-node? ? ?--slave? ? ?--master-id? ? ?03ccad2ba5dd1e062464bc7590400441fafb63f2 192.168.42.111:6392 192.168.42.111:6379
-- slave迟隅,表示添加的是從節(jié)點(diǎn)
-- master-id 03ccad2ba5dd1e062464bc7590400441fafb63f2 表示主節(jié)點(diǎn) 6382 的master_id;192.168.42.111:6392,新從節(jié)點(diǎn);? ? 192.168.42.111:6379 集群原存在的舊節(jié)點(diǎn)智袭。
4)奔缠,redis-trib.rb reshard 192.168.42.111:6382? ? ? //為新主節(jié)點(diǎn)重新分配 solt
How many slots do you want to move (from 1 to 16384)? 1000? ? ?//設(shè)置 slot 數(shù) 1000
What is the receiving node ID? 464bc7590400441fafb63f2? ? ? //新節(jié)點(diǎn) node id
Source node #1:all? ? ? //表示全部節(jié)點(diǎn)重新洗牌
新增完畢!
6吼野,集群減縮節(jié)點(diǎn):集群同時也支持節(jié)點(diǎn)下線掉校哎;
下線的流程如下:
流程說明:
A,確定下線節(jié)點(diǎn)是否存在槽 slot,如果有瞳步,需要先把槽遷移到其他節(jié)點(diǎn)闷哆,保證整個集群槽節(jié)點(diǎn)映射的完整性;
B谚攒,當(dāng)下線的節(jié)點(diǎn)沒有槽或本身是從節(jié)點(diǎn)時阳准,就可以通知集群內(nèi)其它節(jié)點(diǎn)(或者叫忘記節(jié)點(diǎn)),當(dāng)下線節(jié)點(diǎn)被忘記后正常關(guān)閉馏臭。
刪除節(jié)點(diǎn)也分兩種:
一種是主節(jié)點(diǎn) 6382野蝇,一種是從節(jié)點(diǎn) 6392。
在從節(jié)點(diǎn) 6392 中括儒,沒有分配哈希槽绕沈,執(zhí)行? ./redis-trib.rb del-node 192.168.42.111:6392 7668541151b4c37d2d9?
有兩個參數(shù) ip:port和節(jié)點(diǎn)的 id。 從節(jié)點(diǎn) 6392 從集群中刪除了帮寻。
主節(jié)點(diǎn) 6382 刪除步驟:
1乍狐,./redis-trib.rb reshard 192.168.42.111:6382
問我們有多少個哈希槽要移走,因為我們這個節(jié)點(diǎn)上剛分配了 1000 個所以我們這里輸入1000固逗;
2浅蚪,最后執(zhí)行? ?./redis-trib.rb del-node 192.168.42.111:6382 3e50c6398c75e0088a41f908071c2c2eda1dc900
此時節(jié)點(diǎn)下線完成……
請求路由重定向:我們知道,在 redis 集群模式下烫罩,redis 接收的任何鍵相關(guān)命令首先是計算這個鍵 CRC值惜傲,通過 CRC 找到對應(yīng)的槽位,再根據(jù)槽找到所對應(yīng)的 redis 節(jié)點(diǎn)贝攒,如果該節(jié)點(diǎn)是本身盗誊,則直接處理鍵命令;如果不是隘弊,則回復(fù)鍵重定向到其它節(jié)點(diǎn)哈踱,這個過程叫做MOVED 重定向。
故障轉(zhuǎn)移:
redis 集群實(shí)現(xiàn)了高可用梨熙,當(dāng)集群內(nèi)少量節(jié)點(diǎn)出現(xiàn)故障時开镣,通過故障轉(zhuǎn)移可以保證集群正常對外提供服務(wù)。
當(dāng)集群里某個節(jié)點(diǎn)出現(xiàn)了問題咽扇,redis 集群內(nèi)的節(jié)點(diǎn)通過 ping pong 消息發(fā)現(xiàn)節(jié)點(diǎn)是否健康邪财,是否有故障舅列,其實(shí)主要環(huán)節(jié)也包括了 主觀下線和客觀下線;
主觀下線:指某個節(jié)點(diǎn)認(rèn)為另一個節(jié)點(diǎn)不可用卧蜓,即下線狀態(tài),當(dāng)然這個狀態(tài)不是最終的故障判定把敞,只能代表這個節(jié)點(diǎn)自身的意見弥奸,也有可能存在誤判;
下線流程:
A奋早,節(jié)點(diǎn) a 發(fā)送 ping 消息給節(jié)點(diǎn) b ,如果通信正常將接收到 pong 消息盛霎,節(jié)點(diǎn) a 更新最近一次與節(jié)點(diǎn) b 的通信時間;
B耽装,如果節(jié)點(diǎn) a 與節(jié)點(diǎn) b 通信出現(xiàn)問題則斷開連接愤炸,下次會進(jìn)行重連,如果一直通信失敗掉奄,則它們的最后通信時間將無法更新规个;
C,節(jié)點(diǎn)a內(nèi)的定時任務(wù)檢測到與節(jié)點(diǎn)b最后通信時間超過cluster_note-timeout時姓建,更新本地對節(jié)點(diǎn) b 的狀態(tài)為主觀下線(pfail)诞仓。
客觀下線:指真正的下線,集群內(nèi)多個節(jié)點(diǎn)都認(rèn)為該節(jié)點(diǎn)不可用速兔,達(dá)成共識墅拭,將它下線,如果下線的節(jié)點(diǎn)為主節(jié)點(diǎn)涣狗,還要對它進(jìn)行故障轉(zhuǎn)移谍婉;
假如節(jié)點(diǎn) a 標(biāo)記節(jié)點(diǎn) b 為主觀下線,一段時間后節(jié)點(diǎn) a 通過消息把節(jié)點(diǎn) b 的狀態(tài)發(fā)到其它節(jié)點(diǎn)镀钓,當(dāng)節(jié)點(diǎn) c 接受到消息并解析出消息體時穗熬,會發(fā)現(xiàn)節(jié)點(diǎn) b 的 pfail 狀態(tài)時,會觸發(fā)客觀下線流程掸宛;
當(dāng)下線為主節(jié)點(diǎn)時死陆,此時 redis 集群為統(tǒng)計持有槽的主節(jié)點(diǎn)投票數(shù)是否達(dá)到一半,當(dāng)下線報告統(tǒng)計數(shù)大于一半時唧瘾,被標(biāo)記為客觀下線狀態(tài)措译。
故障恢復(fù):故障主節(jié)點(diǎn)下線后,如果下線節(jié)點(diǎn)的是主節(jié)點(diǎn)饰序,則需要在它的從節(jié)點(diǎn)中選一個替換它领虹,保證集群的高可用;
轉(zhuǎn)移過程如下:
1求豫,資格檢查:檢查該從節(jié)點(diǎn)是否有資格替換故障主節(jié)點(diǎn)塌衰,如果此從節(jié)點(diǎn)與主節(jié)點(diǎn)斷開過通信诉稍,那么當(dāng)前從節(jié)點(diǎn)不具體故障轉(zhuǎn)移;
2最疆,準(zhǔn)備選舉時間:當(dāng)從節(jié)點(diǎn)符合故障轉(zhuǎn)移資格后杯巨,更新觸發(fā)故障選舉時間,只有到達(dá)該時間后才能執(zhí)行后續(xù)流程努酸;
3服爷,發(fā)起選舉:當(dāng)?shù)竭_(dá)故障選舉時間時,進(jìn)行選舉获诈;
4仍源,選舉投票:只有持有槽的主節(jié)點(diǎn)才有票,會處理故障選舉消息舔涎,投票過程其實(shí)是一個領(lǐng)導(dǎo)者選舉(選舉從節(jié)點(diǎn)為領(lǐng)導(dǎo)者)的過程笼踩,每個主節(jié)點(diǎn)只能投一張票給從節(jié)點(diǎn),當(dāng)從節(jié)點(diǎn)收集到足夠的選票(大于 N/2+1)后亡嫌,觸發(fā)替換主節(jié)點(diǎn)操作嚎于,撤銷原故障主節(jié)點(diǎn)的槽,委派給自己挟冠,并廣播自己的委派消息匾旭,通知集群內(nèi)所有節(jié)點(diǎn)。