Redis 主從複製與哨兵優化部署解析

weixin_50345481發表於2020-12-19


前言

通過部署主從設定可以有效解決Redis在服務運營中遇到的讀壓力問題,但同時又會產生主從之間不能及時狀態轉換的情況,優化配置哨兵模式即可解決這一難題。


一 Redis 主從結構剖析

1.1 應用挑戰

Redis雖然讀取寫入的速度都特別快,但是也會產生讀壓力特別大的情況。為了分擔讀壓力,Redis支援主從複製,保證主資料庫的資料內容和從資料庫的內容完全一致。

1.2 結構分類

Redis的主從結構可以採用一主多從或者級聯結構,Redis主從複製可以根據是否是全量分為全量同步和增量同步。

在這裡插入圖片描述

1.2.1 全量同步

Redis全量複製一般發生在Slave初始化階段,這時Slave需要將Master上的所有資料都複製一份。

具體步驟如下:

1.從伺服器連線主伺服器,傳送SYNC命令;
2.主伺服器接收到SYNC命名後,開始執行BGSAVE命令生成RDB檔案並使用緩衝區記錄此後執行的所有寫命令;
3.主伺服器BGSAVE執行完後,向所有從伺服器傳送快照檔案,並在傳送期間繼續記錄被執行的寫命令;
4.從伺服器收到快照檔案後丟棄所有舊資料,載入收到的快照;
5.主伺服器快照傳送完畢後開始向從伺服器傳送緩衝區中的寫命令;
6.從伺服器完成對快照的載入,開始接收命令請求,並執行來自主伺服器緩衝區的寫命令;

在這裡插入圖片描述

1.2.2 增量同步

Redis增量複製是指Slave初始化後開始正常工作時主伺服器發生的寫操作同步到從伺服器的過程。

增量複製的過程主要是主伺服器每執行一個寫命令就會向從伺服器傳送相同的寫命令,從伺服器接收並執行收到的寫命令。

1.2.3 Redis主從同步策略流程

主從剛剛連線的時候,進行全量同步;全同步結束後,進行增量同步。當然,如果有需要,slave 在任何時候都可以發起全量同步。

redis 策略是:無論如何,首先會嘗試進行增量同步,如不成功,要求從機進行全量同步。

1.2.4 主從複製的目的:

為了讓主資料庫中的資料複製給從資料庫,保證主資料庫與從資料庫的一致性,使客戶端從主與備資料庫讀取無差別,可以幫助主資料庫減輕負載壓力,也解決單點故障問題。

二 Redis專案部署

2.1 專案圖示

一主兩備

在這裡插入圖片描述

2.2 部署準備

2.2.1 裝置配置

一臺主伺服器   master :20.0.0.10
兩臺備伺服器   slave1 :20.0.0.11
             slave2 :20.0.0.12

裝置重新命名

[root@server1 ~]# hostnamectl set-hostname master
[root@server1 ~]# bash
[root@server2 ~]# hostnamectl set-hostname slave1
[root@server2 ~]# bash
[root@client1 ~]# hostnamectl set-hostname slave2
[root@client1 ~]# bash

2.3 部署流程

2.3.1 首先完成Redis基礎安裝配置

面向所有裝置伺服器
新增redis-5.0.4.tar.gz安裝包

1.關閉防火牆

[root@master ~]# systemctl stop firewalld  
[root@master ~]# setenforce 0  關閉核心防護

2.解壓縮

[root@master ~]# tar zxvf redis-5.0.4.tar.gz   
[root@master ~]# cd redis-5.0.4/
[root@master redis-5.0.4]# make 配置安裝
[root@master redis-5.0.4]# make DREFIX=/usr/local/redis install
更改安裝路徑可以用make PREFIX=安裝路徑 install
[root@master redis-5.0.4]# cd

3.建立連結

[root@master ~]# ln -s /usr/local/redis/bin/* /usr/local/bin/    
[root@master ~]# cd redis-5.0.4/utils/    
[root@master utils]# ls -lh    檢視安裝指令碼
[root@master utils]# ./install_server.sh    執行指令碼
[root@master utils]# netstat -anpt | grep redis   檢視埠狀態

在這裡插入圖片描述
在這裡插入圖片描述

以上完成Redis的基礎安裝配置

2.3.2 完成Redis在主從複製服務配置

在主伺服器(master)上

編輯配置檔案

[root@master utils]# cd
[root@master ~]# vi /etc/redis/6379.conf 
[root@master ~]# /etc/init.d/redis_6379 restart   服務重啟
修改新增
bind 0.0.0.0                     修改監聽地址為0.0.0.0
daemonize yes                    開啟守護程式
logfile /var/log/redis_6379.log  修改日誌檔案目錄
dir /var/lib/redis/6379          修改工作目錄
appendonly yes                   開啟AOF持久化功能

在這裡插入圖片描述
在這裡插入圖片描述

在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
在從伺服器(slave1.slave2)上

編輯配置檔案

