1. 程式人生 > >Redis主從複製,讀寫分離及sentinel監控的使用

Redis主從複製,讀寫分離及sentinel監控的使用

在有redis基礎的前提下,你肯定會發現redis真的很強大很實用,至少我是這麼覺得的。廢話不多說,本文將會簡單說明redis叢集中主從複製,讀寫分離的實現,以及監控運維工具sentinel的使用。

1.redis的主從配置說明

主從複製在redis中的實現非常簡單,redis持久化的實現原理是rdb記憶體快照配合aof日誌檔案兩種方式,本質上只需要將rdb的dump檔案和aof日誌檔案在redis叢集中共享就可以實現redis叢集,從而達到負載的作用。另外redis主從有兩種方式,分別是:

1)一個master跟著多個slave


2)master只跟著一個slave1,slave1跟著另外一個slave2,於此同理


兩種方式相比較而言,第二種會相對好一點,因為當master宕機的時候,只需要將master切換到slave1即可,redis叢集中其他的slave不需要做任何改變。而對於第一種方式而言,相對來說就略微麻煩一點,因為在所有slave間選擇其一作為新任master之後,剩餘的slave需要指向新的master。

那接下來使用方式二進一步說明redis主從複製的配置。

此處使用了虛擬機器配置了三臺同一Host不同埠的redis伺服器,分別是:

192.168.137.201:6379(master) 

192.168.137.201:6380 (slave1)

192.168.137.201:6381 (slave2)

2.redis主從複製讀寫分離的實現

從官網下載redis下來之後,在redis目錄下官方自帶有一份redis.conf配置檔案,埠預設為6379。作為master,可以將rdb記憶體快照的設定遮蔽掉,交給其他slave分擔此部分的IO,但對於aof日誌檔案則應該保留在master,因為在master和slave之間是通過rbd+aof進行資料同步的,aof的粒度細度高,而master資料肯定是最新的,所以將aof開通在master下是最適當的。所以配置master的conf關閉rdb和開啟aof即可。

關閉master(6379)中的rbd快照:註釋掉以下三行即可

save 900 1      // 900內,有1條寫入,則產生快照 
save 300 1000   // 如果300秒內有1000次寫入,則產生快照
save 60 10000  // 如果60秒內有10000次寫入,則產生快照

開啟aof日誌功能:

appendonly yes

另外備註一下配置aof的幾個選項:

appendfilename "appendonly.aof"
Aof同步三種選擇方式說明:
appendfsync always   # 每1個命令,都立即同步到aof. 安全,速度慢
appendfsync everysec # 折衷方案,每秒寫1次
appendfsync no      # 寫入工作交給作業系統,由作業系統判斷緩衝區大小,統一寫入到aof. 同步頻率低,速度快,
no-appendfsync-on-rewrite  yes: # 正在匯出rdb快照的過程中,要不要停止同步aof
auto-aof-rewrite-percentage 100 #aof檔案大小比起上次重寫時的大小,增長率100%時,重寫
auto-aof-rewrite-min-size 64mb #aof檔案,至少超過64M時,重寫

另外將埠為6380和6381的兩臺slave的conf檔案(此處為了便於區分,分別取名為redis6380.conf和redis6381.conf)中的slaveof master host port開啟,之後設定為slaveof master 192.168.137.201 6379。這樣設定之後,就已經是將6380設定成是6379的slave,而對於6379而言,預設即為master角色。由於master的rdb功能關閉了,需要在其中一個slave中開啟rdb功能,另外為了避免redis叢集中資料不同步,需要將slave設定為只讀,由master負責可讀可寫,而slave僅能讀取,這樣就即能保證redis叢集中的資料同步,又可以實現redis的讀寫分離。

設定6380的conf檔案:開啟rdb,關閉aof,並且設定為只讀和設定成6379的slave。

port 6380
pidfile /var/run/redis_6380.pid
dbfilename dump6380.rdb
dir /var/redis/
save 900 1      // 900內,有1條寫入,則產生快照 
save 300 1000   // 如果300秒內有1000次寫入,則產生快照
save 60 10000  // 如果60秒內有10000次寫入,則產生快照
appendonly no # 是否開啟 aof日誌功能
slaveof 127.0.0.1 6379
slave-read-only yes

