Redis6.0主從、哨兵、集群搭建和原理
點擊上方藍色字體,選擇“設(shè)為星標”
回復(fù)”資源“獲取更多資源

由于單機Redis存儲能力受單機限制,以及無法實現(xiàn)讀寫操作的負載均衡和讀寫分離,無法保證高可用。本篇就來介紹 Redis 集群搭建方案及實現(xiàn)原理,實現(xiàn)Redis對數(shù)據(jù)的冗余備份,從而保證數(shù)據(jù)和服務(wù)的高可用。主從復(fù)制是哨兵和集群的基石,因此我們循序漸進,由淺入深一層層的將Redis高可用方案抽絲剝繭展示在大家面前。
主從復(fù)制
介紹
主從復(fù)制,是指將一臺Redis服務(wù)器的數(shù)據(jù),復(fù)制到其他的Redis服務(wù)器,主從是哨兵和集群模式能夠?qū)嵤┑幕A(chǔ)。前者稱為主節(jié)點(master),后者稱為從節(jié)點(slave),數(shù)據(jù)的復(fù)制是單向的,只能由主節(jié)點到從節(jié)點。
默認情況下,每臺Redis服務(wù)器都是主節(jié)點;且一個主節(jié)點可以有零個或多個從節(jié)點(0+個從節(jié)點),但一個從節(jié)點只能有一個主節(jié)點。一般主節(jié)點負責(zé)接收寫請求,從節(jié)點負責(zé)接收讀請求,從而實現(xiàn)讀寫分離。
主從一般部署在不同機器上,復(fù)制時存在網(wǎng)絡(luò)延時問題,使用參數(shù)repl-disable-tcp-nodelay選擇是否關(guān)閉TCP_NODELAY,默認為關(guān)閉:
關(guān)閉:無論數(shù)據(jù)大小都會及時同步到從節(jié)點,占帶寬,適用于主從網(wǎng)絡(luò)好的場景;
開啟:主節(jié)點每隔指定時間合并數(shù)據(jù)為TCP包節(jié)省帶寬,默認為40毫秒同步一次,適用于網(wǎng)絡(luò)環(huán)境復(fù)雜或帶寬緊張,如跨機房;

數(shù)據(jù)冗余:主從復(fù)制實現(xiàn)了數(shù)據(jù)的熱備份,是持久化之外的一種數(shù)據(jù)冗余方式。
故障恢復(fù):當主節(jié)點出現(xiàn)問題時,可以由從節(jié)點提供服務(wù),實現(xiàn)快速的故障恢復(fù);實際上是一種服務(wù)的冗余。
負載均衡:在主從復(fù)制的基礎(chǔ)上,配合讀寫分離,可以由主節(jié)點提供寫服務(wù),由從節(jié)點提供讀服務(wù),分擔(dān)服務(wù)器負載;尤其是在寫少讀多的場景下,通過多個從節(jié)點分擔(dān)讀負載,可以大大提高Redis服務(wù)器的并發(fā)量。
讀寫分離:主庫寫、從庫讀,讀寫分離不僅可以提高服務(wù)器的負載能力,同時可根據(jù)需求的變化,改變從庫的數(shù)量;
高可用基石:除了上述作用以外,主從復(fù)制還是哨兵和集群能夠?qū)嵤┑幕A(chǔ)。
開啟主從配置配置主從可以在命令行或配置文件中配置,上面提到主節(jié)點負責(zé)寫,從節(jié)點負責(zé)讀,因此推薦開啟從服務(wù)器的只讀配置,否則的話在從節(jié)點的寫操作不會同步到主節(jié)點會導(dǎo)致數(shù)據(jù)不一致:
命令行模式在從服務(wù)器命令行中執(zhí)行下面的命令即可成為該主服務(wù)器的從節(jié)點:
#在從服務(wù)器執(zhí)行下面的命令成為或取消成為某節(jié)點的從節(jié)點#slaveof 主服務(wù)器的IP 端口號slaveof host port#取消成為任何服務(wù)器的從服務(wù)器slaveof no one#從服務(wù)器只讀(推薦配置)config set slave-read-only yes#查看主從信息info replication#配置主節(jié)點ACL賬號密碼(Redis6開啟ACL的情況)config set masteruser usernameconfig set masterauth password
slaveof?命令是異步的,不會阻塞。同時,從服務(wù)器現(xiàn)有的數(shù)據(jù)會先被清空,然后才會同步主服務(wù)器的數(shù)據(jù)。?
配置文件
在從服務(wù)器配置文件中添加下面的配置然后重啟從服務(wù)器即可:#在從節(jié)點配置文件中新增下面兩個配置即可指定成為某個主節(jié)點的從節(jié)點#slaveof 主節(jié)點地址 主節(jié)點端口slaveof host port#從服務(wù)器只讀(推薦配置)slave-read-only yes
使用ACL用戶同步
上一篇文章中介紹了Redis6的新特性ACL訪問控制列表,基于該特性我們可以為Redis設(shè)置不同的用戶和權(quán)限,在主從復(fù)制中我們也可以配置該同步用戶的賬號密碼:#命令行模式#在從節(jié)點配置主節(jié)點ACL賬號密碼(Redis6開啟ACL的情況)config set masteruser defaultconfig set masterauth wyk123456#在從節(jié)點查看主節(jié)點的ACL用戶密碼config get master*#配置文件模式 redis.conf#在從節(jié)點配置主節(jié)點ACL賬號密碼(Redis6開啟ACL的情況)masteruser defaultmasterauth wyk123456

