redis的集羣模式
redis的集羣模式有主從同步,哨兵(sentine),cluster模式,以下是主從同步模式的介紹使用,後續補上其它兩種模式
主從同步模式
主從同步也就是讀寫分離,master主庫負責寫操作,slave從庫負責讀操作,slave沒有寫權限。單機的qps有限,實現主從分佈後,請求就分流了,qps就可以提上來,實現水平擴容也容易,直接加從庫slave
缺點:
master掛掉,就失去寫服務,slave掛了不影響其它slave
原理
全量同步
- slave啓動時候,會發送一個psync命令給master,如果是這個從庫slave第一次連接,會觸發全量複製,複製master上所有數據
- master收到命令,執行bgsave命令,fock子進程生成RDB快照,同時啓用緩衝區,把新的寫請求寫到緩衝區。RDB快照生成後,發送RDB給slave
- slave接收到之後,就寫進本地磁盤,然後加載到內存
- master快照發送完畢後,就會把緩衝區新增的寫命令以增量同步給slave從庫
- slave接收相應的增量指令,加載到內存
增量同步
slave從庫初始化完了之後,master的寫命令同步到從庫的過程即是增量同步。增量複製的過程是master每執行一個寫命令就會以AOF形式向slave發送相同的寫命令,增量就像MySQL的Binlog一樣,把日誌增量同步給從服務,slave接收並執行收到的寫命令
從庫流程
slave連接上master,初始化進行全量同步,初始化完了就進入正常工作,增量同步,保持與master數據一致
配置
測試我用的是一臺機子,其中是一個本機windows系統,一個虛擬機centos系統
windows版本:redis-3.2 主庫
centos版本:redis-5.0.5 從庫
由於版本不同,防止同步時候操作rdb報錯,版本選擇向前兼容,windows做主庫,centos做從庫,具體配置內容如下
master配置
G:\>cd redis
放開AOF和設置好aof和rdb存放目錄
dir ./
appendonly yes
設置slave從庫的連接密碼
requirepass 12345
重啓redis服務
G:\redis>redis-server
slave配置
# vi /home/tool/redis-5.0.5/redis.conf
放開AOF和設置好aof和rdb存放目錄
dir ./
appendonly yes
配置文件新增slave從庫配置,格式爲 slaveof <master的IP> <redis端口>
slaveof 192.168.XX.XX 6379
設置連接master的密碼
masterauth 12345
重啓redis服務
# service redis stop
# service redis start
配置完之後,在master查看主從信息,如下圖所示,redis是主庫,連接進來slave從庫一個
在slave查看主從信息,如下圖所示,redis是從庫,主庫ip,端口,已同步偏移量
操作演示
master端
G:\redis>redis-cli
127.0.0.1:6379> auth 12345 #客戶端登錄,需要密碼登錄,驗證
OK
127.0.0.1:6379> keys *
(empty list or set)
slave啓動之後,set值寫入,slave端查看
127.0.0.1:6379> set username toegg
OK
127.0.0.1:6379> keys *
1) "username"
這個時候slave斷開後,等slave重啓服務連入之後,set值寫入,slave端查看
127.0.0.1:6379> set age 18
OK
關閉master的服務,執行代碼驗證,失去了寫服務,slave端讀取正常
127.0.0.1:6379> SHUTDOWN
not connected> QUIT
重啓master服務
G:\redis>redis-server
127.0.0.1:6379> auth 12345 #客戶端登錄,需要密碼登錄,驗證
OK
127.0.0.1:6379> keys *
1) "username"
2) "age"
slave端
[root@localhost /]# redis-cli
127.0.0.1:6379> keys *
(empty list or set)
寫入,因爲從庫只能讀,提示寫入失敗
127.0.0.1:6379> set username toegg
(error) READONLY You can't write against a read only replica.
主庫寫完,slave查看
127.0.0.1:6379> keys *
1) "username"
127.0.0.1:6379> get username
"toegg"
重啓服務,重新連接主庫,同時數據加載進內存
127.0.0.1:6379> SHUTDOWN
not connected> QUIT
[root@localhost /]# service redis start
Starting Redis server...
16658:C 28 May 2020 12:40:04.327 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
16658:C 28 May 2020 12:40:04.328 # Redis version=5.0.5, bits=64, commit=00000000, modified=0, pid=16658, just started
16658:C 28 May 2020 12:40:04.328 # Configuration loaded
[root@localhost /]# redis-cli
127.0.0.1:6379> keys *
1) "username"
127.0.0.1:6379> get username
"toegg"
重啓服務後,主庫端再寫入,slave再查看
127.0.0.1:6379> keys *
1) "age"
2) "username"
127.0.0.1:6379> get age
"18"
127.0.0.1:6379> keys *
1) "age"
2) "username"
代碼層,用在關閉master服務後驗證時執行。這裏注意寫入要連接到master端,讀取則是連接到slave端,實際生產,要根據請求去做相應分發到不同連接端處理業務邏輯。本例只是簡單列出相對應測試代碼,如下:
//master寫服務驗證
$master = new Redis();
try{
$master->connect('192.168.XX.XX', 6379);
$master->auth("12345"); #auth驗證
$result = $master->keys('*');
echo "master keys :"; print_r($result);
$master->set("work", "docker");
$result = $master->keys('*');
echo "master keys :"; print_r($result);
}catch(Exception $exc){
echo "寫服務失效";
}
//slave寫服務驗證
$slave = new Redis();
try{
$slave->connect('127.0.0.1', 6379);
$result = $slave->keys('*');
echo "slave keys :"; print_r($result);
}catch(Exception $exec){
echo "讀服務失效";
}
操作步驟如下:
-
slave寫入,因爲從庫只能讀,提示寫入失敗
-
master寫入,slave查看,已同步到slave
-
重啓slave,會重新連接master並加載主庫的數據
-
slave重啓後,master再寫入,slave查看,會同步到slave
-
關閉master,執行代碼驗證,失去了master寫服務,slave從庫能繼續讀取,驗證如圖
-
重啓master,執行代碼驗證,寫服務恢復,讀服務也正常,驗證如圖
總結:
- master主庫負責寫,slave從庫負責讀
- slave首次連接進行初始化,異步和master進行全量同步,同步主庫所有數據,初始化完後,master以AOF形式執行增量同步到slave
- master掛了,失去寫服務,從庫正常讀取
- slave重啓,會重新連接master,進入之後的增量同步工作
以上就是主從同步的相關內容和使用,有錯誤的地方,請大家指點。測試用的是本機和虛擬機,只有一主一從,實際投產根據實際去調控水平擴容