<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Redis6.0主從、哨兵、集群搭建和原理

          共 11618字,需瀏覽 24分鐘

           ·

          2020-07-21 22:16

          點擊上方藍色字體,選擇“設(shè)為星標

          回復(fù)”資源“獲取更多資源

          f21e8369ed1793fc32babfc78dacbf97.webp

          cb8ce666e99133588480b7555c95bc79.webp

          大數(shù)據(jù)技術(shù)與架構(gòu)點擊右側(cè)關(guān)注,大數(shù)據(jù)開發(fā)領(lǐng)域最強公眾號!

          d0ee8c7a7f1cb1abd2a4ccfb4be9823e.webp

          暴走大數(shù)據(jù)點擊右側(cè)關(guān)注,暴走大數(shù)據(jù)!7be66db9f253198464d3b55833d84995.webp

          由于單機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ù)雜或帶寬緊張,如跨機房;



          f9d21a4c90f9e6b99368ba345c5d6a5a.webp


          作用
          • 數(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
          b4fa268009bb334cae0dada6eb6bada5.webp

          一主一從

          最基礎(chǔ)的主從復(fù)制模型,主節(jié)點負責(zé)處理寫請求,從節(jié)點負責(zé)處理讀請求,主節(jié)點使用RDB持久化模式,從節(jié)點使用AOF持久化模式:35389c5a25cc670abf56a7e5835fe758.webp

          一主多從

          一個主節(jié)點可以有多個從節(jié)點,但每個從節(jié)點只能有一個主節(jié)點。一主多從適用于寫少讀多的場景,多個從節(jié)點可以分擔(dān)讀請求負載,提升并發(fā):ac3cdc54b92cd8089aae63fc56027f14.webp

          樹狀主從

          上面的一主多從可以實現(xiàn)讀請求的負載均衡,但當從節(jié)點數(shù)量多的時候,主節(jié)點的同步壓力也是線性提升的,因此可以使用樹狀主從來分擔(dān)主節(jié)點的同步壓力:f69648c301dc7fea70e5e780fcefd0e8.webp復(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ù)制:全量同步完成后,保持增量同步。

          哨兵介紹哨兵(sentinel),用于對主從結(jié)構(gòu)中的每一臺服務(wù)器進行監(jiān)控,當主節(jié)點出現(xiàn)故障后通過投票機制來挑選新的主節(jié)點,并且將所有的從節(jié)點連接到新的主節(jié)點上。
          前面的主從是最基礎(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ù)器地址。

          哨兵也是一臺redis服務(wù)器,只是不對外提供任何服務(wù),redis的bin目錄下的redis-sentinel其實就是redis-server的軟連接。
          哨兵節(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ù):localhost:6381,localhost:6382,localhost:6383sentinel服務(wù):localhost:26381,localhost:26382,localhost:26383
          6381為Redis初始主節(jié)點,6382,6383分別為6381的從節(jié)點。26381,26382,26383作為三個哨兵服務(wù)監(jiān)控上面的Redis主從架構(gòu)。
          配置啟動三個Redis服務(wù)以及Sentinel 服務(wù):
          1.首先復(fù)制Redis目錄出三個:cp -r /opt/app/redis6 /opt/app/redis6Acp -r /opt/app/redis6 /opt/app/redis6Bcp -r /opt/app/redis6 /opt/app/redis6C
          2.分別修改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.log
          mkdir /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.log
          3.配置完成后,分別啟動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é)點:
          f679214ac68f8c823d0f760638fedd39.webp啟動哨兵服務(wù):d1370f3673176e36488f444386aab06b.webp此時我們在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.log18a4d2fc4ea0abd7fc1193e25b5ff265.webp2a024199634e1dc461340aae98c94828.webp重啟6381的redis服務(wù)后查看,哨兵已經(jīng)自動將6381節(jié)點作為6382新主節(jié)點的從節(jié)點:308a5368ad66ffd3266a8d0cf46cc736.webp5792533e2dafe8e9bf01300b2e039cd9.webp原理哨兵之間會有通訊,哨兵和主從節(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é)點的切換工作;

          7b8671ba2cc8f724f9e1f369027cba67.webp哨兵的選舉機制是以各哨兵節(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)的哨兵接口連接:
          #JavaJedisSentinelPool
          #Pythonfrom?redis.sentinel?import?SentinelConnectionPool
          集群介紹Redis集群(Redis Cluster)是從 Redis 3.0 開始引入的分布式存儲方案。集群由多個節(jié)點(Node)組成,Redis 的數(shù)據(jù)分布在這些節(jié)點中。
          集群中的節(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來說負載更高。840d9881df31b4e19173346dfafe4b9c.webp帶虛擬節(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ù)的嚴重分布不均。68f6af9463cfa31d280f0693a7779276.webp通信機制在上面的哨兵方案中,節(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é)點之間的通訊;

          集群的節(jié)點之間通訊采用Gossip協(xié)議,節(jié)點根據(jù)固定頻率(每秒10次)定時任務(wù)進行判斷,當集群狀態(tài)發(fā)生變化,如增刪節(jié)點、槽狀態(tài)變更時,會通過節(jié)點間通訊同步集群狀態(tài),使集群收斂。集群間發(fā)送的Gossip消息有下面五種消息類型:
          • 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命令;

          訪問集群上面介紹了槽的概念,在每個節(jié)點存儲著不同范圍的槽,數(shù)據(jù)也分布在不同的節(jié)點之上,我們在訪問集群的時候,如何知道數(shù)據(jù)在哪個節(jié)點或者在哪個槽之上呢?下面介紹兩種訪問連接:
          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
          79f6b50345d403ca08fc4debb848baab.webpb4907cd1c2921b147b32e1caea9072ef.webpSmart客戶端相比于dummy客戶端,smart客戶端在初始化連接集群時就緩存了槽slot和節(jié)點node的對應(yīng)關(guān)系,?也就是在連接任意節(jié)點后執(zhí)行cluster slots,我們使用的JedisCluster就是smart客戶端:
          cluster slots
          b92409784a24a5fef114a55a59cbf176.webp集群代理:Redis6版本中新增的特性,客戶端不需要知道集群中的具體節(jié)點個數(shù)和主從身份,可以直接通過代理訪問集群。與Redis在不同的分支,將在后面的文章中具體介紹。?

          搭建集群

          從Redis5之后我們就可以直接使用redis-cli --cluster命令自動部署Redis集群了,所以本篇也直接使用該方式搭建集群。?這里演示仍然是一臺機器上使用三主三從的方式部署Redis集群:93e4270303fdb373a073022c1a8d37af.webp配置:將上面的A,B,C復(fù)制出AA,BB,CC,然后修改里面的配置文件:
          1.首先復(fù)制Redis目錄出三個:cp -r /opt/app/redis6A /opt/app/redis6AAcp -r /opt/app/redis6B /opt/app/redis6BBcp -r /opt/app/redis6C /opt/app/redis6CC
          2.分別修改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
          cluster-config-file:每個節(jié)點在運行過程中,會維護一份集群配置文件。當集群信息發(fā)生變化時(如增減節(jié)點),集群內(nèi)所有節(jié)點會將最新信息更新到該配置文件。節(jié)點重啟后,會重新讀取該配置文件,獲取集群信息,可以方便的重新加入到集群中。也就是說,當 Redis 節(jié)點以集群模式啟動時,會首先尋找是否有集群配置文件。如果有則使用文件中的配置啟動;如果沒有,則初始化配置并將配置保存到文件中。
          集群配置文件由 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é)點
          265957d463c8034032611191e0761d77.webpredis-cli --cluster代替了之前的redis-trib.rb,我們無需安裝ruby環(huán)境即可直接使用它附帶的所有功能:創(chuàng)建集群、增刪節(jié)點、槽遷移、完整性檢查、數(shù)據(jù)重平衡等等。a40880f3850e63533655002fe0e169bb.webp集群限制由于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ù)分布不均的情況,需要注意。47c8078ff3167cfea8392021e0201c45.webp集群參數(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ì)三連


          文章不錯?點個【在看】吧!??

          瀏覽 70
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  后入少妇视频 | 翔田千里91 | 欧美成人精品一级A片禁忌 | 日韩一级毛方 | 亚洲综合爱婷婷AV |