Redis主從模式學習

單機Redis的瓶頸

  • 容量瓶頸( 單臺Redis提供的容量有限 )
  • QPS瓶頸( 單臺Redis能提供的有限 )
  • 機械故障( 單臺redis無法保證高可用 )

主從複製的約定

  • 一個master可以有多個slave
  • 一個slave只能用一個master
  • 數據流向是單向的,master到slave (所以要求一般slave是read-only的,不然就無法保證主從一致性了)

主從配置的兩種方式

slaveof命令(運行中執行)

例如,機器A的ip爲ipA, 機器B的ip爲ipB,機器A上的redis作爲slave,機器B的redis作爲master,如果希望機器A對機器B的redis進行一個主從配置/複製同步的話,那麼就在機器A上執行: slaveof ipB:port (機器A的redis執行完該命令之後,會對機器A的redis進行一個清楚,然後進行數據同步)

如果不再讓機器A作爲機器B的slave的話,可以執行 slaveof no one來斷開主從關係(即使斷開了主從關係,過去同步的數據依然不會清楚)

配置(啓動執行)

可以在配置文件中加入如下命令:

slaveof ip port // 表示作爲哪一個節點的從節點
slave-read-only yes // 表示當前從節點是read-only的
masterauth [password]  // 如果master有密碼的話,那麼需要設置master的密碼

(ps:在master的配置文件中,requirepass [password] 來設置密碼)
(pps: 在redis中,auth password 用於驗證身份, info replication查看主從狀態)

方式 命令 配置
優點 無需重啓 統一配置,方便管理
缺點 不方便管理 需要重啓

*Redis主從模式下的幾個問題

1. 讀寫分離

  • 讀寫分離:讀流量分攤到從節點
    在這裏插入圖片描述

讀寫分離的問題:

  • 複製數據延遲(解決延遲代價很高)

  • 讀到過期的數據

    redis在清理過期數據時,有一個方式是懶惰刪除,即在獲取這個key的時候檢查是否過期,若過期則刪除,而又由於從節點無法主動刪除數據(read-only), 所以如果master沒有及時把過期數據告訴slave的話可能會造成髒讀,redis3.2之後解決了這個問題。

  • 從節點故障

    將從節點上的客戶端進行遷移,成本較高。

2. 主從配置不一致

  • 例如maxmemory不一致,導致主從不一致

3. 規避全量複製

  1. 第一次全量複製

    第一次全量複製不可能避免(減少分片maxmemory, 在低峯的時候進行)

  2. 節點運行ID不匹配

    redis每次啓動時,會有一個run_id,slave會保存master的run_id, 如果master的run_id發生了變化的話,那麼就會觸發一個全量複製。

  3. 複製積壓緩衝區不足

4. 規避複製風暴


主從複製流程

run_id

Redis每次啓動時,都有一個隨機ID來標識Redis,這個隨機ID就是上面通過info命令查看得到的run_id, 查看master節點上的run_id和偏移量:

[root@localhost ~]# redis-cli info server | grep run_id
run_id:7e366f6029d3525177392e98604ceb5195980518
[root@localhost ~]# redis-cli info | grep master_repl_offset
master_repl_offset:0

offset:

偏移量(offset)就是數據寫入量的字節數。

在master節點的Redis上寫入數據時,master就會記錄寫了多少數據,並記錄在偏移量中。

在master上的操作,會同步到salve機器上,slave上的Redis也會記錄偏移量。

當兩臺機器上的偏移量相同時,代表數據同步完成

偏移量是部分複製很重要的依據

查看Redis的偏移量

127.0.0.1:6379> info replication    # 查看複製信息
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.81.101,port=6379,state=online,offset=8602,lag=0
master_repl_offset:8602             # 此時192.168.81.100上的偏移量是8602
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:8601
127.0.0.1:6379> set k1 v1           # 向192.168.81.100寫入數據
OK
127.0.0.1:6379> set k2 v2           # 向192.168.81.100寫入數據
OK
127.0.0.1:6379> set k3 v3           # 向192.168.81.100寫入數據
OK
127.0.0.1:6379> info replication    # 查看複製信息
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.81.101,port=6379,state=online,offset=8759,lag=1
master_repl_offset:8759             # 寫入數據後192.168.81.100上的偏移量是8759
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:8758

master的run_id的改變會觸發全量複製

主從的offset相等則說明一致

psync [run_id] [offset]

表示需要讓run_id的redis將offset之後的數據同步給當前節點…

全量複製

  • master的全部數據同步到slave
  • master在進行同步期間寫的數據也同步到slave

流程:

1. slave -> master:

slave向master發送一個psync ? -1的命令, 因爲第一次不知道master節點的run_id和offset,所以傳的是?和-1

2. master -> slave:

返回 master 的 run_id 和 offset

3. slave保存master傳來的信息

4. master 進行一個bgsave,生成RDB文件

5. master -> slave:

傳輸RDB文件(全量備份),傳輸期間會把“write”的信息存到一個buffer中(repl_back_buffer),這部分就是在傳輸期間會導致不一致的數據,在傳輸完RDB之後會傳輸這部分消息

6. master -> slave:

傳輸buffer中的數據(增量備份)

7. salve清除舊的數據,寫入新數據

在這裏插入圖片描述

全量複製的開銷

  1. bgsave的開銷 (master)
  2. RDB文件進行網絡傳輸的時間 (master)
  3. slave清空數據(slave)
  4. slave加載RDB數據(slave)
  5. 可能的AOF重寫時間 (slave加載完RDB之後,如果開啓了AOF,那麼會進行一個AOF重寫)

部分複製

全量複製開銷太大, 在沒有必要使用全量複製的時候就可以使用部分複製來做.

部分複製其實還是psync [run_id] [offset] , 通知run_id對應的redis把offset之後的數據都同步過來。。master節點在收到這個指令之後,會去查看能否響應這個offset之後的數據(看這個offset是否在維護的範圍內),如果可以響應,那麼就將offset後的部分數據同步給slave…

在這裏插入圖片描述

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