天天看點

Redis 叢集、哨兵、主從同步

目錄

      • redis叢集簡介
      • 搭建redis叢集
      • redis叢集原理
        • 哨兵(Sentinel)機制
        • 用戶端請求處理流程
        • 故障遷移 failover
        • 晉升機制 | 選舉機制
        • 叢集不可用
      • 主從同步
        • 主從同步的作用
        • redis常見的主從結構
        • redis的主從同步機制
        • 注意點

redis叢集簡介

單機版redis server,redis server容量受單機記憶體限制,往往需要redis server叢集來擴容,提升redis資料庫的容量。

redis 5.0之前通過執行redis-trib.rb建立redis叢集,redis-trib.rb是ruby語言寫的腳本,需要配置ruby環境,還需要安裝redis.gem來管理叢集。redis 5.0開始用redis-cli代替redis-trib.rb,雖然redis-trib.rb現在還能用(向下相容),但後續會被取消掉,建議使用redis-cli來建立叢集。

此處以redis 5.x為例建立redis叢集。

# 檢視redis server版本
./redis-server -v
./redis-server --version
           

搭建redis叢集

1、redis叢集至少要3個master,且每個master至少要有一個slave,是以最少要6個節點

如果節點數量不滿足要求,後續會報錯

Redis 叢集、哨兵、主從同步

2、編輯所有叢集節點的redis.conf,允許叢集

Redis 叢集、哨兵、主從同步

參加叢集的所有節點都不能是slave,如果配置了replicaof,将其注釋掉。

哪些節點作為master、哪些節點作為slave,由叢集自動配置設定,不能手動設定。

3、參與叢集的節點,資料庫必須是空的,如果有.rdb、.aof等資料庫檔案,需先删除

如果叢集搭建失敗,重試時需要先删除之前生成的資料庫檔案(.rdb、.aof)。如果資料庫不為空,後續會報錯

Redis 叢集、哨兵、主從同步

4、先啟動參與叢集的每個redis server,再使用某個redis-cli建立叢集

指定參加叢集的節點(ip、port),參數cluster-replicas指定每個master配置設定幾個slave。自動配置設定時,一般是前面的節點都作為master,後面的都作為slave。

會給出叢集配置方案。(圖是以前我在本地模拟時截的,是以ip都是127.0.0.1,隻修改了端口。)

Redis 叢集、哨兵、主從同步

M是master,S是slave,slot(槽點)是用來執行寫指令的,隻配置設定給master,各個master的槽點數差不多。slave隻是作為備份,不執行寫指令,不配置設定槽點。

輸入yes按方案執行

5、連接配接到叢集中的某個節點即可連接配接到整個redis叢集,檢視叢集資訊

# 連接配接到叢集時,不管是連接配接到master還是slave,都要加-c,c即cluster
redis1/bin/redis-cli -h 192.168.1.1 -p 6379 -c  

# 檢視叢集資訊
cluster info
           
Redis 叢集、哨兵、主從同步

叢集狀态、槽點數、節點數都可以看到,其中叢集大小cluster_size隻算master。

# 檢視目前連接配接到的節點的主從資訊
info replication
           
Redis 叢集、哨兵、主從同步

可以看到目前節點的角色,如果是master會顯示其從節點的資訊,如果是slave會顯示如果其master的資訊。此外還能看到資料同步的偏移量。

設定值、取值

Redis 叢集、哨兵、主從同步

先根據key的哈希值确定槽點位置,自動轉到該槽點所在的節點,然後在該槽點處設定值、取值。

redis叢集原理

Redis Cluster 是一種redis伺服器的Sharding技術,內建了主從複制和哨兵 功能,提供了redis的高可用支援。

redis叢集是把資料分散存儲在多個master上,這些master共同組成一個完整的redis資料庫,每個master上隻存儲部分key,也叫作分片。每個master都可以處理請求,slave隻用于所屬master的資料備份,不處理請求。整個redis叢集共有16384個槽點(hash slot)。

redis叢集的優勢

  • 提高擴充性,可增加master節點數量,以分散存儲壓力
  • 提高可用性,master故障時,可自動切換到對應的slave節點

哨兵(Sentinel)機制

哨兵是redis server附帶的程式,每個redis server(master、slave)都自帶得有,預設未配置哨兵。redis server預設使用6379,哨兵預設使用26379。

建立redis叢集時,會自動給每個節點配置哨兵,用于監控叢集中各個節點(master+slave)的狀态。每個節點(master+slave)上都有一個節點資訊檔案記錄叢集各節點的資訊

Redis 叢集、哨兵、主從同步

包括各個節點的ip、port,角色(master、slave),是叢集中的第幾個節點,和目前節點之間是否能ping通(是否connected)。如果是master,還包括槽點區間。

Sentinel的主要功能

  • 叢集監控:監控master、slave節點是否正常工作
  • 消息通知:redis節點故障時,哨兵負責發送警告消息通知管理者
  • 故障遷移:master故障時自動遷移到slave上
  • 配置中心:發生故障轉移時,通知refis用戶端新的master位址

用戶端請求處理流程

redis用戶端可以向redis叢集的任意一個節點發送請求,節點接收到請求後會對其進行解析,先根據key的hash值确定槽點位置,再根據節點資訊檔案确定該槽點所在節點(ip、port),轉發給該節點進行處理。

redis.conf

Redis 叢集、哨兵、主從同步

