Redis主從複製實踐總結

複製簡介

Redis 作爲一門非關係型數據庫,其複製功能和關係型數據庫(MySQL)來說,功能其實都是差不多,無外乎就是實現的原理不同。Redis 的複製功能也是相對於其他的內存性數據庫(memcached)所具備特有的功能。

Redis 複製功能主要的作用,是集羣、分片功能實現的基礎;同時也是 Redis 實現高可用的一種策略,例如解決單機併發問題、數據安全性等等問題。

服務介紹

在本文環境演示中,有一臺主機,啓動了兩個 Redis 示例。

角色 IP 端口號 密碼
從服務 192.168.2.102 6380 6380
主服務 192.168.2.102 6379 6379

實現方式

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.主服務器添加數據。

Snipaste_2021-03-09_22-24-08

2.從服務器獲取數據。

Snipaste_2021-03-09_22-24-23

實現原理

Snipaste_2021-03-09_22-41-46
// 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}時,也會將自身的複製偏移量發送給主服務器,主服務根據偏移量進行判斷數據延遲。存在數據延遲就會從複製積壓緩衝區的數據匯中,將對應的數據補發給從節點。

推薦閱讀

Redis實現列表數據查詢設計

Redis緩存數據一致性解決方案分析

Redis事務處理機制分析與總結

Redis數據類型應用場景總結


本文分享自微信公衆號 - 卡二條的技術圈(qq1005349393)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

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