1. 程式人生 > 其它 >10-redis主從複製+哨兵模式

10-redis主從複製+哨兵模式

Redis主從複製原理

主從複製是隻將墮胎redis伺服器 一般是一主二從三臺 作為一個叢集

一臺是master 主節點 另外的節點稱為slave/follower 稱為從節點

叢集內 主節點有讀寫功能,以寫為主 從節點只有只讀功能,不能寫入資料

從節點的資料是從主節點複製過來的

主從複製的優點

  1. 實現了資料冗餘,主備複製上的資料是一樣的 實現了熱備功能
  2. 故障恢復 當主節點故障時,備節點可以提供恢復資料的功能
  3. 負載均衡,主備機群配合讀寫分離,可以大大提高伺服器併發量,分擔訪問量負載
  4. 實現了服務的高可用,主從複製+哨兵模式 實現了redis叢集的高可用

生產環境下的redis

  1. 一般不會使用單臺 redis是記憶體資料庫 記憶體資料斷電即失,
  2. 從訪問響應速度上來說 不論一個伺服器真實實體記憶體有多大,當單臺redis的使用記憶體量超過20G的時候,已經不適合單機使用了。
  3. 不論關係型資料庫還是非關係型數庫 往往都是“少寫多讀”的環境,一次寫入 會不斷讀取資料,建議使用叢集環境實現讀寫分離。

Redis主從複製

環境搭建

只配置從庫 不配置主庫

127.0.0.1:6379> info replication #查詢當前庫的資訊
# Replication
role:master #角色 master
connected_slaves:0  #沒有從機
master_replid:78bc4f2d4fb4f0985b99db4b5ad45bf32d35513b
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6379> 

一臺虛擬機器上搭建redis主從複製

開啟4個會話視窗

  1. 複製三份配置檔案配置檔案
  1. 編輯redis6379.conf
port 6379
daemonize yes #後臺啟動開啟
logfile "6379.log" #日誌格式改一下 因為有多個服務
dbfilename dump6379.rdb #dump檔名字改成dump6379.rdb
  1. 編輯redis6380.conf
port 6380
daemonize yes
pidfile /var/run/redis_6380.pid #後臺執行pid改完6380
logfile "6380.log"
dbfilename dump6380.rdb

  1. 編輯redis6381.conf
port 6381
daemonize yes
pidfile /var/run/redis_6381.pid
logfile "6381.log"
dbfilename dump6381.rdb

  1. 修改埠資訊
  1. 修改後臺啟動
  1. 修改pid名稱
  1. 修改log檔名稱
  1. 修改rdb檔名稱
  1. 啟動6379埠的redis服務
  1. 啟動6380埠的redis服務
  1. 啟動6381埠的redis服務
  1. 查詢服務程序

3個埠都啟動了

配置主從關係

上面配置完預設都是三臺主節點 我們要配置一主二從

  1. 會話1 埠6379 主節點
  1. 會話2 6380埠 主節點
  1. 會話3 6381埠 主節點

預設三臺都是master

一般情況下只用配置從機就可以

一主(6379)二從(6380/6381)

  1. 會話2 6380埠
127.0.0.1:6380> SLAVEOF 127.0.0.1 6379 #配置主機的ip和埠
OK
127.0.0.1:6380> info replication
# Replication
role:slave # 再次查詢自己變成從機了
master_host:127.0.0.1 #主機的ip
master_port:6379  #主機的埠
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_repl_offset:0
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:ac317b05cedf82644441b02ffe11b67755daf53f
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576

  1. 會話1主機中去驗證
# Replication
role:master
connected_slaves:1 
slave0:ip=127.0.0.1,port=6380,state=online,offset=224,lag=0 #備機 ip埠 狀態
master_replid:ac317b05cedf82644441b02ffe11b67755daf53f
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:224

  1. 會話3 6381上設定自己為從節點
