天天看點

Redis - Redis叢集及主從複制、哨兵模式

Redis主從複制

主從複制,是指将一台Redis伺服器的資料,複制到其他的Redis伺服器。前者稱為主節點

(master/leader),後者稱為從節點(slave/follower);

資料的複制是單向的,隻能由主節點到從節點

Master以寫為主,Slave 以讀為主。

預設情況下,每台Redis伺服器都是主節點。

且一個主節點可以有多個從節點(或沒有從節點),但一個從節點隻能有一個主節點。

主從複制的作用

1、資料備援:主從複制實作了

資料的熱備份

,是持久化之外的一種資料備援方式。

2、故障恢複:當主節點出現問題時,可以由從節點提供服務,實作快速的故障恢複;實際上是一種服務的備援。

3、負載均衡:在主從複制的基礎上,配合

讀寫分離

,可以由

主節點提供寫服務

,由

從節點提供讀服務

(即寫Redis資料時應用連接配接主節點,讀Redis資料時應用連接配接從節點),分擔伺服器負載;尤其是在寫少讀多的場景下,通過多個從節點分擔讀負載,可以大大提高Redis伺服器的并發量。

4、高可用(叢集)基石:除了上述作用以外,主從複制還是哨兵和叢集能夠實施的基礎,是以說主從複制是Redis高可用的基礎。

一般來說,要将Redis運用于工程項目中,隻使用一台Redis是萬萬不能的(當機),原因如下:

1、從結構上,單個Redis伺服器會發生單點故障,并且一台伺服器需要處理所有的請求負載,壓力較

大。

2、從容量上,單個Redis伺服器記憶體容量有限,就算一台Redis伺服器記憶體容量為256G,也不能将所有記憶體用作Redis存儲記憶體,一般來說,

單台Redis最大使用記憶體不應該超過20G

電商網站上的商品,一般都是一次上傳,無數次浏覽的,說專業點也就是"多讀少寫"。對于這種場景,我們可以使如下這種架構:

Redis - Redis叢集及主從複制、哨兵模式

主從複制,讀寫分離!80%的情況下都是進行讀操作,用于減緩伺服器的壓力,架構中經常使用。至少要保證

一主二從

,在公司中,主從複制是必須要使用的。

檢視目前庫的資訊

127.0.0.1:6379> info replication   # 檢視目前庫的資訊
# Replication
role:master  					   # 角色master - 表示是主機
connected_slaves:0 				   # 0表示沒有從機
master_replid:b63c90e6c501143759cb0e7f450bd1eb0c70882a
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
           

Linux - Redis叢集環境搭建

這裡是在一台伺服器上進行叢集,并且配置模式為

一主二從

,是以複制3份

redis.conf

檔案,并别改名為

redis79.conf

redis80.conf

redis81.conf

,指令如下:

先進入到redis.conf所在目錄下

cp redis.conf redis79.conf
cp redis.conf redis80.conf
cp redis.conf redis81.conf
           

在複制完配置檔案之後,需要對每個配置檔案進行修改(因為是在同一台伺服器裡,即單機多服務,如果是多台伺服器可以不用修改),這裡以

redis79.conf

為例

port 6379        					            # 啟動端口
daemonzie yes    								# 守護态運作
pidfile /var/run/redis_6379.pid 			    # pid_file
logfile "6379.log"                              # 日志檔案名
dbfilename dump6379.rdb                         # rdb檔案名
           

啟動3個redis服務

redis-server kconfig/redis79.conf
redis-server kconfig/redis80.conf
redis-server kconfig/redis81.conf
           

檢視程序資訊

ps -ef|grep redis
           
Redis - Redis叢集及主從複制、哨兵模式

配置一主二從

分别連接配接用戶端,建議開三個Linux遠端連接配接來操作

redis-cli -p 6379
redis-cli -p 6380
redis-cli -p 6381
           

使用指令進行配置

真實開發中,從主配置應該在配置檔案中配置,這樣的話是永久的,這裡使用的是指令,隻是暫時的!

因為預設情況下,每台Redis伺服器都是主節點,是以我們隻需要配置從節點即可。通俗點說,就是讓從機去認主機(小弟認大哥)。

我們這裡是讓6380和6381作為從機,是以操作這兩個即可,以6380為例:

127.0.0.1:6380> SLAVEOF 127.0.0.1 6379   # SLAVEOF host 6379,找主機(認大哥)
OK
127.0.0.1:6380> info replication         # 檢視目前庫的資訊
# Replication
role:slave  							 # slave,目前角色是從機
master_host:127.0.0.1   				 # 主機IP
master_port:6379						 # 主機端口
master_link_status:up
master_last_io_seconds_ago:3
master_sync_in_progress:0
slave_repl_offset:14
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:a81be8dd257636b2d3e7a9f595e69d73ff03774e
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:14
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:14
           

修改配置檔案進行配置

修改從機的

redis.conf

配置檔案,真實開發中的配置方式。

# 将注釋打開,配置主機ip和端口
# replicaof <masterip> <masterport>
replicaof 127.0.0.1 6379
# 如果主機有密碼,則還需配置密碼,打開注釋
# masterauth <master-password>
masterauth 123456
           

讀寫分離細節

主機可以寫,但是從機不能寫隻能讀。主機中的所有資訊和資料,都會自動被從機儲存。

