1. 程式人生 > 實用技巧 >搭建Harbor企業級docker倉庫

搭建Harbor企業級docker倉庫

目錄

一、複製介紹

主從複製,是把一臺redis伺服器上資料複製到其他伺服器的機制,其中前者被稱為主節點(master),後者被稱為從節點(slave)。

主從複製的主要主要作用:

  1. 資料冗餘:資料熱備,多機備份。
  2. 故障恢復:當主節點出現問題時,可以讓從節點提供服務,是一種功能的冗餘。
  3. 負載均衡:可以讓主節點寫,從節點多,可以把壓力分配到多個從節點,從而實現負載均衡。
  4. 高可用基石:主從複製是實現哨兵和叢集的基礎。

預設情況下,每個redis伺服器都是master節點,每一個master可以有多個slave節點,但是一個salve節點只能有一個master節點。

二、複製配置

2.1 建立複製

2.1.1 命令

  1. 在配置檔案中加入:slaveof {masterHost} {masterPort}
  2. 在redis-server啟動命令後加入 -- slaveof {masterHost} {masterPort}
  3. 直接使用命令(在客戶端執行): slaveof {masterHost} {masterPort}

2.1.2 演示

準備節點

預設6380埠作為master節點,再啟動一個6380節點作為salve節點。

複製一個配置檔案,命名為redis6380.conf

配置新的埠號

兩個redis例項已經啟動。

執行復制命令

啟動兩個例項

執行slaveof命令

檢視效果

master節點寫入,讀取

slave節點讀取資料

至此,複製搭建成功,資料已經成功從master複製到了slave,並且通過salve讀取成功。

2.2 斷開復制

3.2.1 直接斷開

直接使用slaveof no one命令即可斷開和master的複製關係

斷開復制關係後的資料

  1. 原有已經複製的資料會保留
  2. master後續寫入的資料將不再同步

可以看到原有的資料保留了

斷開後在原有master寫入

資料將不再同步到6380

3.2.2 切換到其他master

可以通過切換到其他master的方式斷開和當前master的繫結。但是和slave no one不同的是,切換新的master後,從原有master複製過來的資料會被清空。

三、拓撲結構

一對一,一對多,樹狀結構。

四、複製過程

4.1儲存主節點

執行slaveof後從節點只是儲存了主節點的地址資訊變直接返回,複製流程還沒有正式開始。

4.2 主從建立socket連線

從節點內部通過每秒執行的定時任務來處理相關邏輯,當定時任務發現存在新的主節點後,會嘗試和主節點建立網路連線。

從節點會建立一個socket去連線主節點,後續資料同步都是基於這個socket進行。

如果從節點無法建立連線,定時任務會無限重試到連線成功或者複製被取消為止。

4.3 傳送ping命令

連線建立成功後從節點會向主節點發送ping請求進行首次通訊,主要有如下目的:

  1. 檢測之前建立的socket是否可用。
  2. 檢測主節點當前是否可接受處理命令

傳送ping命令後如果從節點沒有收到pong回覆或者超時(比如網路超時,或者主節點阻塞無法處理等),從節點會斷開復制,下次定時任務發起後重新連線。

4.4 許可權驗證

如果主節點設定了requirepass引數,則需要密碼驗證,從節點必須配置masterauth引數保證與主節點相同的密碼才能通過驗證,如果驗證失敗,從節點會斷開復制,下次定時任務發起後重新連線。

4.5 資料同步

主從複製連線建立成功後,便開始資料同步,屬於資料的初始化,主節點會把持有的所有資料傳送給從節點,主題是實現方式是從節點給主節點發送psync命令(2.8之前是sync命令)。這塊是耗時最長的步驟,分為全量同步和部分同步。

4.6 命令持續同步

當主節點把當前的資料同步給從節點後,便完成了複製的建立流程,後續主節點會持續的把命令傳送給從節點,保證主從一致。

五、資料同步原理

