1. 程式人生 > 實用技巧 >深入研究Js全域性變數

深入研究Js全域性變數

在redis中,我們可以通過slaveof命令或配置選項,讓一個伺服器去複製另一個伺服器,我們稱被複制的伺服器為主伺服器,而對主伺服器進行復制的伺服器為從伺服器。

下面是從伺服器設定主伺服器相關的配置,如果主伺服器設定了requirepass 選項,需要在masterauth配置上主服務的密碼。

slaveof 127.0.0.1 6379
# If the master is password protected (using the "requirepass" configuration
# directive below) it is possible to tell the slave to authenticate before
# starting the replication synchronization process, otherwise the master will
# refuse the slave request.
masterauth 
123456

複製:

redis的複製功能分為 同步和命令傳播兩個操作:

  • 同步:從伺服器向主伺服器傳送sync命令,主伺服器在收到命令後,會執行bgsave命令在後臺生成一個rdb檔案,並使用一個緩衝區記錄從現在開始執行的所有寫命令,當主伺服器生成好rdb檔案後,會將它傳送給從伺服器,從伺服器接收並載入rdb檔案,將資料庫狀態更新至主伺服器執行bgsave命令時的狀態,然後主伺服器會將緩衝區記錄的所有寫命令傳送給從伺服器,從伺服器執行這些命令後,與主伺服器當前狀態達成一致。
  • 命令傳播:主從伺服器完成同步操作後,主伺服器會將後續執行的寫命令傳送給從伺服器,從伺服器執行後,就可以與主伺服器始終保持資料一致的狀態。

斷線重連:

2.8之前的版本,主從伺服器斷線重連後,從伺服器會向主伺服器傳送sync命令,主從伺服器間會再次執行一次初次複製時的同步操作以達到主從一致的狀態。但是這個方案是低效的,sync命令是一個非常耗費資源的操作,如果主從伺服器只是發生短時間的連線斷開,它們之間的資料差異其實是很小的,完全可以讓主伺服器只是將斷線期間內執行的寫命令傳送給從伺服器達到相同的效果。

針對上面的問題,redis在2.8版本增加了psync命令替代sync命令來執行復制時的同步操作。

psync命令具有完整重同步和部分重同步兩種模式:

  • 完整重同步:和sync命令同步的步驟基本相同。
  • 部分重同步:用於處理斷線重連的複製情況,當從伺服器斷線重連到主伺服器時,如果條件允許
    ,主伺服器可以將主從伺服器斷開期間執行的寫命令傳送給從伺服器,從伺服器只要接收並執行這些命令,就可以將資料庫更新至主伺服器當前所處的狀態。

那麼需要滿足的條件是什麼呢?在這裡要先提出幾個概念:主從伺服器的複製偏移量,主伺服器的複製積壓緩衝區,伺服器執行Id。

複製偏移量:

  • 執行復制的雙方,主從伺服器會分別維護一個複製偏移量。
  • 主伺服器每次向從伺服器傳播n個位元組的資料時,就會在自己的複製偏移量的值上加n。
  • 從伺服器每次收到從主伺服器傳播來的n個位元組的資料時,也會向自己的複製偏移量的值上加n。
  • 主從伺服器處於一致狀態時,主從伺服器的複製偏移量應該總是相同的,不同則說明主從伺服器處於資料不一致的狀態。

複製積壓緩衝區:

  • 複製積壓緩衝區是由主伺服器維護的一個固定長度先進先出佇列,預設大小為1MB(可以通過 repl-backlog-size選項修改)。
  • 當主伺服器進行命令傳播時,它不僅會將寫命令傳送給所有從伺服器,還會將寫命令入隊到複製積壓緩衝區中,因此複製積壓緩衝區中會儲存著一部分最近傳播的寫命令,並且複製積壓緩衝區會為佇列中的每個位元組記錄相應的複製偏移量。
  • 當從伺服器斷線重連上主伺服器後,從伺服器會通過psync命令將自己的複製偏移量傳送給主伺服器,如果這個複製偏移量在主伺服器的複製積壓緩衝區中,那麼主伺服器將對從伺服器執行部分重同步操作,相反則執行完全重同步操作。

伺服器執行Id:

  • 每個redis伺服器都會有自己的執行Id,執行Id在伺服器啟動時自動生成,由40個隨機的十六進位制字元組成。
  • 從伺服器對主伺服器進行初次複製時,主服務會將自己的執行Id傳送給從伺服器,而從伺服器會將這個執行Id儲存起來。
  • 當從伺服器斷線重連上一個主伺服器時,會將之前儲存的執行Id傳送給主伺服器。主伺服器會判斷這個Id和自己的執行Id是否一致,如果一致,嘗試執行部分重同步操作,相反則執行完整重同步操作。

心跳檢測

在2.8版本中,redis還新增了心跳檢測的功能。在命令傳播階段,從伺服器會以每秒一次的頻率向主伺服器傳送命令:REPLCONF ACK <replication_offset>,replication_offset是從伺服器當前的複製偏移量。

傳送REPLCONF ACK命令對於主從伺服器有三個作用:

  • 檢測主從伺服器的網路連線狀態。

向主伺服器傳送 info replication命令可以看到主從伺服器的連線狀態,其中lag值表示從伺服器最後一次向主伺服器傳送心跳的時間距離現在過了多少秒,超過1秒,說明主從伺服器之間的連線可能出現了故障問題。

role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6380,state=online,offset=14452,lag=0
  • 輔助實現min-slaves選項。

min-slaves-to-write和min-slave-max-lag 兩個選項可以防止主伺服器在不安全的情況下執行寫命令。

min-slaves-to-write 3
min-slaves-max-lag 10

上面的配置表示當從伺服器的數量少於3個,或3三個從伺服器的延遲值都大於等於10s,那麼主伺服器將拒絕執行寫命令。

  • 檢測命令丟失。

由於網路故障,主伺服器傳播給從伺服器的寫命令可能在半路丟失。從伺服器向主伺服器傳送REPLCONF ACK <replication_offset>命令後,主伺服器會拿replication_offset與自己複製偏移量比較,如果小於自己的複製偏移量,那麼主伺服器會根據replication_offset在複製積壓緩衝區中取出從伺服器缺少的資料,併發送給從伺服器。

注:還有一點需要注意,redis主從複製,可以提高redis的讀寫效能,但並不能提高redis的可用性,當主伺服器宕機,需要手動啟動主伺服器,或手動將從伺服器升為主伺服器。