復制(Replication)?

Note

本文檔翻譯自: http://redis.io/topics/replication

Redis 支持簡單且易用的主從復制(master-slave replication)功能, 該功能可以讓從服務器(slave server)成為主服務器(master server)的精確復制品。

以下是關于 Redis 復制功能的幾個重要方面:

  • Redis 使用異步復制。 從 Redis 2.8 開始, 從服務器會以每秒一次的頻率向主服務器報告復制流(replication stream)的處理進度。

  • 一個主服務器可以有多個從服務器。

  • 不僅主服務器可以有從服務器, 從服務器也可以有自己的從服務器, 多個從服務器之間可以構成一個圖狀結構。

  • 復制功能不會阻塞主服務器: 即使有一個或多個從服務器正在進行初次同步, 主服務器也可以繼續處理命令請求。

  • 復制功能也不會阻塞從服務器: 只要在 redis.conf 文件中進行了相應的設置, 即使從服務器正在進行初次同步, 服務器也可以使用舊版本的數據集來處理命令查詢。

    不過, 在從服務器刪除舊版本數據集并載入新版本數據集的那段時間內, 連接請求會被阻塞。

    你還可以配置從服務器, 讓它在與主服務器之間的連接斷開時, 向客戶端發送一個錯誤。

  • 復制功能可以單純地用于數據冗余(data redundancy), 也可以通過讓多個從服務器處理只讀命令請求來提升擴展性(scalability): 比如說, 繁重的 SORT 命令可以交給附屬節點去運行。

  • 可以通過復制功能來讓主服務器免于執行持久化操作: 只要關閉主服務器的持久化功能, 然后由從服務器去執行持久化操作即可。

復制功能的運作原理?

無論是初次連接還是重新連接, 當建立一個從服務器時, 從服務器都將向主服務器發送一個 SYNC 命令。

接到 SYNC 命令的主服務器將開始執行 BGSAVE , 并在保存操作執行期間, 將所有新執行的寫入命令都保存到一個緩沖區里面。

BGSAVE 執行完畢后, 主服務器將執行保存操作所得的 .rdb 文件發送給從服務器, 從服務器接收這個 .rdb 文件, 并將文件中的數據載入到內存中。

之后主服務器會以 Redis 命令協議的格式, 將寫命令緩沖區中積累的所有內容都發送給從服務器。

你可以通過 telnet 命令來親自驗證這個同步過程: 首先連上一個正在處理命令請求的 Redis 服務器, 然后向它發送 SYNC 命令, 過一陣子, 你將看到 telnet 會話(session)接收到服務器發來的大段數據(.rdb 文件), 之后還會看到, 所有在服務器執行過的寫命令, 都會重新發送到 telnet 會話來。

即使有多個從服務器同時向主服務器發送 SYNC , 主服務器也只需執行一次 BGSAVE 命令, 就可以處理所有這些從服務器的同步請求。

從服務器可以在主從服務器之間的連接斷開時進行自動重連, 在 Redis 2.8 版本之前, 斷線之后重連的從服務器總要執行一次完整重同步(full resynchronization)操作, 但是從 Redis 2.8 版本開始, 從服務器可以根據主服務器的情況來選擇執行完整重同步還是部分重同步(partial resynchronization)。

部分重同步?

從 Redis 2.8 開始, 在網絡連接短暫性失效之后, 主從服務器可以嘗試繼續執行原有的復制進程(process), 而不一定要執行完整重同步操作。

這個特性需要主服務器為被發送的復制流創建一個內存緩沖區(in-memory backlog), 并且主服務器和所有從服務器之間都記錄一個復制偏移量(replication offset)和一個主服務器 ID (master run id), 當出現網絡連接斷開時, 從服務器會重新連接, 并且向主服務器請求繼續執行原來的復制進程:

  • 如果從服務器記錄的主服務器 ID 和當前要連接的主服務器的 ID 相同, 并且從服務器記錄的偏移量所指定的數據仍然保存在主服務器的復制流緩沖區里面, 那么主服務器會向從服務器發送斷線時缺失的那部分數據, 然后復制工作可以繼續執行。
  • 否則的話, 從服務器就要執行完整重同步操作。