主從建立連線成功後,從節點會向主節點發送psync命令來完成資料同步,同步過程分為:全量複製和部分複製。

  1. 全量複製:一般用於初次複製場景,主節點一次性把全部資料發給從節點,是一個比較重的操作
  2. 部分複製:用於處理在主從複製中因網路閃斷等原因造成的資料丟失的場景,當主從再次連線後,如果主節點完整儲存了中斷期間的資料,主節點會補發丟失的資料給從節點,補發的資料遠遠小於全量資料,部分複製有效避免了全量複製的過高開銷。

5.1 psync命令需要的元件

psync命令執行需要以下元件的支援:

  1. 主從複製偏移量
  2. 主節點複製擠壓緩衝區
  3. 主節點執行id

5.1.1 主從複製偏移量

master節點處理完寫入命令後,會把命令的位元組長度做累加記錄。

從節點再接收到主節點發送的命令後,也會累加自身的偏移量。

通過對比master的偏移量和slave的偏移量來看slave和master的資料差異大小。

5.1.2 主節點複製積壓緩衝區

複製緩衝區是儲存在主節點上的一個固定長度佇列,預設大小為1MB,當有slave時候回建立緩衝區,這時主節點響應寫命令時,不但會把命令傳送給從節點,還會寫入複製擠壓緩衝區。

擠壓緩衝區是一個先進先出的佇列,如果超過容量,之前的資料會被覆蓋。大小是可以配置的。擠壓緩衝區主要為了部分複製做準備。可以通過info replication來檢視:

repl_backlog_active:1 //開啟複製緩衝區
repl_backlog_size:1048576 //緩衝區最大長度
repl_backlog_first_byte_offset:4505 //起始變異量,計算當前緩衝區可用範圍
repl_backlog_histlen:5460 //已儲存資料的有效長度

5.1.3 主節點執行id

每個redis節點(主從)啟動後都會生成一個40位的16進位制的字串作為執行id,用於唯一識別一個redis節點。從節點會儲存主節點的執行id用於識別自己正在複製的是哪一個主節點。redis重啟後id會改變。

初次複製時,從節點會儲存主節點的runid。

5.2 psync命令

從節點通過給主節點發送psync命令實現部分複製或者全量複製。命令格式為:

psync {runid} {offset}
  1. runid:所輔助主節點的runid,
  2. offset:當前從節點的資料偏移量

第一次複製時沒有offset和主節點的runid,會發送psync -1命令

5.3 全量複製

  1. 首次複製傳送 psync ? -1
  2. master 繼續請求發現是全量複製,恢復fullresync {runid} {offset}
  3. slave儲存主節點響應的runid和 offset
  4. 主節點執行bgsave,並且把從選擇開始的命令同時寫入一個緩衝區(複製緩衝區)
  5. 主節點執行完bgsave後把最終生成的rdb發給salve。
  6. salve收到主節點發送過來的rdb後開始清空自身資料
  7. salve把主節點的rdb載入自己的rdb,此時salve的資料更新至主節點執行bgsave時候的狀態。
  8. 主節點將複製緩衝區的命令傳送給salve
  9. slave執行接收到的複製緩衝區的命令,至此salve的資料更新至主節點的最新狀態
  10. 如果slave開啟了aof,則會立即做bgrewriteaof,確保全量複製後aof持久化檔案立即可用。

5.4 部分複製

部分複製時redis針對全量複製開銷過高做出的一種優化措施,使用psync {runid}{offset}命令實現。

當主從複製的過程中,如果出現網路閃斷或者命令丟失等異常情況,從節點會要求主節點補發資料,如果此時主節點的複製積壓緩衝區記憶體中剛好存在這部分資料(就是斷網這段時間沒有同步到從節點的資料),則直接發給從節點,最終保持了和從節點的一直,也避免了大規模的全量複製。

  1. 如果主從節點之間網路出現中斷,如果超過repl-timeout時間,主節點會認為從節點故障並中斷複製連線。
  2. 主從斷開後,主節點依然在響應命令,這個時候新的命令無法同步到從節點,主從出現了不一致。上面也解釋了主節點會預設將命令寫入到複製積壓緩衝區,預設為1M,超出後會覆蓋。
  3. 網路恢復了,從節點再次連線主節點,連線建立成功。
  4. 從節點儲存了主節點的runid和自身的複製偏移量(offset),通過psync {runid} {offset}命令和主節點進行互動
  5. 主節點如果發現滿足部分複製的條件(後面詳細解釋這個條件),則返回continue給從節點
  6. 主節點根據偏移量把複製積壓緩衝區的資料發給從節點,最終保證主從複製進入正常。