一主一從
最基礎(chǔ)的主從復(fù)制模型,主節(jié)點負責(zé)處理寫請求,從節(jié)點負責(zé)處理讀請求,主節(jié)點使用RDB持久化模式,從節(jié)點使用AOF持久化模式:
一主多從
一個主節(jié)點可以有多個從節(jié)點,但每個從節(jié)點只能有一個主節(jié)點。一主多從適用于寫少讀多的場景,多個從節(jié)點可以分擔(dān)讀請求負載,提升并發(fā):
樹狀主從
上面的一主多從可以實現(xiàn)讀請求的負載均衡,但當從節(jié)點數(shù)量多的時候,主節(jié)點的同步壓力也是線性提升的,因此可以使用樹狀主從來分擔(dān)主節(jié)點的同步壓力:
復(fù)制原理主從復(fù)制過程大體可以分為3個階段:連接建立階段(即準備階段)、數(shù)據(jù)同步階段、命令傳播階段。在從節(jié)點執(zhí)行 slaveof 命令后,復(fù)制過程便開始按下面的流程運作:
保存主節(jié)點信息:配置slaveof之后會在從節(jié)點保存主節(jié)點的信息。
主從建立socket連接:定時發(fā)現(xiàn)主節(jié)點以及嘗試建立連接。
發(fā)送ping命令:從節(jié)點定時發(fā)送ping給主節(jié)點,主節(jié)點返回PONG。若主節(jié)點沒有返回PONG或因阻塞無法響應(yīng)導(dǎo)致超時,則主從斷開,在下次定時任務(wù)時會從新ping主節(jié)點。
權(quán)限驗證:若主節(jié)點開啟了ACL或配置了requirepass參數(shù),則從節(jié)點需要配置masteruser和masterauth參數(shù)才能保證主從正常連接。
同步數(shù)據(jù)集:首次連接,全量同步。
命令持續(xù)復(fù)制:全量同步完成后,保持增量同步。
前面的主從是最基礎(chǔ)的提升Redis服務(wù)器穩(wěn)定性的一種實現(xiàn)方式,但我們可以看到master節(jié)點仍然是一臺,若主節(jié)點宕機,所有從服務(wù)器都不會有新的數(shù)據(jù)進來,如何讓主節(jié)點也實現(xiàn)高可用,當主節(jié)點宕機的時候自動從從節(jié)點中選舉一臺節(jié)點提升為主節(jié)點就是哨兵實現(xiàn)的功能。作用
監(jiān)控:監(jiān)控主從節(jié)點運行情況。
通知:當監(jiān)控節(jié)點出現(xiàn)故障,哨兵之間進行通訊。
自動故障轉(zhuǎn)移:當監(jiān)控到主節(jié)點宕機后,斷開與宕機主節(jié)點連接的所有從節(jié)點,然后在從節(jié)點中選取一個作為主節(jié)點,將其他的從節(jié)點連接到這個最新的主節(jié)點。最后通知客戶端最新的服務(wù)器地址。
哨兵節(jié)點最少三臺且必須為單數(shù)。這個與其他分布式框架如zookeeper類似,如果是雙數(shù),在選舉的時候就會出現(xiàn)平票的情況,所以必須是三臺及以上的單數(shù)。
配置文件
在redis源碼中找到?sentinel.conf?配置文件,我們把它移動到redis安裝目錄下然后修改配置,共有下面幾個配置:vim /opt/app/redis6/bin/sentinel.conf#端口port 26379#后臺啟動daemonize yes#運行時PID文件pidfile /var/run/redis-sentinel.pid#日志文件(絕對路徑)logfile "/opt/app/redis6/sentinel.log"#數(shù)據(jù)目錄dir /tmp/sentinel_26379#監(jiān)控的節(jié)點名字可以自定義,后邊的2代表的:如果有倆個哨兵判斷這個主節(jié)點掛了那這個主節(jié)點就掛了,通常設(shè)置為哨兵個數(shù)一半加一sentinel monitor mymaster 127.0.0.1 6379 2#哨兵連接主節(jié)點多長時間沒有響應(yīng)就代表主節(jié)點掛了,單位毫秒。默認30000毫秒,30秒。sentinel down-after-milliseconds mymaster 30000#在故障轉(zhuǎn)移時,最多有多少從節(jié)點對新的主節(jié)點進行同步。這個值越小完成故障轉(zhuǎn)移的時間就越長,這個值越大就意味著越多的從節(jié)點因為同步數(shù)據(jù)而暫時阻塞不可用sentinel parallel-syncs mymaster 1#在進行同步的過程中,多長時間完成算有效,單位是毫秒,默認值是180000毫秒,3分鐘。sentinel failover-timeout mymaster 180000#禁止使用SENTINEL SET設(shè)置notification-script和client-reconfig-scriptsentinel deny-scripts-reconfig yes
哨兵啟動及驗證
我這里演示在一臺機器上啟動3個Redis服務(wù)以及3個哨兵服務(wù),其中3個redis服務(wù)作一主兩從,哨兵監(jiān)控主節(jié)點,然后測試主節(jié)點掛了之后哨兵自動選舉新的master節(jié)點。[實際應(yīng)用中建議分別部署在不同的機器上]:配置啟動三個Redis服務(wù)以及Sentinel 服務(wù):Redis服務(wù):localhost:6381,localhost:6382,localhost:6383sentinel服務(wù):localhost:26381,localhost:26382,localhost:263836381為Redis初始主節(jié)點,6382,6383分別為6381的從節(jié)點。26381,26382,26383作為三個哨兵服務(wù)監(jiān)控上面的Redis主從架構(gòu)。
1.首先復(fù)制Redis目錄出三個:cp -r /opt/app/redis6 /opt/app/redis6Acp -r /opt/app/redis6 /opt/app/redis6Bcp -r /opt/app/redis6 /opt/app/redis6C2.分別修改A,B,C三個目錄中的redis.conf和sentinel.conf文件,主要修改端口和文件路徑,下面以A為演示,B,C略過:vim redis.conf--------------------------------------------port 6381daemonize yespidfile "/var/run/redisA_6381.pid"logfile "/opt/app/redis6A/redis_6381.log" #需要手動touch文件dir "/opt/app/redis6A/data" #需要手動先mkdir文件夾--------------------------------------------vim sentinel.conf--------------------------------------------port 26381daemonize yespidfile /var/run/redis-sentinel_26381.pidlogfile "/opt/app/redis6A/sentinel_26381.log" #需要手動先touch文件dir /tmp/sentinel_26381 #需要手動先mkdir文件夾sentinel monitor mymaster 127.0.0.1 6381 2 #此參數(shù)在ABC三個服務(wù)中保持一致,都監(jiān)聽6381端口--------------------------------------------創(chuàng)建log文件和目錄:mkdir /opt/app/redis6A/datamkdir /opt/app/redis6B/datamkdir /opt/app/redis6C/datatouch /opt/app/redis6A/redis_6381.logtouch /opt/app/redis6B/redis_6382.logtouch /opt/app/redis6C/redis_6383.logmkdir /tmp/sentinel_26381mkdir /tmp/sentinel_26382mkdir /tmp/sentinel_26383touch /opt/app/redis6A/sentinel_26381.logtouch /opt/app/redis6B/sentinel_26382.logtouch /opt/app/redis6C/sentinel_26383.log3.配置完成后,分別啟動Redis三個服務(wù)以及Sentinel三個服務(wù):#啟動Redis/opt/app/redis6A/bin/redis-server /opt/app/redis6A/bin/redis.conf/opt/app/redis6B/bin/redis-server /opt/app/redis6B/bin/redis.conf/opt/app/redis6C/bin/redis-server /opt/app/redis6C/bin/redis.conf#配置Redis主從,6381為主,6382和6383為從節(jié)點#最后啟動Sentinel/opt/app/redis6A/bin/redis-sentinel /opt/app/redis6A/bin/sentinel.conf/opt/app/redis6B/bin/redis-sentinel /opt/app/redis6B/bin/sentinel.conf/opt/app/redis6C/bin/redis-sentinel /opt/app/redis6C/bin/sentinel.conf
使用redis-cli客戶端命令行進入6381,6382,6383的Redis服務(wù),然后配置6382和6383作為6381的從節(jié)點:
啟動哨兵服務(wù):
此時我們在redis客戶端中使用debug命令模擬主節(jié)點崩潰的情況,然后看是否會選舉6382和6383提升為主節(jié)點,以及6381恢復(fù)啟動后是什么角色:#命令執(zhí)行一個非法的內(nèi)存訪問從而讓 Redis 崩潰,僅在開發(fā)時用于 BUG 調(diào)試,執(zhí)行后需要重啟服務(wù)debug segfault
然后我們查看哨兵的日志:vim?/opt/app/redis6A/sentinel_26381.log