127.0.0.1:6381> SLAVEOF 127.0.0.1 6379  #設定主機為從節點  主節點的ip埠 127.0.0.1 6379
OK
127.0.0.1:6381> info replication
# Replication
role:slave #本機角色
master_host:127.0.0.1  #master ip
master_port:6379 #master port
master_link_status:up
master_last_io_seconds_ago:5
master_sync_in_progress:0
slave_repl_offset:616
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:ac317b05cedf82644441b02ffe11b67755daf53f
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:616
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576

  1. 去會話1 主機上去驗證

使用命令配置 是暫時的 永久配置需要在配置檔案中配置!!!

  1. 永久配置 在配置檔案中寫入主的ip埠即可
# 6380、6381都配置從屬到6379
replicaof 127.0.0.1 6379

主機可以寫 從機只能讀

主機的資料從機都會自動儲存

故障模擬

模擬主機down機後 從機可以用

  1. 6379埠已經down機
  1. 從機仍然可以獲取資訊
  1. 主節點啟動後寫入
  1. 從節點可以檢視到新寫入的資訊

總結

主節點down機後 從節點依舊連線主節點 整個主從沒有了寫入操作 主節點恢復後寫入的資料 會同步到從節點

模擬故障2

  1. 模擬6381從機down掉
  1. 主節點寫入值
  1. 沒有down掉的主機可以查到
  1. down掉的從機查不到資訊
  1. 查詢down掉從機的角色 啟動服務後 變成了master 主節點
  1. 再次設定down掉的機器為從機 查詢剛才set的key3的值 可以查到
127.0.0.1:6381> get key3
(nil)
127.0.0.1:6381> info replication
# Replication
role:master
connected_slaves:0
master_replid:3eb0b967bc167f368df2ced66251dce8a4b73367
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6381> SLAVEOF 127.0.0.1 6379  #再次設定為從機
OK
127.0.0.1:6381> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_repl_offset:827
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:4f660b5694c705fb64403b08984b92602de96317
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:827
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:814
repl_backlog_histlen:14
127.0.0.1:6381> get key3 #可以查詢到down機前master寫入的資訊
"v3"
127.0.0.1:6381> 

***總結 ***

命令列設定的主從 從機down機後重啟後會變為主機 無法查詢到叢集主機寫入的資訊 重新設定為從機後可以查詢到down機後主機寫入的資訊

以上叢集架構圖

以上的架構是一主二從 當主節點掛掉之後 整個叢集不具有寫入功能,

另一種主從架構嘗試

以上架構的問題是 當主節點掛掉後 整個叢集只有讀功能 不具備寫入功能

我們也可以嘗試配置成如下架構

6379埠的服務仍然作為主節點

6380埠的服務 把自己設定為salve 同時把主節點設定為 6379

6381埠的服務 把自己設定為slave 同時把主節點設定為6380

這樣6380埠的服務 既作為 6379埠服務的salve 又是6381埠服務的master

接上面的環境進行改造

6379埠服務

改造前 主節點 同時有兩個slave節點

6380埠服務這個不需要修改

目前是從節點 同時主節點是6379埠

修改6381埠這臺服務

6381這臺的master修改為6380埠的服務

再次查詢6379埠master這臺服務

salve變成了一個

6380此時即使主節點也是從節點

我們查詢的時候這臺仍然是從節點

也就是目前是不能寫入只能查詢

確認三臺主機同步是否正常

6379埠寫入

6380埠查詢

6381埠查詢

同步沒有問題

模擬故障3

6379埠服務故障關機

6380仍然是從節點

同時6381也是從節點 目前叢集也是一種群龍無首的狀態 哨兵模式之前 這個問題是無法解決的 只能通過手動配置6380埠服務為主節點

6380埠服務操作

127.0.0.1:6380> SLAVEOF no one #設定沒有主節點
OK
127.0.0.1:6380> info replication #再次查詢自己就變成了主節點
# Replication
role:master #主節點
connected_slaves:1
slave0:ip=127.0.0.1,port=6381,state=online,offset=8077,lag=1 #設定的從節點6381資訊還在正常
master_replid:9de587961909c012366d01ef97578ef118226747
master_replid2:4f660b5694c705fb64403b08984b92602de96317
master_repl_offset:8091
second_repl_offset:8078
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:8091
127.0.0.1:6380> 