當主機斷開連接配接,從機依舊連接配接到主機,但是沒有寫操作,如果主機回來了,從機依舊可以直接擷取到主機寫的資訊。

當從機斷開連接配接,主機進行了寫操作,此時從機再連接配接回來,從機還是可以讀取到斷開這段時間主機寫的資訊。

如果是使用指令行來配置主從的話,主機重新開機之後依然是主機,但是從機重新開機之後不再是從機,需要從新配置,一旦變回從機,依舊可以從主機中擷取資訊。

從機複制原理

Slave 啟動成功連接配接到 master 後會發送一個sync同步指令。

Master 接到指令,啟動背景的存盤程序,同時收集所有接收到的用于修改資料集指令,在背景程序執行完畢之後,

master将傳送整個資料檔案到slave,并完成一次完全同步

全量複制:而slave服務在接收到資料庫檔案資料後,将其存盤并加載到記憶體中。

增量複制:Master 繼續将新的所有收集到的修改指令依次傳給slave,完成同步。

但是隻要是重新連接配接master,一次完全同步(全量複制)将被自動執行! 我們的資料一定可以在從機中看到!

連結清單式主從複制
Redis - Redis叢集及主從複制、哨兵模式

哨兵模式

上面所說的兩種

主從方式

在實際開發中都不會用。

如果主機down掉了,這個時候可不可以選擇一個一個從機變成主機(謀權篡位)呢?

哨兵模式

出來之前,可以通過手動的方式來實作。

使用

SLAVEOF no one

指令可以讓自己變成主機,其他從機就可以手動連接配接到最新的這個主機(手動連接配接)。如果原來的主機回來了,沒辦法,也隻能重新配置和連接配接了。

哨兵模式概述

即自動選舉主機的模式。

主從切換技術的方法是:當主伺服器當機後,需要手動把一台從伺服器切換為主伺服器,這就需要人工幹預,費事費力,還會造成一段時間内服務不可用。這不是一種推薦的方式,更多時候,我們優先考慮

哨兵模式

。Redis從2.8開始正式提供了Sentinel(哨兵) 架構來解決這個問題。

謀權篡位的自動版,能夠背景監控主機是否故障,如果故障了根據投票數

自動将從庫轉換為主庫

哨兵模式是一種特殊的模式,首先Redis提供了哨兵的指令,哨兵是一個獨立的程序,作為程序,它會獨立運作。其原理是哨兵通過發送指令,等待Redis伺服器響應,進而監控運作的多個Redis執行個體。

Redis - Redis叢集及主從複制、哨兵模式

這裡的哨兵有兩個作用:

1、通過發送指令,讓Redis伺服器傳回監控其運作狀态,包括主伺服器和從伺服器。

2、當哨兵監測到master當機,會自動将slave切換成master,然後通過釋出訂閱模式通知其他的從服

務器,修改配置檔案,讓它們切換主機。

然而一個哨兵程序對Redis伺服器進行監控,可能會出現問題,為此,我們可以使用多個哨兵進行監控。各個哨兵之間還會進行監控,這樣就形成了多哨兵模式。(類似于Eureka叢集)

Redis - Redis叢集及主從複制、哨兵模式

假設主伺服器當機,哨兵1先檢測到這個結果,系統并不會馬上進行failover過程,僅僅是哨兵1主觀的認為主伺服器不可用,這個現象成為

主觀下線

。當後面的哨兵也檢測到主伺服器不可用,并且數量達到一定值時,那麼哨兵之間就會進行一次投票,投票的結果由一個哨兵發起,進行failover[故障轉移]操作。切換成功後,就會通過釋出訂閱模式,讓各個哨兵把自己監控的從伺服器實作切換主機,這個過程稱為

客觀下線

哨兵模式配置

文中是使用

一主二從

的方式,是以哨兵也可以選擇3個(如果伺服器是學生機的配置,可能承受不了,則可以隻做一個)。

分别給

6379

6380

6381

配置一個sentinel.conf。即

sentinel26379.conf

sentinel26380.conf

sentinel26381.conf

這裡以

sentinel26380.conf

為例進行配置:

port 26379       # 哨兵端口
daemonize yes    # 守護态運作
logfile "26379.log"  # 日志檔案
dir "./"         # 哨兵工作目錄
bind 127.0.0.1   # 綁定ip 多個ip使用空格隔開

# 告訴sentinel去監聽位址為ip:port的一個master,這裡的master-name可以自定義,quorum是一個數字,指明當有多少個sentinel認為一個master失效時,master才算真正失效
# sentinel monitor <master-name> <ip> <redis-port> <quorum>
sentinel monitor mymaster 127.0.0.1 6379 2

# 設定連接配接master和slave時的密碼,注意的是sentinel不能分别為master和slave設定不同的密碼,是以master和slave的密碼應該設定相同。如果沒有密碼,可以不寫。
# sentinel auth-pass <master-name> <password>
sentinel auth-pass mymaster 123456

# 指定多少毫秒之後 主節點沒有應答哨兵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 180000
           

配置完畢之後,分别啟動sentinel

redis-sentinel kconfig/sentinel23679.conf
redis-sentinel kconfig/sentinel23680.conf
redis-sentinel kconfig/sentinel23681.conf
           

此時,哨兵模式配置完畢,此外還可以再配置檔案裡配置一些額外資訊如:

# 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高可用之哨兵模式Sentinel配置與啟動(五)

繼續閱讀