redis(四)-主從複製

參考資料:
redis 4.x cookbook 中文版;
redis官方文檔
注: 本文redis的版本爲: 5.0.3

redis學習路徑

主從複製:

在沒有哨兵的情況下,redis的主從複製,如果主服務器掛掉之後,需要人工將從服務器晉升;

#使用 replicaof ip 端口 配置此redis的主服務器;
#replicaof <masterip> <masterport>

#redis的主從同步是異步進行的,不需要用戶操作;
#可以設置當主服務器連接的副本服務器個數低於一定數量時,拒絕寫入數據;
#當副本服務器與主服務器丟失連接的時間很短時,副本服務器依然可以從主服務器執行部分重新同步;
#出現斷網情況,副本服務器會自動發起重連,以求與主服務器進行同步;

#配置主服務器的密碼,如果主服務器配置密碼,而副本服務器沒有下面的配置,主服務器將拒絕同步;
#masterauth <master-password>

#當副本服務器正在與主服務器進行同步中,或者與主服務器斷開時,正好有客戶端查詢數據:
#配置爲yes,將給客戶端返回副本服務器存儲的數據,
#(這些數據可能是歷史數據,如果正在進行第一次同步,也許會是空)
#配置爲no,將給查詢數據的連接返回錯誤"SYNC WITH MASTER IN PROGING";
replica-serve-stale-data yes

#配置爲yes時,副本服務器只讀;在redis2.6之前,副本服務器默認只讀;
#如果配置爲no,將會出現寫在副本服務器上的數據,被主從同步後的數據覆蓋;
#配置成只讀以後也不能暴露給外網,這裏只讀只是一個保護層,很容易被攻擊;
#可以通過"rename-command"來隱藏危險(涉及修改服務器或者數據)的命令,只留下讀命令來提高安全性;
replica-read-only yes

#在redis中有兩種同步策略,disk(磁盤)或者socket(直接網絡傳輸)
#目前socket模式僅試驗,所以默認是磁盤同步;
#redis的主從同步其實上是rdb的快照文件的傳輸;
#磁盤(disk)模式,主服務器將會使用子進程來創建一個rdb快照文件到磁盤,當快照文件生成後,
#會通過父進程發送給各個副本(這個動作是增量的,通常只發送上次同步時間之後的數據);
#無盤(socket網絡傳輸)模式,子進程直接與各個副本服務器進行socket連接(可並行),發送數據,
#不生成rdb文件到磁盤;
#在慢磁盤,高速網絡的情況下,無盤更有優勢,但是目前還在實驗中;
#diskless-無盤,所以,設置爲no表示磁盤同步;
repl-diskless-sync no

#開啓無盤同步時,副本服務器與主服務器建立同步連接的延遲時間,單位爲秒;
#這裏有一點很重要,主服務器一旦開始本次同步傳輸後,後面的副本服務器只能等下次同步才能再次同步;
#默認爲5秒;設置爲0時,將不延遲;
repl-diskless-sync-delay 5

#設置副本服務器給主服務器發送ping的間隔,單位爲秒;默認爲10;
repl-ping-replica-period 10 

#設置主從同步的超時時間,注意此處的值,必須大於repl-ping-replica-period,
#如果小於的話傳輸量不大的時候,每次都會檢測到超時;
repl-timeout 60

#配置主從同步時,tcp傳輸是否有延遲;
#選擇yes,意味着不允許tcp延遲,但是這樣redis主服務器將會以少量的數據包占用少量的帶寬傳輸數據;
#這樣tcp雖然不會延遲,但是多批次的發送數據,將會導致數據完整到達副本服務器會出現延時;
#選擇no,將會用更大的帶寬傳輸數據,但是數據完整到達副本服務器的時間會更快;
#在大流量或者高頻次同步時,選擇yes會更好;
#因爲大流量時,可能每次同步花費的時間會更多;
#高頻次時允許延遲可能會出現問題;
repl-disable-tcp-nodelay no

#當有副本服務器斷開後,主服務器就開始累積未同步數據到緩衝區;
#當副本服務器連接到主服務器時,它們使用PSYNC命令來發送舊的主服務器複製ID和它們到目前爲止處理的偏移量.
#這樣,主設備可以只發送所需的增量部分.但是,如果主緩衝區中沒有足夠的積壓(需要的數據比緩衝區多),
#或者如果複製副本引用的是不再已知的歷史記錄(複製ID),則會發生完全重新同步:
#在這種情況下,複製副本將從頭開始獲取數據集的完整副本.
#主機啓動後臺保存進程以生成RDB文件.同時,它開始緩衝從客戶端接收的所有新的寫命令.
#後臺保存完成後,主服務器將數據庫文件傳輸到副本服務器,副本服務器將其保存在磁盤上後將其加載到內存中.
#然後,主服務器將向副本服務器發送所有緩衝的命令.這是作爲命令流完成的,並且與Redis協議本身的格式相同.
#這裏設置的就是這個緩衝區的大小,默認就是1MB;
repl-backlog-size 1mb