第一個配置是節點資訊檔案的儲存路徑,預設儲存路徑是資料存儲目錄(.aof、.rdb所在目錄)下的nodes.conf檔案。

建立叢集時會往每個節點的nodes.conf中寫入叢集初始配置,叢集建立後,每個節點的哨兵每秒都會ping一下其它節點,确定其它節點的狀态,來維護|更新節點資訊檔案。

第二個配置指定逾時時間,預設15000ms,即15s。如果哨兵在15s内都沒有ping通某個節點,就主觀認為該節點down掉了,将該節點的狀态辨別為sdown,s即subjectively 主觀。

如果超過一半的master都将某個master的狀态辨別為sdown,就認為客觀上該master節點确實down掉了,将該master節點的狀态辨別為odown,o即objectively ,客觀。哨兵會自動将從該master的所有slave中選一個新的master。注意是哨兵确定新的master,不是由其它master确定。

故障遷移 failover

故障遷移是指:master故障,sentinel從附屬slave中選出新master,其它附屬slave從新master同步資料的過程。具體過程如下

  • try-failover  master的狀态被辨別odown,叢集嘗試進行故障轉移
  • elected-leader  從該master的附屬slave中選出新master
  • selected-slave  已選出新的master
  • send-slaveof-noone  向新master發送slaveof no one指令,擺脫slave地位
  • wait-promotion  等待新master完成配置更新,晉升為master。配置更新有2個方面:一是去掉replicaof配置擺脫slave角色,二是繼承原master的槽點、得到寫權限(slave預設隻讀)
  • promoted  晉升完成
  • 其它附屬slave從新master同步全量資料

故障遷移期間,整個redis叢集不對外提供服務。redis叢集和zk叢集很相似,資料一緻性強,但可用性得不到保證。

晉升機制 | 選舉機制

redis.conf

Redis 叢集、哨兵、主從同步

優先級有3個值:10,25,100,預設100,數值越小,優先級越高。

master選舉算法

  • 選擇優先級高的(數值小的)
  • 如果優先級相同,選擇主從複制偏移量offset靠後的,偏移量越靠後,資料越新;
  • 如果便宜量相同,選擇 run id 小的。

叢集不可用

以下2種情況都會使redis叢集不可用(叢集狀态為fail)

  • 某個master節點及其所有slave節點都down掉
  • master節點短時間内down掉一半以上,不管有沒有代替的slave,整個叢集直接不可用

主從同步

建立redis叢集時會自動設定哨兵、主從關系,slave會自動從master同步資料,sentinel 的多執行個體部署保證了sentinel 本身的可用性,slave+sentinel保證了redis叢集的高可用。

sentinel雖然提高了redis叢集的可用性,但又是master又是slave又是sentinel,增加了redis叢集的複雜性,部署、擴容麻煩。

主從同步的作用

  • 資料備援(備份)
  • 提高可用性:master故障,可将某個slave作為新的master

至于讀寫分離,用master處理寫請求(、讀請求),slave處理讀請求,這對redis來說沒必要。

讀寫分離主要有2個作用:減輕master讀寫壓力,提高整體負載;提高性能。

關系資料庫讀寫資料要進行檔案IO,耗時、性能差,需要讀寫分離提高性能;redis本身是記憶體資料庫,性能極高,不需要讀寫分離來提高性能。

關系資料庫叢集通常是一主多從,需要從庫分擔讀請求的壓力,redis叢集本身就有多個master,通過多個master來分擔讀寫壓力、存儲壓力,不需要slave來分擔。

是以redis叢集一般不做讀寫分離,沒必要,slave隻作資料備份,讀寫請求都由master處理。

redis常見的主從結構

Redis 叢集、哨兵、主從同步

如果slave太多,都從master同步資料,master IO壓力會很大,此時可以使用第三種層級結構,從其它slave同步資料。

redis的主從同步機制

master節點之間存儲不同的資料,同步指的是主從節點之間的同步。

redis的同步機制如下

  • 主從剛連接配接時做全量同步,後續做增量同步
  • 如果嘗試增量同步時失敗,則進行全量同步
  • 如果有需要,slave随時可以發起全量同步
  • 同步過程中出現網絡問題時會自動重連,重連之後會自動補上缺少的資料
  • 主從同步預設采用異步複制方式,不會阻塞master,master在主從複制時仍可以處理用戶端請求

全量同步

  • slave發送sync指令給master
  • master執行bgsave指令,啟動一個背景程序,将記憶體中的全量資料同步到rdb檔案中,并将此後執行的寫指令記錄到緩沖區中
  • master完成bgsave指令後,将rdb檔案發送給slave
  • slave使用新接收到的rdb檔案替換舊的rdb檔案,重新載入資料
  • master發送rdb檔案完畢後繼續向slave發送緩沖區中的寫指令
  • slave接收并執行master發送的緩存區中的寫指令

增量同步

  • master接收并執行寫指令
  • 将寫指令記錄到aof檔案中,并将寫指令發送給slave執行

注意點

  • 如果master壓力很大,這時候增加slave數量會加大master的IO壓力,盡量不要先增加slave數量,先增加master節點數量以分散現有master的壓力。
  • slave啟動後會立刻發送sync指令與master進行全量同步,如果多個slave同時進行重新開機,可能導緻master IO壓力驟增甚至當機。
  • slave和master盡量在同一個區域網路内,以保證網絡的穩定性、網絡傳輸的速度

繼續閱讀