Redis學習 主從複製(master-replica)架構介紹及實現

如下筆記以及實驗皆出自於 中華石杉大佬的視頻教學,我跟着作了實驗,而且把課上的筆記整理了一下。html

redis的主從架構

在一個項目中使用redis必然是由於咱們想要作成高併發,redis是整個大型的緩存架構中,支撐高併發的很是重要的一個環節, 可是光redis是不夠的。java

redis不能支撐高併發的瓶頸就是 單機 單機的redis不可能說QPS超過10萬+,除非你的機器性能特別好,維護作的好, 並且你的總體的操做不能太複雜。node

因此讀寫分離通常來講是用來支撐高併發,寫的請求比較少,大量的請求都是讀,那麼redis的主從架構就是比較好的選擇, 主從架構 -> 讀寫分離 -> 水平擴容支撐讀高併發,主節點用來寫,從節點用來讀。git

PS:在我使用的5.0.4版本中slave這個術語已經被replica代替了,嗯~ 這個單詞的意思確實有點很差聽哈。反正官方已經改掉了,我也就全換掉了。github

master-replica

redis replication(主從複製)的核心機制

  • redis採用異步方式複製master節點數據到replica節點,不過redis 2.8開始,replica node會週期性地確認本身每次複製的數據量
  • 一個master node是能夠配置多個replica node的
  • replica node也能夠鏈接其餘的replica node
  • replica node作複製的時候,是不會block master node的正常工做的
  • replica node在作複製的時候,也不會block對本身的查詢操做,它會用舊的數據集來提供服務; 可是複製完成的時候,須要刪除舊數據集,加載新數據集,這個時候就會暫停對外服務了
  • replica node主要用來進行橫向擴容,作讀寫分離,擴容的replica node能夠提升讀的吞吐量

redis 主從複製的核心原理

當啓動一個 replica node 的時候,它會發送一個 PSYNC 命令給 master node。redis

若是 replica node 使用 PSYNC 初次鏈接到 master node,那麼會觸發一次 full resynchronization 全量複製。此時 master 會啓動一個後臺線程, 開始生成一份 RDB 快照文件,同時還會將從客戶端 client 新收到的全部寫命令緩存在內存中。RDB 文件生成完畢後, master 會將這個 RDB 發送給 replica, replica 會先寫入本地磁盤,而後再從本地磁盤加載到內存中,接着 master 會將內存中緩存的寫命令發送到 replica,replica 也會同步這些數據。replica node 若是跟 master node 有網絡故障,斷開了鏈接,會自動重連,鏈接以後 master node 僅會複製給 replica 部分缺乏的數據。spring

流程圖

什麼是PSYNC命令呢

簡單來講PSYNC完成的使命就是判斷從服務器是否須要全量複製仍是增量複製,畢竟每次由於一點點網路波動從新鏈接主節點,都要全量複製,很是的低效緩存

PSYNC格式:安全

PSYNC runid offsetbash

runid

每一個Redis服務器都會有一個代表本身身份的ID。在PSYNC中發送的這個ID是指以前鏈接的Master的ID,若是沒保存這個ID, PSYNC的命令會使用」PSYNC ? -1」 這種形式發送給Master,表示須要全量複製。

offset(複製偏移量)

在主從複製的Master和replica雙方都會各自維持一個offset。Master成功發送N個字節的命令後會將Master的offset加上N, replica在接收到N個字節命令後一樣會將replica的offset增長N。Master和replica若是狀態是一致的那麼它的的offset也應該是一致的。

全量複製流程

  • 主節點master收到全量複製的命令後 執行 bgsave ,在本地生成一份 rdb 快照文件;並使用一個緩衝區(稱爲複製緩衝區)記錄從如今開始執行的全部寫命令 redis配置文件中有個參數:client-output-buffer-limit replica 256MB 64MB 60

若是在複製期間,內存緩衝區超過60秒一直消耗超過 64MB,或者一次性超過 256MB,那麼中止複製,複製失敗。後兩個參數是配合使用的,假如:消耗超過64MB 一直持續了59秒,可是60秒的時候不超過64MB了,那麼就保持鏈接繼續複製。

  • master node 將 rdb 快照文件發送給 replica node,若是 rdb 複製時間超過 60秒(redis配置文件參數:repl-timeout),那麼 replica node 就會認爲複製失敗, 能夠適當調大這個參數(對於千兆網卡的機器,通常每秒傳輸 100MB,6G 文件,極可能超過 60s)

  • master node 在生成 rdb 時,會將全部新的寫命令緩存在內存中,在 replica node 保存了 rdb 以後,再將新的寫命令複製給 replica node; 從節點首先清除本身的舊數據,而後載入接收的RDB文件

  • 主節點將前述複製緩衝區中的全部寫命令發送給從節點,從節點執行這些寫命令,若是從節點開啓了AOF,則會觸發bgrewriteaof的執行,從而保證AOF文件更新至主節點的最新狀態

部分複製流程(增量複製)

  • 若是全量複製過程當中,master-replica 網絡鏈接斷掉,那麼 replica 從新鏈接 master 時,會觸發增量複製。

  • master 直接從本身的 backlog 中獲取部分丟失的數據,發送給 replica node,默認 backlog 就是 1MB。

  • master 就是根據 replica 發送的 psync 中的 offset 來從 backlog 中獲取數據的。

例如,若是主節點的offset是1000,而從節點的offset是500,那麼部分複製就須要將offset爲501-1000的數據傳遞給從節點

完整的複製流程

