部分同步的實現
部分重同步功能由以下三個部分構成:
復制偏移量
執行復制的雙方——主服務器和從服務器會分別維護一個復制偏移量:
- 主服務器每次向從服務器傳播N個字節的數據時,就將自己的復制偏移量的值加上N;
- 從服務器每次收到主服務器傳播來的N個字節的數據時,就將自己的復制偏移量的值加上N;
通過對比主從服務器的復制偏移量,程序可以很容易地知道主從服務器是否處于一致狀態:
- 如果主從服務器處于一致狀態,那么主從服務器兩者的偏移量總是相同的;
- 相反,如果主從服務器兩者的偏移量并不相同,那么說明主從服務器并未處于一致狀態。
如下面的情況:
假設從服務器A在斷線之后就立即重新連接主服務器,并且成功,那么接下來, 從服務器將向主服務器發送PSYNC命令,報告從服務器A當前的復制偏移量為10107 ,那么這時,主服務器應該對從服務器執行完整重同步還是部分重同步呢?如果執行部分重同步的話,主服務器又如何補償從服務器A在斷線期間丟失的那部分數據呢?以上問題的答案都和復制積壓緩沖區有關。
復制積壓緩沖區
復制積壓緩沖區是由主服務器維護的一個固定長度(fixed-size)先進先出(FIFO)隊列,默認大小為1MB。
和普通先進先出隊列隨著元素的增加和減少而動態調整長度不同,固定長度先進先出隊列的長度是固定的,當入隊元素的數量大于隊列長度時,最先入隊的元素會被彈出,而新元素會被放入隊列。
當主服務器進行命令傳播時,它不僅會將寫命令發送給所有從服務器,還會將寫命令入隊到復制積壓緩沖區里面,如圖所示。
因此,主服務器的復制積壓緩沖區里面會保存著一部分最近傳播的寫命令,并且復制積壓緩沖區會為隊列中的每個字節記錄相應的復制偏移量,就像下表所示的那樣:
當從服務器重新連上主服務器時,從服務器會通過PSYNC命令將自己的復制偏移量offset發送給主服務器,主服務器會根據這個復制偏移量來決定對從服務器執行何種同步操作:
- 如果offset偏移量之后的數據(也即是偏移量offset+1開始的數據)仍然存在于復制積壓緩沖區里面,那么主服務器將對從服務器執行部分重同步操作;
- 相反,如果offset偏移量之后的數據已經不存在于復制積壓緩沖區,那么主服務器將對從服務器執行完整重同步操作。
根據需要調整復制積壓緩沖區的大小
Redis為復制積壓緩沖區設置的默認大小為1MB,如果主服務器需要執行大量寫命令,又或者主從服務器斷線后重連接所需的時間比較長,那么這個大小也許并不合適。如果復制積壓緩沖區的大小設置得不恰當,那么PSYNC命令的復制重同步模式就不能正常發揮作用,因此,正確估算和設置復制積壓緩沖區的大小非常重要。
復制積壓緩沖區的最小大小可以根據公式 second * write_size_per_second來估算:
- 其中second為從服務器斷線后重新連接上主服務器所需的平均時間(以秒計算);
- 而write_size_per_second則是主服務器平均每秒產生的寫命令數據量(協議格式(RESP協議)的寫命令的長度總和);
例如,如果主服務器平均每秒產生 1MB 的寫數據,而從服務器斷線之后平均要5秒才能重新連接上主服務器,那么復制積壓緩沖區的大小就不能低于5MB。
為了安全起見,可以將 復制積壓緩沖區的大小 = 2 * second * write_size_per_second
,這樣可以保證絕大部分斷線情況都能用部分同步來處理。
至于復制積壓緩沖區大小的修改方法,可以參考配置文件中關于 repl-backlog-size
選項的說明。
服務器運行ID
除了復制偏移量和復制積壓緩沖區之外,實現部分重同步還需要用到服務器運行ID(run ID):
- 每個Redis服務器,不論主服務器還是從服務,都會有自己的運行ID;
- 運行ID在服務器啟動時自動生成,由40個隨機的十六進制字符組成,例如
53b9b28df8042fdc9ab5e3fcbbbabff1d5dce2b3
;
當從服務器對主服務器進行初次復制時,主服務器會將自己的運行ID傳送給從服務器,而從服務器則會將這個運行ID保存起來(注意哦,是從服務器保存了主服務器的ID)。
當從服務器斷線并重新連上一個主服務器時,從服務器將向當前連接的主服務器發送之前保存的運行ID:
- 如果從服務器保存的運行ID和當前連接的主服務器的運行ID相同,那么說明從服務器斷線之前復制的就是當前連接的這個主服務器,主服務器可以繼續嘗試執行部分重同步操作;
- 相反地,如果從服務器保存的運行ID和當前連接的主服務器的運行ID并不相同,那么說明從服務器斷線之前復制的主服務器并不是當前連接的這個主服務器,主服務器將對從服務器執行完整重同步操作。
-
數據
+關注
關注
8文章
7006瀏覽量
88955 -
服務器
+關注
關注
12文章
9129瀏覽量
85348 -
數據庫
+關注
關注
7文章
3795瀏覽量
64366 -
Redis
+關注
關注
0文章
374瀏覽量
10871
發布評論請先 登錄
相關推薦
評論