Redis 2.8 的這個部分重同步特性會用到一個新增的 PSYNC 內部命令, 而 Redis 2.8 以前的舊版本只有 SYNC 命令, 不過, 只要從服務器是 Redis 2.8 或以上的版本, 它就會根據主服務器的版本來決定到底是使用 PSYNC 還是 SYNC

  • 如果主服務器是 Redis 2.8 或以上版本,那么從服務器使用 PSYNC 命令來進行同步。
  • 如果主服務器是 Redis 2.8 之前的版本,那么從服務器使用 SYNC 命令來進行同步。

配置?

配置一個從服務器非常簡單, 只要在配置文件中增加以下的這一行就可以了:

slaveof 192.168.1.1 6379

當然, 你需要將代碼中的 192.168.1.16379 替換成你的主服務器的 IP 和端口號。

另外一種方法是調用 SLAVEOF 命令, 輸入主服務器的 IP 和端口, 然后同步就會開始:

127.0.0.1:6379> SLAVEOF 192.168.1.1 10086
OK

只讀從服務器?

從 Redis 2.6 開始, 從服務器支持只讀模式, 并且該模式為從服務器的默認模式。

只讀模式由 redis.conf 文件中的 slave-read-only 選項控制, 也可以通過 CONFIG SET 命令來開啟或關閉這個模式。

只讀從服務器會拒絕執行任何寫命令, 所以不會出現因為操作失誤而將數據不小心寫入到了從服務器的情況。

即使從服務器是只讀的, DEBUGCONFIG 等管理式命令仍然是可以使用的, 所以我們還是不應該將服務器暴露給互聯網或者任何不可信網絡。 不過, 使用 redis.conf 中的命令改名選項, 我們可以通過禁止執行某些命令來提升只讀從服務器的安全性。

你可能會感到好奇, 既然從服務器上的寫數據會被重同步數據覆蓋, 也可能在從服務器重啟時丟失, 那么為什么要讓一個從服務器變得可寫呢?

原因是, 一些不重要的臨時數據, 仍然是可以保存在從服務器上面的。 比如說, 客戶端可以在從服務器上保存主服務器的可達性(reachability)信息, 從而實現故障轉移(failover)策略。

從服務器相關配置?

如果主服務器通過 requirepass 選項設置了密碼, 那么為了讓從服務器的同步操作可以順利進行, 我們也必須為從服務器進行相應的身份驗證設置。

對于一個正在運行的服務器, 可以使用客戶端輸入以下命令:

config set masterauth <password>

要永久地設置這個密碼, 那么可以將它加入到配置文件中:

masterauth <password>

另外還有幾個選項, 它們和主服務器執行部分重同步時所使用的復制流緩沖區有關, 詳細的信息可以參考 Redis 源碼中附帶的 redis.conf 示例文件。

主服務器只在有至少 N 個從服務器的情況下,才執行寫操作?

從 Redis 2.8 開始, 為了保證數據的安全性, 可以通過配置, 讓主服務器只在有至少 N 個當前已連接從服務器的情況下, 才執行寫命令。

不過, 因為 Redis 使用異步復制, 所以主服務器發送的寫數據并不一定會被從服務器接收到, 因此, 數據丟失的可能性仍然是存在的。

以下是這個特性的運作原理:

  • 從服務器以每秒一次的頻率 PING 主服務器一次, 并報告復制流的處理情況。
  • 主服務器會記錄各個從服務器最后一次向它發送 PING 的時間。
  • 用戶可以通過配置, 指定網絡延遲的最大值 min-slaves-max-lag , 以及執行寫操作所需的至少從服務器數量 min-slaves-to-write

如果至少有 min-slaves-to-write 個從服務器, 并且這些服務器的延遲值都少于 min-slaves-max-lag 秒, 那么主服務器就會執行客戶端請求的寫操作。

你可以將這個特性看作 CAP 理論中的 C 的條件放寬版本: 盡管不能保證寫操作的持久性, 但起碼丟失數據的窗口會被嚴格限制在指定的秒數中。

另一方面, 如果條件達不到 min-slaves-to-writemin-slaves-max-lag 所指定的條件, 那么寫操作就不會被執行, 主服務器會向請求執行寫操作的客戶端返回一個錯誤。

以下是這個特性的兩個選項和它們所需的參數:

  • min-slaves-to-write <number of slaves>
  • min-slaves-max-lag <number of seconds>

詳細的信息可以參考 Redis 源碼中附帶的 redis.conf 示例文件。

討論 ?

comments powered by Disqus
四川快乐12开奖时间