主節點判斷判斷滿足部分複製的條件

  1. runid必須和自身一致
  2. 從節點發過來的偏移量之後的資料都在自身的複製積壓緩衝區內,這個很好理解,比如從節點發過來的offset是10(代表10以後的資料都沒有同步),但是緩衝區的offset是15(說明15之前的的資料已經不在緩衝區了),這個時候就沒辦法進行部分複製

如果不滿足部分複製條件,則主節點會返回fullsync給從節點,從節點會開啟全量複製

由此可見覆制積壓緩衝區的大小比較重要,如果太小,會被覆蓋,最終導致主從網路恢復後無法進行部分複製,這個值得大小應該要基於網路的中斷時間,已經主節點的qps和命令的大小來進行計算,然後進行合理的設定。

六、主從心跳

6.1 流程

主從心跳檢測示意圖

  1. master會週期性的ping slave,週期時間通過repl-ping-replica-period引數來控制,預設是10秒

  2. slave每隔1秒迴向master傳送replconf ack {offset}命令:

    • 實時監測主從節點的網路狀態

    • 上報自身的資料複製偏移量,如果主節點發現從節點有資料缺失,主節點會從自身的複製積壓緩衝區中拉取資料發給從節點

    • 實現從節點的數量和延遲性功能,通過min-replicas-to-write(最小可用的從節點個數)和min-replicas-max-lag(允許的最小延遲秒,一般為0,或者1)引數定義。

      • 如果master開啟了這兩個引數,那麼如果可用的從節點小於min-replicas-to-write或者延遲大於min-replicas-max-lag,master會拒絕資料寫入。示意圖如下。

6.2 repl -timeout引數

redis.conf有個repl-timeout引數:

  1. slave角度,如果在repl-timeout時間內沒有收到傳輸的rdb snapshot資料,

  2. slave角度,如果在repl-timeout沒有收到master傳送的資料包或者ping。

  3. master角度,如果在repl-timeout時間沒有收到REPCONF ACK確認資訊。

當redis檢測到repl-timeout超時(預設值60s),將會關閉主從之間的連線,redis slave會重新建立主從連線的請求。這個值一定要大於repl-ping-replica-period引數

為了降低主從延遲,一般建議把redis的主從節點部署在相同的機房。

七、全量複製場景

全量複製非常重,應該儘量避免,下面是一些會導致全量複製的操作。

  1. 第一次建立複製,無法避免,建議低峰時候進行
  2. runid不匹配,從節點會儲存主節點的runid,如果主節點重啟,則主節點的runid會改變,發現和從節點儲存的runid不一致時,會進行全量複製,應該避免重啟,比如可以採用debug reload命令,或者採用故障轉移功能,當主節點發生故障後,可以將從節點提升為主節點,或者採用哨兵或者叢集方案
  3. 複製積壓緩衝區不足(repl-backlog-size),這個緩衝區預設大小為1M,當超過1m後覆蓋,主從中斷再次連線後如果從節點的offset在複製積壓緩衝區找不到,則會導致全量複製,這個緩衝區的大小要基於網路狀況,命令大小,以及qps進行計算配置。

七、一些配置和命令

  1. salve-read-only=yes。 從節點只讀,如果從節點修改,會造成主從資料不一致
  2. repl-disable-tcp-nodelay 是否關閉tcp_nodelay,預設為no,建議配置為yes。這個是伺服器tcp的一個功能,tcp nagle演算法
  3. debug reload,不會導致runid改變,但是會情況記憶體資料,再次從rdb載入。
  4. 。。。