replica node 啓動時,會在本身本地保存 master node 的信息,包括 master node 的host和ip,可是複製流程沒開始。

replica node 內部有個定時任務,每秒檢查是否有新的 master node 要鏈接和複製,若是發現,就跟 master node 創建 socket 網絡鏈接; 而後 replica node 發送 ping 命令給 master node。若是 master 設置了 requirepass(就是redis的登陸密碼), 那麼 replica node 必須發送 masterauth 的口令過去進行認證;master node 第一次執行全量複製,將全部數據發給 replica node; 而在後續,master node 持續將寫命令,異步複製給 replica node。

redis-master-slave-replication-detail

  • 第一步:從節點服務器內部維護了兩個字段,即masterhost和masterport字段,用於存儲主節點的ip和port信息。

  • 第二步:創建socket鏈接,即從節點每秒1次調用複製定時函數replicationCron(),若是發現了有主節點能夠鏈接,便會根據主節點的ip和port,建立socket鏈接

  • 第三步:身份驗證,若是從節點中設置了masterauth選項,則從節點須要向主節點進行身份驗證;沒有設置該選項,則不須要驗證; 從節點進行身份驗證是經過向主節點發送auth命令進行的,auth命令的參數即爲配置文件中的masterauth的值;若是主節點設置密碼的狀態, 與從節點masterauth的狀態一致(一致是指都存在,且密碼相同,或者都不存在),則身份驗證經過,複製過程繼續;若是不一致,則從節點斷開socket鏈接,並重連。

  • 第四步:數據同步,就是全量複製或者增量複製,並且在複製階段繼續有寫命令會存在主節點內存中,後續會異步發送給replica node

replica node若是跟master node有網絡故障,斷開了鏈接,會自動重連。master若是發現有多個replica node都來從新鏈接, 僅僅會啓動一個rdb save操做,用一份數據服務全部replica node。

主從複製的斷點續傳

從redis 2.8開始,就支持主從複製的斷點續傳,若是主從複製過程當中,網絡鏈接斷掉了,那麼能夠接着上次複製的地方,繼續複製下去,而不是從頭開始複製一份

master node會在內存中常見一個backlog,master和replica都會保存一個replica offset還有一個master id,offset就是保存在backlog中的。 若是master和replica網絡鏈接斷掉了,replica會讓master從上次的replica offset開始繼續複製

可是若是沒有找到對應的offset,那麼就會執行一次resynchronization(全量複製)

無磁盤化複製

master 在內存中直接建立 RDB,而後發送給 replica,不會在本身本地落地磁盤了。只須要在配置文件中開啓 repl-diskless-sync yes 便可。

repl-diskless-sync yes

# 等待 5s 後再開始複製,由於要等更多 replica 從新鏈接過來
repl-diskless-sync-delay 5
複製代碼

過時key處理

replica不會過時key,只會等待master過時key。若是master過時了一個key,或者經過LRU淘汰了一個key,那麼會模擬一條del命令發送給replica。

heartbeat

主從節點互相都會發送 heartbeat 信息。

master 默認每隔 10秒 發送一次 heartbeat,replica node 每隔 1秒 發送一個 heartbeat。

master持久化對於主從架構的安全保障的意義

若是採用了主從架構,那麼建議必須開啓master node的持久化! 如何實現redis的持久化

並且不建議使用replica node做爲master node的數據熱備若是你關掉master的持久化,可能在master宕機重啓的時候數據是空的,而後可能一通過複製,replica node數據也丟了

另外,master 的各類備份方案,也須要作。萬一本地的全部文件丟失了,從備份中挑選一份 rdb 去恢復 master,這樣才能確保啓動的時候,是有數據的 即便採用了後續講解的高可用機制,replica node能夠自動接管master node,可是也可能sentinal尚未檢測到master failure,master node就自動重啓了, 仍是可能致使上面的全部replica node數據清空故障。

實現redis的主從複製架構(一主一從)

node hostname IP port
master node eshop-cache01 192.168.0.30 6379
replica node eshop-cache02 192.168.0.31 6379

在除了安裝redis時配置的參數外,從節點還須要額外配置如下內容

配置主節點(eshop-cache01)配置文件

  • 在配置文件中修改 bind 127.0.0.1bind 192.168.0.30 本身自己的ip地址

或者配置成 bind 0.0.0.0 若是配置成自己ip地址,則須要在使用redis的客戶端時,使用redis-cli -h 192.168.0.30進入客戶端了

  • 配置認證密碼 requirepass redis-pass , 就是登陸redis 的登陸密碼

配置從節點(eshop-cache02)配置文件

  • 在配置文件中修改 bind 127.0.0.1bind 192.168.0.31 本身自己的ip地址

  • 配置 replicaofreplicaof eshop-cache01 6379 eshop-cache01我是在 master node /etc/hosts 中配置了映射本機的ip

replicaof 填寫主節點的ip 和 端口號

  • 開啓安全認證 masterauth redis-pass 填寫的就是 master node 的登陸密碼,須要在主節點配置文件中配置

  • 強制讀寫分離 replica-read-only yes 這個默認是開啓的

能夠自由選擇是否開啓AOF持久化

測試主從複製(讀寫分離)

前後啓動主節點和從節點的redis實例,進入主節點客戶端,set k1 v1 而後在從節點中看是否能讀取到數據,讀取到數據即表明成功。

master-replica

info replication命令能夠查看自己的角色是主節點 仍是 從節點

擴展閱讀

相關文章
相關標籤/搜索