摘要:本文將演示主從複製如何配置、實現以及實現原理,Redis主從複製三大策略,全量複製、部分複製和立即複製。
本文分享自華為雲社群《Redis主從複製實踐總結》,原文作者:A夢多啦A 。
複製簡介
Redis 作為一門非關係型資料庫,其複製功能和關係型資料庫(MySQL)來說,功能其實都是差不多,無外乎就是實現的原理不同。Redis 的複製功能也是相對於其他的記憶體性資料庫(memcached)所具備特有的功能。
Redis 複製功能主要的作用,是叢集、分片功能實現的基礎;同時也是 Redis 實現高可用的一種策略,例如解決單機併發問題、資料安全性等等問題。
服務介紹
在本文環境演示中,有一臺主機,啟動了兩個 Redis 示例。
實現方式
Redis 複製實現方式分為下面三種方式:
1. 服務啟動時配置
該方式通過在啟動 Redis 服務時,通過命令列引數,進行啟動主從複製功能。該方式的弊端是不能實現配置持久化,當服務停掉之後,啟動服務時,需要新增相同的命令引數。
1.1 master 伺服器事先在 redis.confg 增加 requirepass 項。
requirepass 6379
1.2 啟動從伺服器。
redis-server --port 6380 --replicaof 192.168.2.102 6379
2. 命令列配置
該方式通過使用 redis-cli 進入操作行介面,進行配置。該方式的弊端是不能實現配置持久化,當服務停掉之後,啟動服務需要執行同樣的命令。
2.1 master 伺服器執行。
127.0.0.1:6379> config set requirepass 6379 OK
2.2 從伺服器執行。
127.0.0.1:6380> replicaof 192.168.2.102 6379 OK 127.0.0.1:6380> config set masterauth 6379 OK
3. 配置檔案配置
該方式是通過 redis.conf 配置檔案進行設定,能夠實現配置的持久化,是一種推薦使用的方式。
3.1 配置主伺服器,redis.config。
requirepass 6379
3.2 配置從伺服器,redis.config。
masterauth 6379 replicaof 192.168.2.102 6379
4.配置說明
1.masterauth:設定 redis.confi 連線密碼,如果設定了該值。其他客戶端在連線該伺服器時,需要新增密碼才可以訪問。
2.requirepass:設定主伺服器的連線密碼,和 1 中 masterauth 一致。
3.replicaof:從伺服器連線到伺服器的 IP 地址+埠號。
效果測試
1.主伺服器新增資料。
2.從伺服器獲取資料。
實現原理
// uml圖 @startuml 從伺服器->主伺服器: 1.儲存配置 從伺服器->主伺服器: 2.建立socket連線 從伺服器->主伺服器: 3.傳送ping命令 從伺服器->主伺服器: 4.許可權驗證 從伺服器->主伺服器: 5.同步資料 從伺服器->主伺服器: 6.持續複製資料 @enduml
主從複製主要實現的一個流程如上圖:
1.第一步,從伺服器儲存主伺服器的配置資訊,儲存之後待從伺服器內部的定時器執行時,就會觸發複製的流程。
2.第二步,從伺服器首先會與主伺服器建立一個socket套位元組連線,用作主從通訊使用。後面主伺服器傳送資料給從伺服器也是通過該套位元組進行。
3.第三步,socket套位元組連線成功之後,接著傳送鑑權ping命令,正常的情況下,主伺服器會傳送對應的響應。ping命令的作用是為了,保證socket套位元組是否可以用,同時也是為了驗證主伺服器是否接受操作命令。
4.第四步,接著就是鑑權驗證,判斷從節點配置的主節點連線密碼是否正確。
5.第五步,鑑權成功之後,就可以開始複製資料了。主伺服器此時會進行全量複製,將主服務的資料全部發給從伺服器,從伺服器儲存主伺服器傳送的資料。
6.接下來就是持續複製操作。主伺服器會進行非同步複製,一邊將寫的資料寫入自身,同時會將新的寫命令傳送給從伺服器。
實現策略
Redis主從複製主要分為三種弄策略方式,不同的策略方式都是針對不同的場景下進行使用。三種場景方式分別如下:
1.全量複製。全量複製用在主從複製剛建立時或者從切主伺服器時,從伺服器沒有主伺服器的資料,主伺服器會將自身的資料通過rdb檔案方式傳送給從伺服器,從伺服器會清空自身資料,接著將主伺服器傳送的資料載入到自身中。
// uml圖 @startuml 從伺服器->主伺服器: 1.psync ? -1 主伺服器->從伺服器: 2.fullsync runid offset 從伺服器: 3.儲存 runid offset 主伺服器: 4.執行bgsave生成rdb 主伺服器->從伺服器: 5.傳送rdb 從伺服器: 6.清空自身老資料 從伺服器: 7.載入主伺服器資料 @enduml
2.部分複製。部分複製用在一些異常情況下,例如主從延遲、從服務當機之後重新啟動接收主伺服器傳送的部分資料。
部分複製的實現主要依賴於複製快取區、主服務的runid、主從伺服器各自的複製偏移量(offset)。
複製快取區:主服務在接收寫命令時,會將命令寫入快取區,以便從伺服器在異常情況下,減少資料的丟失。當從伺服器正常連線之後,主伺服器會將快取區內的資料傳送給從伺服器。這裡的快取區是一個長佇列。
主伺服器runid:主伺服器會在每次服務啟動之後,會生成一個唯一的ID,作為自身標識。從伺服器會將該標識儲存起來,傳送部分複製命令時,會使用該runid。
psync runid offset
主從複製各自偏移量:主從服務在建立複製之後,都會有自身的偏移量。從節點會每秒鐘傳送自身複製的偏移量給從節點,主節點在傳送寫命令之後,從節點也會增加自身的複製偏移量。主節點在每次進行了寫命令之後,也會增加自身的偏移量。這裡的偏移量是通過命令的位元組長度累加計算。
3.非同步複製。非同步複製是針對主從建立複製關係之後,主從伺服器持續保持複製關係。
場景問題
1.資料安全。
// 從伺服器只讀 replica-read-only yes // 從伺服器連線密碼 masterauth
2.資料延遲。
預設的情況下主節點存在新資料不會立即傳送給從伺服器,如果開啟,則會理解傳送給從伺服器。預設的時間拒絕與Linux核心。
// 複製延遲 repl-disable-tcp-nodelay yes
3.主從節點連線狀態。
主從節點一旦建立連線之後,會定時模擬成對方的客戶端,檢測對方的服務狀態。主節點可以通過設定repl-ping-replica-period配置引數進行設定。預設的頻率是10s。
從節點咋執行replconf ack {offsetid}時,也會將自身的複製偏移量傳送給主伺服器,主服務根據偏移量進行判斷資料延遲。存在資料延遲就會從複製積壓緩衝區的資料匯中,將對應的資料補發給從節點。