重啟6381的redis服務(wù)后查看,哨兵已經(jīng)自動將6381節(jié)點作為6382新主節(jié)點的從節(jié)點:
原理哨兵之間會有通訊,哨兵和主從節(jié)點之間也有監(jiān)控,基于這些信息同步和狀態(tài)監(jiān)控實現(xiàn)Redis的故障轉(zhuǎn)移:哨兵和哨兵之間以及哨兵和Redis主從節(jié)點之間每隔一秒發(fā)送ping監(jiān)控它們的健康狀態(tài);
哨兵向Redis主從節(jié)點每隔10秒發(fā)送一次info保存節(jié)點信息;
哨兵向Redis主節(jié)點每隔2秒發(fā)送一次hello,直到哨兵報出sdown,代表主節(jié)點失聯(lián),然后通知其余哨兵嘗試連接該主節(jié)點;
Redis主節(jié)點下線的情況分為主觀下線和客觀下線:主觀下線(sdown):單獨一個哨兵發(fā)現(xiàn)master故障了。
客觀下線(odown):半數(shù)哨兵都認為master節(jié)點故障就會觸發(fā)故障轉(zhuǎn)移。哨兵Leader選舉:
一般情況下當哨兵發(fā)現(xiàn)主節(jié)點sdown之后 該哨兵節(jié)點會成為領(lǐng)導(dǎo)者負責(zé)處理主從節(jié)點的切換工作:
哨兵A發(fā)現(xiàn)Redis主節(jié)點失聯(lián);
哨兵A報出sdown,并通知其他哨兵,發(fā)送指令sentinel is-master-down-by-address-port給其余哨兵節(jié)點;
其余哨兵接收到哨兵A的指令后嘗試連接Redis主節(jié)點,發(fā)現(xiàn)主節(jié)點確實失聯(lián);
哨兵返回信息給哨兵A,當超過半數(shù)的哨兵認為主節(jié)點下線后,狀態(tài)會變成odown;
最先發(fā)現(xiàn)主節(jié)點下線的哨兵A會成為哨兵領(lǐng)導(dǎo)者負責(zé)這次的主從節(jié)點的切換工作;
哨兵的選舉機制是以各哨兵節(jié)點接收到發(fā)送sentinel is-master-down-by-address-port指令的哨兵id 投票,票數(shù)最高的哨兵id會成為本次故障轉(zhuǎn)移工作的哨兵Leader;故障轉(zhuǎn)移:當哨兵發(fā)現(xiàn)主節(jié)點下線之后經(jīng)過上面的哨兵選舉機制,選舉出本次故障轉(zhuǎn)移工作的哨兵節(jié)點完成本次主從節(jié)點切換的工作:
哨兵Leader 根據(jù)一定規(guī)則從各個從節(jié)點中選擇出一個節(jié)點升級為主節(jié)點;
其余從節(jié)點修改對應(yīng)的主節(jié)點為新的主節(jié)點;
當原主節(jié)點恢復(fù)啟動的時候,變?yōu)樾碌闹鞴?jié)點的從節(jié)點
哨兵Leader選擇新的主節(jié)點遵循下面幾個規(guī)則:健康度:從節(jié)點響應(yīng)時間快;完整性:從節(jié)點消費主節(jié)點的offset偏移量盡可能的高 ();穩(wěn)定性:若仍有多個從節(jié)點,則根據(jù)從節(jié)點的創(chuàng)建時間選擇最有資歷的節(jié)點升級為主節(jié)點;?在哨兵模式下主從節(jié)點總是會變更,因此在Java或Python中訪問哨兵模式下的Redis時可以使用對應(yīng)的哨兵接口連接:
集群介紹Redis集群(Redis Cluster)是從 Redis 3.0 開始引入的分布式存儲方案。集群由多個節(jié)點(Node)組成,Redis 的數(shù)據(jù)分布在這些節(jié)點中。#JavaJedisSentinelPool#Pythonfrom?redis.sentinel?import?SentinelConnectionPool
集群中的節(jié)點分為主節(jié)點和從節(jié)點,只有主節(jié)點負責(zé)讀寫請求和集群信息的維護,從節(jié)點只進行主節(jié)點數(shù)據(jù)和狀態(tài)信息的復(fù)制。
作用Redis集群的作用有下面幾點:
數(shù)據(jù)分區(qū):突破單機的存儲限制,將數(shù)據(jù)分散到多個不同的節(jié)點存儲;
負載均衡:每個主節(jié)點都可以處理讀寫請求,提高了并發(fā)能力;
高可用:集群有著和哨兵模式類似的故障轉(zhuǎn)移能力,提升集群的穩(wěn)定性;
原理數(shù)據(jù)分區(qū)規(guī)則衡量數(shù)據(jù)分區(qū)方法的標準有兩個重要因素:1) 是否均勻分區(qū); 2)增減節(jié)點對數(shù)據(jù)分布的影響;
由于哈希算法具有隨機性,可以保證數(shù)據(jù)均勻分布,因此Redis集群采用哈希分區(qū)的方式對數(shù)據(jù)進行分區(qū),哈希分區(qū)就是對數(shù)據(jù)的特征值進行哈希,然后根據(jù)哈希值決定數(shù)據(jù)放在哪里。
常見的哈希分區(qū)有:哈希取余:計算key的hash值,對節(jié)點數(shù)量做取余計算,根據(jù)結(jié)果將數(shù)據(jù)映射到對應(yīng)節(jié)點;但當節(jié)點增減時,系統(tǒng)中所有數(shù)據(jù)都需要重新計算映射關(guān)系,引發(fā)大量數(shù)據(jù)遷移;
一致性哈希:將hash值區(qū)間抽象為一個環(huán)形,節(jié)點均勻分布在該環(huán)形之上,然后根據(jù)數(shù)據(jù)的key計算hash值,在該hash值所在的圓環(huán)上的位置延順時針行走找到的第一個節(jié)點的位置,該數(shù)據(jù)就放在該節(jié)點之上。相比于哈希取余,一致性哈希分區(qū)將增減節(jié)點的影響限制為相鄰節(jié)點。
例:在AB節(jié)點中新增一個節(jié)點E時,因為B上的數(shù)據(jù)的key的hash值在A和B所在的hash區(qū)間之內(nèi),因此只有C上的一部分數(shù)據(jù)會遷移到B節(jié)點之上;同理如果從BCD中移除C節(jié)點,由于C上的數(shù)據(jù)的key的hash值在B和C所在的hash區(qū)間之內(nèi),因此C上的數(shù)據(jù)順時針找到的第一個節(jié)點就是D節(jié)點,因此C的數(shù)據(jù)會全部遷移到D節(jié)點之上。但當節(jié)點數(shù)量較少的時候,增刪節(jié)點對單個節(jié)點的影響較大,會造成數(shù)據(jù)分布不均,如移除C節(jié)點時,C的數(shù)據(jù)會全部遷移到D節(jié)點上,此時D節(jié)點擁有的數(shù)據(jù)由原來的1/4變成現(xiàn)在的1/2,相比于節(jié)點A和B來說負載更高。
帶虛擬節(jié)點的一致性哈希 (Redis集群):Redis采用的方案,在一致性哈希基礎(chǔ)之上,引入虛擬節(jié)點的概念,虛擬節(jié)點被稱為槽(slot)。Redis集群中,槽的數(shù)量為16384。槽介于數(shù)據(jù)和節(jié)點之間,將節(jié)點劃分為一定數(shù)量的槽,每個槽包含哈希值一定范圍內(nèi)的數(shù)據(jù)。由原來的hash-->node 變?yōu)?hash-->slot-->node。當增刪節(jié)點時,該節(jié)點所有擁有的槽會被重新分配給其他節(jié)點,可以避免在一致性哈希分區(qū)中由于某個節(jié)點的增刪造成數(shù)據(jù)的嚴重分布不均。
通信機制在上面的哨兵方案中,節(jié)點被分為數(shù)據(jù)節(jié)點和哨兵節(jié)點,哨兵節(jié)點也是redis服務(wù),但只作為選舉監(jiān)控使用,只有數(shù)據(jù)節(jié)點會存儲數(shù)據(jù)。而在Redis集群中,所有節(jié)點都是數(shù)據(jù)節(jié)點,也都參與集群的狀態(tài)維護。在Redis集群中,數(shù)據(jù)節(jié)點提供兩個TCP端口,在配置防火墻時需要同時開啟下面兩類端口:普通端口:即客戶端訪問端口,如默認的6379;
集群端口:普通端口號加10000,如6379的集群端口為16379,用于集群節(jié)點之間的通訊;
MEET:在節(jié)點握手階段,對新加入的節(jié)點發(fā)送meet消息,請求新節(jié)點加入當前集群,新節(jié)點收到消息會回復(fù)PONG消息;
PING:節(jié)點之間互相發(fā)送ping消息,收到消息的會回復(fù)pong消息。ping消息內(nèi)容包含本節(jié)點和其他節(jié)點的狀態(tài)信息,以此達到狀態(tài)同步;
PONG:pong消息包含自身的狀態(tài)數(shù)據(jù),在接收到ping或meet消息時會回復(fù)pong消息,也會主動向集群廣播pong消息;
FAIL:當一個主節(jié)點判斷另一個主節(jié)點進入fail狀態(tài)時,會向集群廣播這個消息,接收到的節(jié)點會保存該消息并對該fail節(jié)點做狀態(tài)判斷;
PUBLISH:當節(jié)點收到publish命令時,會先執(zhí)行命令,然后向集群廣播publish消息,接收到消息的節(jié)點也會執(zhí)行publish命令;
Dummy客戶端使用redis-cli客戶端連接集群被稱為dummy客戶端,只會在執(zhí)行命令之后通過MOVED錯誤重定向找到對應(yīng)的節(jié)點,如圖,我們可以使用redis-cli -c命令進入集群命令行,當查看或設(shè)置key的時候會根據(jù)上面提到的CRC16算法計算key的hash值找到對應(yīng)的槽slot,然后重定向到對應(yīng)的節(jié)點之后才能操作,我們也使用cluster keyslot命令查看key所在的槽solt:
#使用-c進入集群命令行模式redis-cli -c -p 6381#使用命令查看key所在的槽cluster keyslot key1

