天天看點

Redis主從同步,讀寫分離設定

本文介紹使用Redis的主從同步功能(master, slave),使程式實作讀寫分離,避免io瓶頸,提高資料讀寫效率。

Redis支援一個master伺服器對多個slave伺服器同步,同步使用釋出/訂閱機制。

1個master對多個slave,還可以進行分層,每個slave下可以再同步slave,擴充成樹狀結構。

Redis 主從同步設定

Redis預設的端口是6379,我們為了不影響原有Redis,使用新的端口

master 配置 redis_master.conf

port 
requirepass 
masterauth 
daemonize yes
           

slave1 配置 redis_slave1.conf 設為master的slave

port 
slaveof  
requirepass 
masterauth 
daemonize yes
           

slave2 配置 redis_slave2.conf 設為master的slave

port 
slaveof  
requirepass 
masterauth 
daemonize yes
           

daemonize 表示背景啟動。

requirepass 為主機認證密碼。

masterauth 為從機通路主機驗證密碼,需要與主機的requirepass一緻。

因後面需要示範主從切換,是以三組conf的驗證密碼都一緻。

Redis 主從同步測試

依次啟動master, slave1, slave2

redis-server redis_master.conf
redis-server redis_slave1.conf
redis-server redis_slave2.conf
           

執行後檢視是否啟動成功

ps aux|grep redis
root    Ss  :  : redis-server *: 
root    Ss  :  : redis-server *: 
root    Ss  :  : redis-server *: 
           

進入master,設定key abc的值為123

redis-cli -p 
:> auth 
OK
:> set abc 
OK
:> get abc
"123"
           

分别進入slave1, slave2檢查是否同步資料

slave1:

redis-cli -p 6301
127.0.0.1:6301> auth 123456
OK
127.0.0.1:6301> get abc
"123"
127.0.0.1:6301>
           

slave2:

redis-cli -p 6302
127.0.0.1:6302> auth 123456
OK
127.0.0.1:6302> get abc
"123"
127.0.0.1:6302>
           

進入master修改key abc的值為456

:> set abc 
OK
:> get abc
"456"
           

檢查slave1, slave2是否同步

slave1:

:> get abc
"456"
           

slave2:

:> get abc
"456"
           

Redis主從切換

在運作過程中,如果master出現問題,我們可以通過設定,把另一台slave機自動設為master使用。這裡主要用到Redis的sentinel功能來實作主從切換。

sentinel1.conf

port 
sentinel monitor master   
sentinel auth-pass master 
logfile "/tmp/sentinel.log"
daemonize yes
           

sentinel2.conf

port 
sentinel monitor master   
sentinel auth-pass master 
logfile "/tmp/sentinel.log"
daemonize yes
           

sentinel monitor master 127.0.0.1 6300 2 中的 2 表示有2個以上的sentinel服務檢測到master失效,才會執行主從切換。

啟動兩個sentinel程序

redis-server sentinel1.conf --sentinel
redis-server sentinel2.conf --sentinel

ps aux|grep redis
root    Ss  : : redis-server *: [sentinel]  
root    Ss  : : redis-server *: [sentinel] 
           

Redis日志可以看到,啟動成功開始監控

Running mode=sentinel, port=.
Sentinel ID is 3a23343948cd7f26662ccba1d01b92955311ef52
+monitor master master   quorum 
+slave slave    @ master  
+slave slave    @ master  

Running mode=sentinel, port=.
Sentinel ID is ce0ee2af6b454205a3e475763945f505a10a7d6a
+monitor master master   quorum 
+slave slave    @ master  
+slave slave    @ master  

+sentinel sentinel 3a23343948cd7f26662ccba1d01b92955311ef52   @ master  
+sentinel sentinel ce0ee2af6b454205a3e475763945f505a10a7d6a   @ master  
           

終止master,測試主從切換

kill master程序後,sentinel判斷master失效,執行主從切換處理。

日志如下:

+failover-state-reconf-slaves master master  
+slave-reconf-sent slave :   @ master  
+config-update-from sentinel a23343948cd7f26662ccba1d01b92955311ef52   
+switch-master master    
+slave slave :   @ master  
+slave slave :   @ master  
-odown master master  
+slave-reconf-inprog slave :   @ master  
+slave-reconf-done slave :   @ master  
+failover-end master master  
+switch-master master    
+convert-to-slave slave :   @ master  
           

從日志可以看出,主從切換執行了以下操作:

1.将slave2切換為新的master,redis_slave2.conf 中的 slaveof 127.0.0.1 6300 被自動删除。

2.将redis_slave1.conf的 slaveof 127.0.0.1 6300 自動更新為 slaveof 127.0.0.1 6302,使用slave2作為新的master。

3.原master重新開機動後,會作為slave使用,redis_master.conf會自動加入slaveof 127.0.0.1 6302。

原master重新開機後進行主從同步測試

原master更新key abc為888,因為現在已經是slave,是以更新失敗。

:> set abc 
(error) READONLY You can't write against a read only slave.
           

slave2 更新key abc為888

:> set abc 
OK
:> get abc
"888"
           

原master,slave1檢查是否同步

原master

:> get abc
"888"
           

slave1

:> get abc
"888"
           

經檢查,主從切換後,slave2作為新的master,其他伺服器作為slave,可正常使用。

繼續閱讀