Redis主從同步,讀寫分離設定
本文介紹使用Redis的主從同步功能(master, slave),使程式實現讀寫分離,避免io瓶頸,提高資料讀寫效率。
Redis支援一個master伺服器對多個slave伺服器同步,同步使用釋出/訂閱機制。
1個master對多個slave,還可以進行分層,每個slave下可以再同步slave,擴充套件成樹狀結構。
Redis 主從同步設定
Redis預設的埠是6379,我們為了不影響原有Redis,使用新的埠
master 配置 redis_master.conf
port 6300
requirepass 123456
masterauth 123456
daemonize yes
slave1 配置 redis_slave1.conf 設為master的slave
port 6301
slaveof 127.0.0.1 6300
requirepass 123456
masterauth 123456
daemonize yes
slave2 配置 redis_slave2.conf 設為master的slave
port 6302
slaveof 127.0.0.1 6300
requirepass 123456
masterauth 123456
daemonize yes
daemonize 表示後臺啟動。
requirepass 為主機認證密碼。
masterauth
因後面需要演示主從切換,因此三組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 1858 Ss 3:55 0:00.01 redis-server *:6302
root 1849 Ss 3 :54 0:00.01 redis-server *:6301
root 1842 Ss 3:54 0:00.02 redis-server *:6300
進入master,設定key abc的值為123
redis-cli -p 6300
127.0.0.1:6300> auth 123456
OK
127.0.0.1:6300> set abc 123
OK
127.0.0.1:6300> 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
127.0.0.1:6300> set abc 456
OK
127.0.0.1:6300> get abc
"456"
檢查slave1, slave2是否同步
slave1:
127.0.0.1:6301> get abc
"456"
slave2:
127.0.0.1:6302> get abc
"456"
Redis主從切換
在執行過程中,如果master出現問題,我們可以通過設定,把另一臺slave機自動設為master使用。這裡主要用到Redis的sentinel功能來實現主從切換。
sentinel1.conf
port 26301
sentinel monitor master 127.0.0.1 6300 2
sentinel auth-pass master 123456
logfile "/tmp/sentinel.log"
daemonize yes
sentinel2.conf
port 26302
sentinel monitor master 127.0.0.1 6300 2
sentinel auth-pass master 123456
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 2643 Ss 4:28 0:00.02 redis-server *:26302 [sentinel]
root 2636 Ss 4:28 0:00.02 redis-server *:26301 [sentinel]
Redis日誌可以看到,啟動成功開始監控
Running mode=sentinel, port=26301.
Sentinel ID is 3a23343948cd7f26662ccba1d01b92955311ef52
+monitor master master 127.0.0.1 6300 quorum 2
+slave slave 127.0.0.1:6301 127.0.0.1 6301 @ master 127.0.0.1 6300
+slave slave 127.0.0.1:6302 127.0.0.1 6302 @ master 127.0.0.1 6300
Running mode=sentinel, port=26302.
Sentinel ID is ce0ee2af6b454205a3e475763945f505a10a7d6a
+monitor master master 127.0.0.1 6300 quorum 2
+slave slave 127.0.0.1:6301 127.0.0.1 6301 @ master 127.0.0.1 6300
+slave slave 127.0.0.1:6302 127.0.0.1 6302 @ master 127.0.0.1 6300
+sentinel sentinel 3a23343948cd7f26662ccba1d01b92955311ef52 127.0.0.1 26301 @ master 127.0.0.1 6300
+sentinel sentinel ce0ee2af6b454205a3e475763945f505a10a7d6a 127.0.0.1 26302 @ master 127.0.0.1 6300
終止master,測試主從切換
kill master程序後,sentinel判斷master失效,執行主從切換處理。
日誌如下:
+failover-state-reconf-slaves master master 127.0.0.1 6300
+slave-reconf-sent slave 127.0.0.1:6301 127.0.0.1 6301 @ master 127.0.0.1 6300
+config-update-from sentinel 3a23343948cd7f26662ccba1d01b92955311ef52 127.0.0.1 26301
+switch-master master 127.0.0.1 6300 127.0.0.1 6302
+slave slave 127.0.0.1:6301 127.0.0.1 6301 @ master 127.0.0.1 6302
+slave slave 127.0.0.1:6300 127.0.0.1 6300 @ master 127.0.0.1 6302
-odown master master 127.0.0.1 6300
+slave-reconf-inprog slave 127.0.0.1:6301 127.0.0.1 6301 @ master 127.0.0.1 6300
+slave-reconf-done slave 127.0.0.1:6301 127.0.0.1 6301 @ master 127.0.0.1 6300
+failover-end master master 127.0.0.1 6300
+switch-master master 127.0.0.1 6300 127.0.0.1 6302
+convert-to-slave slave 127.0.0.1:6300 127.0.0.1 6300 @ master 127.0.0.1 6302
從日誌可以看出,主從切換執行了以下操作:
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,所以更新失敗。
127.0.0.1:6300> set abc 888
(error) READONLY You can't write against a read only slave.
slave2 更新key abc為888
127.0.0.1:6302> set abc 888
OK
127.0.0.1:6302> get abc
"888"
原master,slave1檢查是否同步
原master
127.0.0.1:6300> get abc
"888"
slave1
127.0.0.1:6301> get abc
"888"
經檢查,主從切換後,slave2作為新的master,其他伺服器作為slave,可正常使用。