redis的集羣模式之主從模式(五)

redis的集羣模式

redis的集羣模式有主從同步,哨兵(sentine),cluster模式,以下是主從同步模式的介紹使用,後續補上其它兩種模式


主從同步模式

主從同步也就是讀寫分離,master主庫負責寫操作,slave從庫負責讀操作,slave沒有寫權限。單機的qps有限,實現主從分佈後,請求就分流了,qps就可以提上來,實現水平擴容也容易,直接加從庫slave

缺點:
master掛掉,就失去寫服務,slave掛了不影響其它slave

原理

全量同步

  1. slave啓動時候,會發送一個psync命令給master,如果是這個從庫slave第一次連接,會觸發全量複製,複製master上所有數據
  2. master收到命令,執行bgsave命令,fock子進程生成RDB快照,同時啓用緩衝區,把新的寫請求寫到緩衝區。RDB快照生成後,發送RDB給slave
  3. slave接收到之後,就寫進本地磁盤,然後加載到內存
  4. master快照發送完畢後,就會把緩衝區新增的寫命令以增量同步給slave從庫
  5. 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 "讀服務失效";
}

操作步驟如下:

  1. slave寫入,因爲從庫只能讀,提示寫入失敗

  2. master寫入,slave查看,已同步到slave

  3. 重啓slave,會重新連接master並加載主庫的數據

  4. slave重啓後,master再寫入,slave查看,會同步到slave

  5. 關閉master,執行代碼驗證,失去了master寫服務,slave從庫能繼續讀取,驗證如圖
    代碼執行圖

  6. 重啓master,執行代碼驗證,寫服務恢復,讀服務也正常,驗證如圖
    代碼執行圖2


總結:

  1. master主庫負責寫,slave從庫負責讀
  2. slave首次連接進行初始化,異步和master進行全量同步,同步主庫所有數據,初始化完後,master以AOF形式執行增量同步到slave
  3. master掛了,失去寫服務,從庫正常讀取
  4. slave重啓,會重新連接master,進入之後的增量同步工作

以上就是主從同步的相關內容和使用,有錯誤的地方,請大家指點。測試用的是本機和虛擬機,只有一主一從,實際投產根據實際去調控水平擴容

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章