Smart客戶端相比于dummy客戶端,smart客戶端在初始化連接集群時就緩存了槽slot和節(jié)點node的對應(yīng)關(guān)系,?也就是在連接任意節(jié)點后執(zhí)行cluster slots,我們使用的JedisCluster就是smart客戶端:cluster slots
集群代理:Redis6版本中新增的特性,客戶端不需要知道集群中的具體節(jié)點個數(shù)和主從身份,可以直接通過代理訪問集群。與Redis在不同的分支,將在后面的文章中具體介紹。?搭建集群
從Redis5之后我們就可以直接使用redis-cli --cluster命令自動部署Redis集群了,所以本篇也直接使用該方式搭建集群。?這里演示仍然是一臺機器上使用三主三從的方式部署Redis集群:
配置:將上面的A,B,C復(fù)制出AA,BB,CC,然后修改里面的配置文件:cluster-config-file:每個節(jié)點在運行過程中,會維護一份集群配置文件。當集群信息發(fā)生變化時(如增減節(jié)點),集群內(nèi)所有節(jié)點會將最新信息更新到該配置文件。節(jié)點重啟后,會重新讀取該配置文件,獲取集群信息,可以方便的重新加入到集群中。也就是說,當 Redis 節(jié)點以集群模式啟動時,會首先尋找是否有集群配置文件。如果有則使用文件中的配置啟動;如果沒有,則初始化配置并將配置保存到文件中。1.首先復(fù)制Redis目錄出三個:cp -r /opt/app/redis6A /opt/app/redis6AAcp -r /opt/app/redis6B /opt/app/redis6BBcp -r /opt/app/redis6C /opt/app/redis6CC2.分別修改6個目錄中的redis.conf文件,主要開啟集群以及修改端口和文件路徑,下面以A為演示,其余略過:vim /opt/app/redis6A/bin/redis.conf--------------------------------------------port 6381daemonize yespidfile "/var/run/redisA_6381.pid"logfile "/opt/app/redis6A/redis_6381.log" #需要手動touch文件dir "/opt/app/redis6A/data" #需要手動先mkdir文件夾cluster-enabled yes # 啟用集群模式cluster-node-timeout 15000 # 設(shè)置當前節(jié)點連接超時毫秒數(shù)cluster-config-file node_6381.conf #設(shè)置當前節(jié)點集群配置文件路徑--------------------------------------------3.在6個目錄下分別創(chuàng)建log文件和目錄:mkdir /opt/app/redis6A/datatouch?/opt/app/redis6A/redis_6381.log
集群配置文件由 Redis 節(jié)點維護,不需要人工修改。?
啟動部署:部署集群需要先啟動各個節(jié)點的服務(wù),此時這些節(jié)點都沒加到集群中,使用redis-cli --cluster create xxx命令創(chuàng)建集群:
bin/redis-cli --cluster create 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6391 127.0.0.1:6392 127.0.0.1:6393 --cluster-replicas 1#這里的--cluster-replicas表示每個主節(jié)點有幾個副本節(jié)點
redis-cli --cluster代替了之前的redis-trib.rb,我們無需安裝ruby環(huán)境即可直接使用它附帶的所有功能:創(chuàng)建集群、增刪節(jié)點、槽遷移、完整性檢查、數(shù)據(jù)重平衡等等。
集群限制由于Redis集群中數(shù)據(jù)分布在不同的節(jié)點上,因此有些功能會受限:db庫:單機的Redis默認有16個db數(shù)據(jù)庫,但在集群模式下只有一個db0;復(fù)制結(jié)構(gòu):上面的復(fù)制結(jié)構(gòu)有樹狀結(jié)構(gòu),但在集群模式下只允許單層復(fù)制結(jié)構(gòu);事務(wù)/lua腳本:僅允許操作的key在同一個節(jié)點上才可以在集群下使用事務(wù)或lua腳本;(使用Hash Tag可以解決)key的批量操作:如mget,mset操作,只有當操作的key都在同一個節(jié)點上才可以執(zhí)行;(使用Hash Tag可以解決)keys/flushall:只會在該節(jié)點之上進行操作,不會對集群的其他節(jié)點進行操作;Hash Tag:上面介紹集群限制的時候,由于key被分布在不同的節(jié)點之上,因此無法跨節(jié)點做事務(wù)或lua腳本操作,但我們可以使用hash tag方式解決。hash tag:當key包含{}的時候,不會對整個key做hash,只會對{}包含的部分做hash然后分配槽slot;因此我們可以讓不同的key在同一個槽內(nèi),這樣就可以解決key的批量操作和事務(wù)及l(fā)ua腳本的限制了;但由于hash tag會將不同的key分配在相同的slot中,如果使用不當,會造成數(shù)據(jù)分布不均的情況,需要注意。
集群參數(shù)優(yōu)化cluster_node_timeout:默認值為15s。影響ping消息接收節(jié)點的選擇,值越大對延遲容忍度越高,選擇的接收節(jié)點就越少,可以降低帶寬,但會影響收斂速度。應(yīng)該根據(jù)帶寬情況和實際要求具體調(diào)整。影響故障轉(zhuǎn)移的判定,值越大越不容易誤判,但完成轉(zhuǎn)移所消耗的時間就越長。應(yīng)根據(jù)網(wǎng)絡(luò)情況和實際要求具體調(diào)整。?cluster-require-full-coverage為了保證集群的完整性,只有當16384個槽slot全部分配完畢,集群才可以上線,但同時,若主節(jié)點發(fā)生故障且故障轉(zhuǎn)移還未完成時,原主節(jié)點的槽不在任何節(jié)點中,集群會處于下線狀態(tài),影響客戶端的使用。
該參數(shù)可以改變此設(shè)定:no:? 表示當槽沒有完全分配時,集群仍然可以上線;yes: 默認配置,只有槽完全分配,集群才可以上線。
歡迎點贊+收藏+轉(zhuǎn)發(fā)朋友圈素質(zhì)三連
文章不錯?點個【在看】吧!??