啟動master:

./bin/redis-server ./redis.conf

在/var/redis目錄下可以看到自動生成了一個appendonly.aof檔案。啟動一個客戶端連線6379伺服器./bin/redis-cli -h 127.0.0.1 -p 6379 ,接著輸入info replication檢視master資訊:


可以看到role為master,且連線的slave為0個。

接著啟動slave6380:


同理啟動一個slave6380的客戶端連線,並且輸入info replication檢視:


此時很明顯可以看到當前6380伺服器角色是slave,並且是master的IP和埠為127.0.0.1:6379.

不難理解回過頭在master中再次輸入info replication可以發現connectioned-slave為1.


來檢驗一下master和slave6380之間的資料是否同步:在master中set幾個key,在salve6380中檢視是否能訪問得到



反過來檢視一下/var/redis下的aof和dump檔案:


還有一個上面設定了slave為只讀狀態,測試一下往slave中寫入是否能成功:


上圖很好的表明了到此步之後已經設定好了redis的主從複製,以及讀寫分離。

同理的另外一個6381slave配置和6380差不多,將6381的rdb也關閉了即可:

port 6381
pidfile /var/run/redis_6381.pid
dbfilename dump6381.rdb
dir /var/redis/
#save 900 1      // 900內,有1條寫入,則產生快照 
#save 300 1000   // 如果300秒內有1000次寫入,則產生快照
#save 60 10000  // 如果60秒內有10000次寫入,則產生快照
appendonly no # 是否開啟 aof日誌功能
slaveof 127.0.0.1 6380
slave-read-only yes


連線上分slave6381之後如上圖所示,其為slave角色,且其master為6380.


在slave6380中又可以查看出其為slave為角色,並且其master為6379,還有6381又是其slave。

測試6381slave是否同步資料:


至此,通過配置檔案conf配置redis主從複製到此就順利成功了,另外如果希望在不斷開redis執行的狀態下更改master和slave,還可以是config命令來實現:

修改一天slave為master

1)設定該redis不做其他redis的slave

命令:slaveof no one

2)修改其為readonly為no

其他的slave再指向新的master

命令:slaveof ip port

3.sentienl監控的使用

sentienl的作用就是在master宕機的時候,由sentienl來切換新的master。

其工作原理是:在指定的連線超時次數時,確認master為宕機狀態,根據slave的優先順序,選擇優先順序最高的slave,將其更改為master,並且將其他的slave改為指向該新的master上。

sentienl的幾個配置引數:

sentinel monitor def_master 127.0.0.1 6379 1  
sentinel auth-pass def_master 密碼 
##master被當前sentinel例項認定為“失效”的間隔時間  
##如果當前sentinel與master直接的通訊中,在指定時間內沒有響應或者響應錯誤程式碼,那麼  
##當前sentinel就認為master失效(SDOWN,“主觀”失效)  
##<mastername> <millseconds>  
##預設為30秒  
sentinel down-after-milliseconds def_master 30000  
  
##當前sentinel例項是否允許實施“failover”(故障轉移)  
##no表示當前sentinel為“觀察者”(只參與"投票".不參與實施failover),  
##全域性中至少有一個為yes  
sentinel can-failover def_master yes  

其中需要特別說明的是最後一個sentinel can-failover mastername yes引數,這個在2.6版本之前需要指定這個引數,其作用是在多個sentinel存在的時候,發揮作用切換master時誰具有能力去切換。在2.8版本之後就不需要再指定這個引數了,因為本來這個引數只需要隨便一個,有一個sentienl來執行就行。

為了更好的演示sentienl的效果將slave2也指向6379,先斷掉所有redis程序:


更改slave6381的conf檔案,然後啟動三臺伺服器。檢視master狀態:


在下載下來的redis目錄下也帶有一份sentinel.conf檔案,做以下修改:

sentinel monitor mymaster 127.0.0.1 6379 1
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1

對master啟動sentinel監控:


現在測試一下將master6379模擬一下宕機的情況,shutdown一下:


過了30秒之後可以看到sentienl監控如下資訊:


檢視此時的6381,已經被切換為master了


如果先指定哪個slave優先切換為master,可以更改各自的conf的slave優先順序屬性值slave-priority,預設為100.