當6379埠服務重啟服務再次迴歸的時候

已經不屬於整個叢集 是一個單獨的master了

以上問題 自動選舉master,master掛掉重新迴歸的問題 可以通過哨兵模式實現。

哨兵模式

哨兵模式介紹

主從切換 是當主服務down機之後 需要干預把服務切換到另外一臺作為備機上作為主伺服器,人工切換存在時間差,一段時間內服務不可用 ,redis從2.8開始提供sentinel哨兵模式,。

哨兵模式啟動後 哨兵會生成一個獨立的程序,作為程序它會獨立存在,

哨兵通過傳送命令 等待redis響應回覆 從而監控多個redist服務,一段時間內沒有回覆哨兵 則判斷為故障,通過一定演算法在叢集內選舉另外一臺slave為主節點,當舊的主節點恢復服務加入集群后,會被設定為叢集的slave節點。

哨兵工作原理

  1. Slave 啟動成功連線到 master 後會傳送一個sync同步命令

  2. Master 接到命令,啟動後臺的存檔程序,同時收集所有接收到的用於修改資料集命令,在後臺程序執行
    完畢之後,master將傳送整個資料檔案到slave,並完成一次完全同步。

全量複製:slave服務在接收到資料庫檔案資料後,將其存檔並全部載入到記憶體中。 相當於複製一份當前master狀態的副本。

增量複製:Master 繼續將新的所有收集到的修改命令依次傳給slave,完成同步 只修改master修改的部分,其它部分不動。增刪改查。

  1. 只要是slave重新連線master 一定會進行一次全量複製!!

哨兵模式主要作用

通過傳送命令 返回並監控redis服務執行狀態 包含master和slave的狀態

當檢測到主機master服務down掉 會自動選舉一臺slave為master 通過釋出訂閱的方式通知到其它slave主機,修改配置檔案 讓它們切換master主機

配置哨兵模式

環境恢復至 127.0.0.1 6379 主/6380/6381作為從節點

與 redis.conf 同目錄下 配置檔案sentinel.conf

sentinel monitor myredis 127.0.0.1 6379 1 #sentinel monitor 哨兵監控 myredis這個隨便起名 後面是監控的主機 ip port  1表示這個主服務掛掉後 哨兵選舉誰作為新的master

啟動哨兵

redis-sentinel peizhi/sentinel.conf 

啟動後可以看到當前的master和slave

模擬故障 主節點掛掉

6380埠服務變成了主節點

6381埠服務上驗證 6380成為了主節點

哨兵日誌輸出

主節點故障通過演算法選舉6380埠服務為主節點

重新啟動6379埠服務查詢自己是獨立的master

追蹤哨兵日誌 發現哨兵自動把 127.0.0.1 6379設定為7380主節點的從節點

再次查詢6379埠服務的資訊

發現變成了salve節點 同時master主機是6380埠服務 與哨兵日誌輸出的資訊一致。

哨兵模式配置檔案解析