[root@slave1 utils]# vi /etc/redis/6379.conf 
[root@slave1 utils]# /etc/init.d/redis_6379 restart  服務重啟
修改新增
bind 0.0.0.0                 修改監聽地址為0.0.0.0
appendonly yes               開啟AOF持久化功能
replicaof 20.0.0.10 6379     增加一個同步master節點IP和埠

在這裡插入圖片描述

在這裡插入圖片描述

在這裡插入圖片描述

在master伺服器上檢視
驗證主從效果

[root@master ~]# tail -f /var/log/redis_6379.log 

在這裡插入圖片描述

在slave1,slave2上
檢視效果,日誌記錄

[root@slave1 ~]# tail -f /var/log/redis_6379.log 

在這裡插入圖片描述
在這裡插入圖片描述

檢視主從同步
在master伺服器上

[root@master ~]# vi /var/log/redis_6379.log 

在這裡插入圖片描述

2.3.2.1 測試主從資料複製功能

在master伺服器上

[root@master ~]# redis-cli         進入資料庫
127.0.0.1:6379> set k aa           新增k鍵值為aa
OK                                 操作成功輸出返回OK
127.0.0.1:6379> get k              獲取k的鍵值
"aa"                               輸出返回值aa
127.0.0.1:6379> info replication   資訊複製,狀態資訊
# Replication
role:master      狀態:主伺服器
connected_slaves:2    連線節點2個
slave0:ip=20.0.0.11,port=6379,state=online,offset=2753,lag=1  節點0,ip地址20.0.0.11,埠:6379
slave1:ip=20.0.0.12,port=6379,state=online,offset=2753,lag=0
master_replid:b442ee024c9aa96b2cf043fdae81248f9a07eed2
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2753
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:2753

在這裡插入圖片描述

在slave1上

[root@slave1 ~]# redis-cli        進入資料庫
127.0.0.1:6379> get k             獲取k的鍵值
"aa"                              輸出返回值aa
127.0.0.1:6379> info replication  資訊複製,狀態資訊
# Replication
role:slave                        狀態:從伺服器
master_host:20.0.0.10             主伺服器:ip地址為20.0.0.10
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:3033
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:b442ee024c9aa96b2cf043fdae81248f9a07eed2
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:3033
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:3033

在slave2上

[root@slave2 ~]# redis-cli 
127.0.0.1:6379> get k
"aa"
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:20.0.0.10
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:3467
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:b442ee024c9aa96b2cf043fdae81248f9a07eed2
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:3467
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:29
repl_backlog_histlen:3439

2.3.2.2 驗證主伺服器下線後出現的情況

在master伺服器上
模擬主伺服器故障下線

[root@master ~]# /etc/init.d/redis_6379 stop      關閉服務
[root@master ~]# tail -f /var/log/redis_6379.log  檢視日誌

在這裡插入圖片描述

在slvae1從伺服器檢視現象

[root@slave1 ~]# tail -f /var/log/redis_6379.log 檢視日誌
[root@slave1 ~]# redis-cli                       進入資料庫
127.0.0.1:6379> get k                            獲取k的鍵值                    
"aa"                                             輸出返回值aa            
127.0.0.1:6379> info replication               資訊複製,狀態資訊
# Replication
role:slave                                    狀態:從伺服器
master_host:20.0.0.10

在這裡插入圖片描述
在這裡插入圖片描述

在slave2上

在這裡插入圖片描述

在這裡插入圖片描述
發現主伺服器下線,從伺服器狀態不會自動轉換為master,但資料會轉移過來,讀取不受影響

解決優化方法:
通過哨兵功能可以實現在主伺服器失效時,主從的狀態自動轉換

先恢復到之前狀態
master上
恢復上線

[root@master ~]# /etc/init.d/redis_6379 start      服務啟動
[root@master ~]# tail -f /var/log/redis_6379.log   檢視日誌
[root@master ~]# redis-cli                         進入資料庫
127.0.0.1:6379> info replication            資訊複製,狀態檢視
# Replication
role:master          主服務 
connected_slaves:2   連線2個伺服器
slave0:ip=20.0.0.12,port=6379,state=online,offset=84,lag=1
slave1:ip=20.0.0.11,port=6379,state=online,offset=84,lag=0
master_replid:087088c1aa398b11c1e4759e93eb8abb6bc277e2
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:84
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:84
127.0.0.1:6379> set k1 bb      新增k1鍵值為bb
OK
127.0.0.1:6379> get k1         獲取k1的鍵值
"bb"

在這裡插入圖片描述

在slvae1從伺服器上

[root@slave1 ~]# tail -f /var/log/redis_6379.log 檢視日誌
[root@slave1 ~]# redis-cli 
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:20.0.0.10
master_port:6379
master_link_status:up
master_last_io_seconds_ago:8
master_sync_in_progress:0
slave_repl_offset:542
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:087088c1aa398b11c1e4759e93eb8abb6bc277e2
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:542
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:542
127.0.0.1:6379> get k1     獲取k1的鍵值
"bb"                                   

在這裡插入圖片描述

2.3.3 哨兵模式原理

2.3.3.1 概述

哨兵(sentinel) 是一個分散式系統,用於對主從結構中的每臺伺服器進行監控,當出現故障時通過投票機制選擇新的master並將所有slave連線到新的master。所以整個執行哨兵的叢集的數量不得少於3個節點。