#下面這個設置是指,從上次所有副本服務器都斷開後,主服務器有一段時間沒有副本服務器連接,
#將會清除緩衝區積壓的數據;
#單位爲秒;設置爲0時意味着永不釋放積壓數據的緩衝區;
#值得注意的是,副本服務器因爲有可能會被提升爲主服務器然後與其他副本服務器進行部分同步,
#所以副本服務器應該設置爲0;(這裏有個疑問,當副本服務器被提升爲主服務器後,這個字段如何處理?)
Repl-backlog-ttl 3600

#副本優先級,當主服務器掛掉之後,redis-Sentinel(哨兵)將會提升優先級數字最低的稱爲新的主服務器;
#注意,0是特殊優先級,具有此優先級的副本,將永遠不會被提升爲主服務器;
#此設置必須爲整數;默認設置爲100;
replica-priority 100

#下面兩個設置必須同時滿足,否則主服務器將拒絕寫入數據;
#只要下面兩個設置,有一個設置爲0就可以關閉該功能,默認情況下,該功能是關閉的;
#下面的意思是:最少需要3個副本服務器與主服務器之間的ping的最大延遲不能超過10s,才進行寫操作;
min-replicas-to-write 3
min-replicas-max-lag 10

#下面這倆有點難搞,我也沒明白啥意思,反正是跟哨兵有關的;可能是用來監聽副本服務器存活之類的吧;
#有懂得大佬可以說一下...
#replica-announce-ip 5.5.5.5
#replica-announce-port 1234

在redis的每個實例中都會保存自身的信息:

#主服務器信息
127.0.0.1:6379> keys *
1) "key1"
127.0.0.1:6379> info replication
# Replication
#自身角色
role:master
#連接到本主服務器的從服務器數量;
connected_slaves:1
#從服務器的信息:ip,端口,在線狀態,偏移量(相對數據庫中第一個字節),延遲
slave0:ip=127.0.0.1,port=6380,state=online,offset=140,lag=1
#兩個複製id,都是很長的僞隨機字符串;
master_replid:5c1942b0633673e5475144131028209f2aca1746
master_replid2:0000000000000000000000000000000000000000
#主服務器的偏移量
master_repl_offset:140
#第二複製id的偏移量;
second_repl_offset:-1
#複製緩衝區信息:是否活躍,緩衝區大小,緩衝區字節相對數據庫第一個字節的偏移量,緩衝區長度;
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:140

#副本服務器信息
127.0.0.1:6380> slaveof 127.0.0.1 6379
OK
127.0.0.1:6380> keys *
1) "key1"
127.0.0.1:6380> info replication
# Replication
#自身角色
role:slave
#主服務器信息
master_host:127.0.0.1
master_port:6379
master_link_status:up
#上一次同步時間
master_last_io_seconds_ago:3
#主服務器同步進程數
master_sync_in_progress:0
#副本服務器信息:偏移量,優先級,只讀,連接到此服務器的副本服務器;
slave_repl_offset:126
slave_priority:100
slave_read_only:1
connected_slaves:0
#兩個複製id,都是很長的僞隨機字符串;副本服務器的複製id與主服務器保持一致;
master_replid:5c1942b0633673e5475144131028209f2aca1746
master_replid2:0000000000000000000000000000000000000000
#主服務器的偏移量
master_repl_offset:126
#第二複製id的偏移量;
second_repl_offset:-1
#複製緩衝區信息:是否活躍,緩衝區大小,緩衝區字節相對數據庫第一個字節的偏移量,緩衝區長度;
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:126

當主服務器掛掉或斷開連接之後,副本服務器可能會提升成主服務器,然後會重新生成自己的兩個複製id;
因爲在redis系統中,複製id一致,表示是同一個主機的不同角色(master/slave);
如下情況可以解釋爲什麼需要兩個複製id:
當主A,從1,從2組成主從複製;主A因網絡問題斷掉連接,從1升級爲主1,同時加入了從3;
這時候主1需要擔負起從2的複製責任,也要爲從3複製數據;
[從1升級爲主1時,會將自己原本的主複製id放到第二複製id,然後生成一個新複製id,作爲主複製id]
這時,主1給從3複製數據時使用的是新的主複製id;主1給從2複製數據時使用的是原先的複製id(第二個複製id)
於此同時,主A在另一片網絡中還是主服務器;如果從1晉升爲主1後不改變主複製id,就會違背規則:redis中複製id相同,偏移量相同,它們就是同一個數據庫.(偏移量一致是很可能發生的)

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