# Example sentinel.conf
# 哨兵sentinel例項執行的埠 預設26379
port 26379 #像redis.cong   如果有哨兵叢集  需要配置多個埠
# 哨兵sentinel的工作目錄
dir /tmp  #定義自己的工作目錄 生成自己的檔案
# 哨兵sentinel監控的redis主節點的 ip port
# master-name 可以自己命名的主節點名字 只能由字母A-z、數字0-9 、這三個字元".-_"組成。
# quorum 配置多少個sentinel 哨兵統一認為master主節點失聯 那麼這時客觀上認為主節點失聯了
# sentinel monitor <master-name> <ip> <redis-port> <quorum>
sentinel monitor mymaster 127.0.0.1 6379 2
# 當在Redis例項中開啟了requirepass foobared 授權密碼 這樣所有連線Redis例項的客戶端都要提供
密碼
# 設定哨兵sentinel 連線主從的密碼 注意必須為主從設定一樣的驗證密碼
# sentinel auth-pass <master-name> <password>
sentinel auth-pass mymaster MySUPER--secret-0123passw0rd
# 指定多少毫秒之後 主節點沒有應答哨兵sentinel 此時 哨兵主觀上認為主節點下線 預設30秒
# sentinel down-after-milliseconds <master-name> <milliseconds>
sentinel down-after-milliseconds mymaster 30000
# 這個配置項指定了在發生failover主備切換時最多可以有多少個slave同時對新的master進行 同步,
這個數字越小,完成failover所需的時間就越長,
但是如果這個數字越大,就意味著 越多的slave因為replication而不可用。
可以通過將這個值設為 1 來保證每次只有一個slave 處於不能處理命令請求的狀態。
# sentinel parallel-syncs <master-name> <numslaves>
sentinel parallel-syncs mymaster 1
# 故障轉移的超時時間 failover-timeout 可以用在以下這些方面:
#1. 同一個sentinel對同一個master兩次failover之間的間隔時間。
#2. 當一個slave從一個錯誤的master那裡同步資料開始計算時間。直到slave被糾正為向正確的master那
裡同步資料時。
#3.當想要取消一個正在進行的failover所需要的時間。
#4.當進行failover時,配置所有slaves指向新的master所需的最大時間。不過,即使過了這個超時,
slaves依然會被正確配置為指向master,但是就不按parallel-syncs所配置的規則來了
# 預設三分鐘
# sentinel failover-timeout <master-name> <milliseconds>
sentinel failover-timeout mymaster 180000
# SCRIPTS EXECUTION
#配置當某一事件發生時所需要執行的指令碼,可以通過指令碼來通知管理員,例如當系統執行不正常時發郵件通知
相關人員。
#對於指令碼的執行結果有以下規則:
#若指令碼執行後返回1,那麼該指令碼稍後將會被再次執行,重複次數目前預設為10
#若指令碼執行後返回2,或者比2更高的一個返回值,指令碼將不會重複執行。
#如果指令碼在執行過程中由於收到系統中斷訊號被終止了,則同返回值為1時的行為相同。
#一個指令碼的最大執行時間為60s,如果超過這個時間,指令碼將會被一個SIGKILL訊號終止,之後重新執行。
#通知型指令碼:當sentinel有任何警告級別的事件發生時(比如說redis例項的主觀失效和客觀失效等等),
將會去呼叫這個指令碼,這時這個指令碼應該通過郵件,SMS等方式去通知系統管理員關於系統不正常執行的信
息。呼叫該指令碼時,將傳給指令碼兩個引數,一個是事件的型別,一個是事件的描述。如果sentinel.conf配
置檔案中配置了這個指令碼路徑,那麼必須保證這個指令碼存在於這個路徑,並且是可執行的,否則sentinel無
法正常啟動成功。
#通知指令碼
# shell程式設計
# sentinel notification-script <master-name> <script-path>
sentinel notification-script mymaster /var/redis/notify.sh
# 客戶端重新配置主節點引數指令碼
# 當一個master由於failover而發生改變時,這個指令碼將會被呼叫,通知相關的客戶端關於master地址已
經發生改變的資訊。
# 以下引數將會在呼叫指令碼時傳給指令碼:
# <master-name> <role> <state> <from-ip> <from-port> <to-ip> <to-port>
# 目前<state>總是“failover”,
# <role>是“leader”或者“observer”中的一個。
# 引數 from-ip, from-port, to-ip, to-port是用來和舊的master和新的master(即舊的slave)通
信的
# 這個指令碼應該是通用的,能被多次呼叫,不是針對性的。
# sentinel client-reconfig-script <master-name> <script-path>
sentinel client-reconfig-script mymaster /var/redis/reconfig.sh # 一般都是由運維來配
置!

多哨兵模式介紹

一個哨兵對redis監控可能會出現問題,可以使用多哨兵模式進行監控,各個哨兵之間會進行監控 這樣就形成了多哨兵模式

哨兵模式優缺點

優點

主從複製的優點他都有

自動切換master 實現叢集高可用,實現故障轉移

缺點

Redis叢集不容易線上擴容

哨兵模式的配置項很多,哨兵模式配置比較麻煩。