redis的復制很簡單,由於資源限制,本例中采用兩台虛擬機,每台虛擬機安裝兩個redis實例,共四個來測試
一、安裝redis
https://www.cnblogs.com/qq931399960/p/10616459.html
二、當前安裝的redis分別為
192.168.102.69:6379 (master)
192.168.102.69:6380 (slave)
192.168.102.52:6379 (slave)
192.168.102.52:6379 (slave)
三、配置主從復制
5.0版本使用REPLICAOF代替了之前版本的SLAVEOF,如果使用5.0及之后版本,則建議新命令REPLICAOF。
1、命令行方式
分別登錄各slave redis命令行,執行auth xxx賦權,執行如下命令(重啟之后無效)
REPLICAOF 192.168.102.69 6379 CONFIG SET masterauth 12345
若取消復制,則執行如下命令即可
REPLICAOF no one
2、配置方式(永久生效,本例中使用配置方式)
redis slave配置文件中添加如下配置,重啟redis
replicaof 192.168.102.69 6379 masterauth 12345
若取消復制,只需要去掉上述配置,重啟即可
四、驗證
1、登錄從實例,查看info
2、登錄主實例,查看info
重啟之后,replication id和offset會被重置
主實例添加key,從實例查詢,已同步,ok
五、配置只有N個連接復制的時候才允許主實例寫操作
個人覺得,若使redis節點高可用,則該項應該使用默認配置,否則可能會出現幾個節點不可用,造成寫操作失敗。
該功能工作原理如下:
1、從實例每秒ping主實例,確認已處理的復制流的數量
2、redis主實例記住最后接收到的從實例ping的時間
3、用戶配置從實例的最小數量在小於指定的最大延遲(秒)時間時可寫。
該功能有兩個配置控制(5.0版本之前replicas改為slaves)
min-replicas-to-write <number of slaves> (默認0) min-replicas-max-lag <number of seconds> (默認10)
在redis master配置文件中添加配置
min-replicas-to-write 4 min-replicas-max-lag 10
意為,當至少4個slave連接master的延遲時間小於10秒時,主實例才可以進行寫操作。
也可以通過命令行在重啟之前生效
127.0.0.1:6379> CONFIG SET min-replicas-to-write 4 OK 127.0.0.1:6379> CONFIG GET min-replicas-to-write 1) "min-replicas-to-write" 2) "4" 127.0.0.1:6379>
登錄master,執行測試
如下為在redis官網獲取到的一些信息
從實例在與主實例的連接斷開后,會自動重連,並且嘗試作為主實例的一個精確副本。其工作機制如下
1、當主從實例正常連接時,主實例發送命令流給從實例來保證數據的一致性
2、由於網絡問題或者檢測到超時等引起的主從連接斷開,從實例將重新連接主實例並嘗試進行部分再同步,也就是說,從實例將獲取在連接斷開期間丟失的命令流。
3、當部分再同步不可實現,從實例將會請求一個全量再同步。其中包括主實例創建一個所有數據的快照,並且發送給從實例,然后繼續發送數據集改變時的命令流。
默認情況下,redis使用高性能,低延遲的異步復制。redis從實例異步的獲取接收到的主實例數據量,因此主實例不用每次都等待從實例處理命令,但是主實例嫩鞏固知道從實例的命令的執行狀態
redis基本復制規則
1、redis使用異步復制,異步進行從實例到主實例的數據處理量的確認
2、主實例可以有多個從實例
3、從實例可以從其他從實例處接受數據,從redis4.0起,所有子從實例都從主實例獲取精確的復制流
4、在主實例側,redis復制是非阻塞的。當一個或者多個從實例執行初始化同步或者部分再同步時,主實例將繼續處理查詢請求。
5、在從實例側,復制也基本上是非阻塞的。當從實例正在執行初始化同步時,它可以使用老版本的數據集處理查詢。另外,可以在從實例中配置當復制流停止后,返回一個錯誤給客戶端。但是在數據初始化同步之后,需要刪除舊數據,加載新數據,在這一時期,從實例將會阻塞所有接收到的連接(對於一個非常大數據集,可能會持續幾秒)。自從redis4.0,可以配置在另外一個線程中刪除舊數據,但是仍然在主線程中加載新的初始化數據,並且阻塞從實例。
6、redis復制可以應用於可擴展性,比如有多個從實例提只讀服務,或者僅僅只是用於數據安全和高可用
7、可以使用復制來避免主實例將全部數據集寫入到磁盤中。這種使用方式一般在主實例中禁止了持久化,但必須謹慎的設置該功能,因為主實例啟動后,將會清空所有數據,如果從實例向主實例獲取數據,那么從實例的數據也將為空
強烈建議在主從實例中都打開持久化。
每個redis主實例都有一個relication id,它由一個大的偽隨機字符串組成,標記數據集的給定描述。每個主實例還具有一個偏移量(offset),這個偏移量會一直增加,即使沒有從節點連接,復制偏移量也會增加,重啟之前replication id不會變化,重啟之后,replication id和offset都會發生變化。一般replciation id和offset來確定主實例的一個准確的版本。
當從實例連接到主實例,從實例通過PSYNC命令來發送他們的最新的舊主實例replication id和offset,使用這種方式,主服務器可以只發送所需的增量部分命令流。但是如果主實例緩沖區沒有足夠的backlog,或者從實例指向了一個位置的歷史replication id,那么將會發生全量再同步。
全量再同步工作原理
主實例啟動一個后台保存進程生成RDB文件,如此同時,開始緩存所有從客戶端獲取的寫命令,當后台保存進程結束,主實例將這個RDB數據庫文件傳送給從實例,從實例將其保存在磁盤,並且加載到內存,之后主實例發送所有緩存的命令給從實例。
SYNC是一個舊的命令,不支持部分再同步,在新版本中已經使用PSYNC代替,考慮到向后兼容,SYNC命令沒有去除
主從連接斷開后,從節點可以自動重新連接主實例。若果主實例接收到多個並發的同步請求,其將只執行一個后台保存進程生成RDB文件,然后將該RDB文件發送給以上並發同步的各請求
Replication id的解釋
如果兩個實例具有相同的replication id和offset,那么他們具有相同的數據集。每次主實例重啟或者從實例提升為主實例,對於這個實例來講,將會產生新的replication id,連接到主實例的從實例將在握手之后繼承其replication id。因此具有相同id 的兩個實例是有關聯的,因為他們可能在不同的
時間點獲取到了相同的數據。對於一個保存有最新數據的給定歷史節點,偏移量作為一個邏輯時間來理解。例如:A和B具有相同的replication id,但是其中一個的偏移量為1000,另外一個偏移量為1023,這意味着第一個實例少執行了一些命令,也可以說,A實例,執行一些命令之后可以達到B實例的狀態。
redis具有兩個replication id的原因在於,提升為主實例的從實例。在故障轉移中,被提升為主實例的從實例仍然需要記住它過去的replication id,因為這個replication id是之前主實例的一個id之一,在這種情況下,其他將與新主實例進行同步的從實例使用之前舊的主實例的replciation id與新的主實例之間可以執行部分同步。這和預期一致,因為當從實例提升為主實例,它將輔id設置為主id,在id轉換時,記錄偏移量,之后選出一個新的隨機replication id,因為一個新的歷史記錄開始。檔處理新從實例連接,主實例將用當前的id和輔id匹配它們的id和offset,簡而言之,故障轉移之后,連接到一個新的主實例的從實例不需要執行一個全量同步。
故障轉移之后改變replication id的原因在於
由於一些分區,有可能舊的主實例仍然作為主實例在工作,保留相同的replication id違背了一個相同id和相同offset意味着它們具有相同的數據集的規則。
只讀從實例
自從2.6版本,從實例默認支持只讀模式,可以通過配置文件中修改slave-read-only來設置,也可以通過命令行config set來設置,前者永久生效。但這並不意味着redis從實例就是嚴格的不能寫,因為一些管理命令,比如DEBUG/CONFIG仍然可以使用,可以通過rename-command指令來關閉相關命令以提高安全性。從實例也可以配置為可寫,但在4.0版本之前,可寫從實例不能兼容expire命令,也即是,使用expire或者其他命令設置一個key的ttl最大值,當key到達了指定時間之后,使用讀命令已經不能獲取到key,但是通過dbsize等命令獲取key的數量時,依然包含了該key並且該key依然在占用內存。redis 4.0 RC3之后版本解決了該問題,並且可寫從實例可以和主實例一樣可以通過ttl剔除過期數據。
自從redis4.0,從實例僅本地可寫,但子從實例始終都是從主實例同步數據,如
A -- >B --> C
上述A為主實例,B為可寫從實例,C為只讀從實例,C中的數據內容將與A一致,C不會不同在B中寫入,但在A中不存在的數據。
Redis復制處理expires
redis使用三種技術來使expire key生效
1、從實例不過期key,他們等待主實例key過期,當主實例key過期,生成一個DEL命令,發送給從實例。
2、由於主控驅動過期,有時可能主實例還沒有能夠提供DEL命令,從實例中還存在邏輯上已經失效的key,此時如果將該key返回給客戶端,這就與邏不符。為了解決這個問題,從實例在不違法數據集一致性的情況下,使用它的邏輯時鍾一遍報告一個key並不只存在於讀取操作中(?),這樣,從實例可以避免上報邏輯上已經過期的key仍然存在。
3、Lua腳本執行期間,不執行key過期,所以整個腳本執行期間,要么一個key不存在,要么一個key一直存在,防止key在腳本執行中間過期。
消息和角色命令
INFO
INFO REPLICATION
ROLE