2.3.3.2 哨兵模式的作用

1.監控

不斷的檢查master和slave是否正常執行。
master存活檢測、master與slave執行情況檢測

2.通知(提醒)

當被監控的伺服器出現問題時,向其他(哨兵間,客戶端)傳送通知。

3.自動故障轉移

斷開master與slave連線,選取一個slave作為master,將其他slave連線到新的master,並告知客戶端新的伺服器地址

注意:

哨兵也是一臺redis伺服器,只是不提供資料服務哨兵的啟動依賴於主從模式,所以須把主從模式安裝好的情況下再去做哨兵模式,所有節點上都需要部署哨兵模式,哨兵模式會監控所有的redis工作節點是否正常,當master出現問題的時候,因為其他節點與主節點失去聯絡,因此會投票,投票過半就認為這個master的確出現問題,然後會通知哨兵間,然後從slaves中選取一個作為新的master

2.3.4 哨兵部署流程

在master伺服器上

編輯哨兵模式的配置檔案

[root@master ~]# vi redis-5.0.4/sentinel.conf 
修改新增
protected-mode no               關閉保護模式
daemonize yes                   指定sentine1為後臺啟動,開啟守護程式
logfile "/var/log/sentinel.log" 指定日誌存放路徑
dir /var/lib/redis/6379         指定資料庫存放路徑

sentinel monitor mymaster 20.0.0.10 6379 2     
指定幾個哨兵(slave)檢測主伺服器故障,才會進行故障遷移(主伺服器ip地址,埠號,slave數)

sentinel down-after-milliseconds mymaster 3000  
 判定伺服器down掉的時間週期,預設30000毫秒(30秒)
 
sentinel failover-timeout mymaster 100000
故障節點的最大超時時間為100000毫秒(100秒)

在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述

在這裡插入圖片描述

拷貝檔案到slave1,slave2上

[root@master ~]# scp redis-5.0.4/sentinel.conf root@20.0.0.11:/root/redis-5.0.4
[root@master ~]# scp redis-5.0.4/sentinel.conf root@20.0.0.12:/root/redis-5.0.4

在這裡插入圖片描述

啟動哨兵模式

先啟master伺服器,後啟slave伺服器

[root@master ~]# redis-sentinel redis-5.0.4/sentinel.conf &
[1] 69742
[root@slave1 ~]# redis-sentinel redis-5.0.4/sentinel.conf &
[1] 69460
[root@slave2 ~]# redis-sentinel redis-5.0.4/sentinel.conf &
[1] 61944

在master伺服器上

1.檢視日誌

[root@master ~]# tail -f /var/log/sentinel.log 

在這裡插入圖片描述
2.檢視程式狀態

[root@master ~]# ps aux | grep redis
[root@master ~]# ps aux | grep sentinel

在這裡插入圖片描述
表明哨兵服務已經啟動

3.遠端登入資料庫檢視哨兵狀態

[root@master ~]# redis-cli -h 20.0.0.10 -p 26379 info sentinel
[root@master ~]# redis-cli -h 20.0.0.10 -p 6379 info replication

在這裡插入圖片描述

2.3.4.1 模擬主伺服器出現問題down下來,檢視從伺服器狀態變化

在master伺服器上

[root@master ~]# /etc/init.d/redis_6379 stop  停止服務
[root@master ~]# ps aux | grep redis        檢視程式狀態

在這裡插入圖片描述

在從伺服器上進行日誌檢視

[root@slave1 ~]#  tail -f /var/log/sentinel.log 

在這裡插入圖片描述
發現master狀態轉移到從slave1上

在slave2檢視遠端登入檢視哨兵資訊

[root@slave2 ~]# redis-cli -h 20.0.0.11 -p 26379 info sentinel

在這裡插入圖片描述

2.3.4.2 檢視之前配置的哨兵檢測的主伺服器地址情況

在slave1上

[root@slave1 ~]# vi redis-5.0.4/sentinel.conf 

在這裡插入圖片描述
在master伺服器上
在這裡插入圖片描述
發現的配置地址變化,在自動切換主狀態時也會自動變更檢測地址

2.3.4.3 檢視當原master伺服器恢復上線時,狀態變化

在master伺服器上

[root@master ~]# /etc/init.d/redis_6379 start  服務啟動
[root@master ~]# ps aux | grep redis           檢視程式埠狀態
[root@master ~]# tail -f /var/log/sentinel.log 檢視日誌檔案

在這裡插入圖片描述
在這裡插入圖片描述
在slave2上
檢視資料庫哨兵狀態

[root@slave2 ~]# redis-cli -h 20.0.0.11 -p 26379 info sentinel

在這裡插入圖片描述

發現在原主伺服器出現上線後,master狀態並不會再次轉換重新到自己上,這一點不同於vrrp服務,原因vrrp有優先順序設定,此處服務沒有。


總結

通過以上對Redis服務運用所遇到的相關問題,運用vrrp相似設定部署主從,哨兵模式來達到優化服務操作。

相關文章