文章目錄
- 拓撲
- 一主一從
- 相關問題
- 一主多從
- 相關問題
- 樹形主從結構
- 相關問題
- 主從復制原理
- 復制流程
- psync 命令
- 命令解析
- replicatonid
- offset
- 總結
- 運行流程
拓撲
若干個節點之間按照什么樣的方式來進行組織連接
一主一從
- 都可以讀,從節點可以幫主節點分擔一部分的壓力
- 只有主節點能寫
解決了單點并發量不高和單點可能出現故障的情況
相關問題
- 寫請求太多
但是如果寫請求太多,也會給主節點造成一些壓力。
- 此時我們可以通過關閉主節點的
AOF
,只在從節點上開啟AOF
的方式降低主節點的壓力 AOF
需要將數據寫到硬盤上,而寫硬盤比寫內存要慢上不少,因此讓主節點就只寫內存,這樣主節點能支持的并發量就更大了
- 數據丟失
但是這種設定方式,有一個嚴重的缺陷:主節點一旦掛了,不能讓他自動重啟(如果自動創奇,此時沒有AOF
文件,就會丟失數據,進一步的主從結構,會把從節點的數據也給刪了)
改進辦法:當主節點掛了之后,就需要讓主節點從從節點這里獲取到 AOF
文件,然后再啟動
一主多從
在實際開發中,讀請求的數量是遠遠超過寫請求的,此時我們就可以用一主多從的結構
- 主節點上的數據發生改變,就會把改變的數據同時同步給所有的從節點
相關問題
- 網絡帶寬壓力
隨著從節點個數的增加,同步一條數據,就需要傳輸多次,主節點的網絡帶寬要壓力是很大的
解決辦法:使用樹形主從結構
樹形主從結構
可以有效的緩解主節點網絡帶寬壓力大的情況
- 這樣就把同步數據的網絡壓力,均攤到多個節點上了,主節點就不需要那么高的網絡帶寬了
相關問題
- 同步時間變長
一旦數據進行修改了,同步數據的延時是比一主多從結構要長的,
主從復制原理
復制流程
- 先保存主節點的 IP 和端口(在一個變量中)
- 然后建立一個
TCP
連接(三次握手) - 通過
ping
命令,驗證主節點是否能夠正常工作(站在應用程序角度)- 上面的
TCP
三次握手,驗證的是通信雙方能否正常讀寫數據,而不是能否正常工作(站在系統層面) - 檢查路修好了沒(三次握手);檢查這輛車子是不是好的(
ping
)
- 上面的
redis
主節點如果開啟了密碼,就會觸發“權限認證”
上面的都是準備操作,最關鍵的復制操作就是第五步和第六步
- 同步數據集:相當于全量同步。在進行同步的一瞬間,一次性把所有的數據都給我
- 命令持續復制:相當于增量同步。后續再有數據變化,繼續進行同步
psync 命令
redis
提供了一個 psync
命令,完成數據同步的過程
- 不需要我們手動執行,
redis
服務器會在建立好主從同步關系之后,自動執行psync
- 從節點負責執行
pysnc
,從節點從主節點這邊拉取數據(從節點主動要,而不是主節點主動給)
語法格式為:
PSYNC replicationid offset
命令解析
replicatonid
replicationid
:理解成復制 Id,是主節點在啟動的時候生成的(從節點變成主節點的時候也會生成,下面有談到)- 即使是同一個主節點,每次重啟,生成的
replication id
都是不同的 - 從節點和主節點建立了復制關系,就會從主節點這邊獲取到
replication id
- 此處討論的都是一個主節點,多個從節點。
- 即使是同一個主節點,每次重啟,生成的
我們可以通過 info
命令,獲取到 replication id
info replication
- 一般情況下,
replid2
是用不到的
使用到
replid2
的情況
- 有一個主節點 A,還有一個從節點 B。 A 生成
replid
,B 獲取到 A 的replid
- 如果 A 和 B 通信過程中出現了一些網絡抖動,B 可能就會認為 A 掛了,于是 B 就會自己成為主節點,給自己生成一個
replid
- 此時 B 也會記得舊的
replid
,就是通過replid2
- 后續網絡穩定了,B 還可以根據
replid2
重新回到 A 的懷抱
- 需要手動干預。不過哨兵機制可以自動完成這個過程
offset
可以理解成偏移量,主節點和從節點上都會維護偏移量(整數)
- 主節點上:主節點會收到很多的修改操作的命令,每個命令都要占據幾個字節,主節點會把這些修改命令的字節數進行累加,就會得到一個逐漸變大的數字
- 從節點上:描述了現在從節點這里的數據同步到哪里了
- 如果從節點和主節點這里的偏移量一樣,就說明同步完成了
- 從節點(
slave
)每秒鐘上報自身的復制偏移量給主節點
總結
replicationid
和 offset
共同描述了一個“數據集合”
如果發現兩個機器,replicationid
一樣,offset
也一樣,就可以認為這兩個 redis
機器上存儲的數據就是完全一樣的
- 主服務器看做銀行總行,從服務器看做分行
- 總行里面有很多客戶,每個客戶都有一個自己的賬戶,用
replicationid
表示賬戶,offset
表示訂單數量 - 比如張三的賬戶
replicationid
是123123
,他此時轉出 100 元,總行實時記錄,訂單數量offset
為 1,隨后同步給分行
- 總行里面有很多客戶,每個客戶都有一個自己的賬戶,用
- 只要總行和分行里面,賬戶號
replicationid
和訂單數量offset
一樣,就說明兩邊的數據是一樣的,如果分行的訂單數量offset
比總行的少,那就說明還沒同步完成
運行流程
-
FULLRESYNC
:全量數據的同步 -
CONTINEU
:增量數據的同步 -
ERR
:比較老版本的redis
服務器不支持psync
(可以用sync
,會阻塞redis
服務器) -
psync
這里可以從主節點獲取全量數據,也可以獲取一部分數據,主要就是看offset
這里的進度offset
寫作-1
,就是獲取全量數據- 獲取所有數據是最穩妥的,但是會比較低效
offset
寫具體的正整數,則是從當前偏移量位置來進行獲取- 如果從節點之前已經從主節點這里復制過一部分數據了,就只需要把新的之前沒復制過的數據搞過來即可
不是從節點索要哪部分,主節點就一定給哪部分。主節點會自行判斷,看當前是否方便給哪部分數據,不方便就只能給全量數據了
什么時候進行全量復制?
- 首次和主節點進行數據同步
- 主節點不方便進行部分復制的時候
什么時候進行增量復制?
- 從節點之前已經從主節點上復制過數據了。因為網絡抖動或者從節點重啟了,從節點需要重新從主節點這邊同步數據,此時看看能不能只同步一笑部分(大部分數據都是一致的)
**