Redis 支持簡單且易用的主從複製(master-slave replication)功能, 該功能可讓從服務器(slave server)成爲主服務器(master server)的精確複製品。html
如下是關於 Redis 複製功能的幾個重要方面:redis
Redis 使用異步複製。 從 Redis 2.8 開始, 從服務器會以每秒一次的頻率向主服務器報告複製流(replication stream)的處理進度。shell
一個主服務器能夠有多個從服務器。安全
不只主服務器能夠有從服務器, 從服務器也能夠有本身的從服務器, 多個從服務器之間能夠構成一個圖狀結構。服務器
複製功能不會阻塞主服務器: 即便有一個或多個從服務器正在進行初次同步, 主服務器也能夠繼續處理命令請求。網絡
複製功能也不會阻塞從服務器: 只要在 redis.conf
文件中進行了相應的設置, 即便從服務器正在進行初次同步, 服務器也可使用舊版本的數據集來處理命令查詢。session
不過, 在從服務器刪除舊版本數據集並載入新版本數據集的那段時間內, 鏈接請求會被阻塞。異步
你還能夠配置從服務器, 讓它在與主服務器之間的鏈接斷開時, 向客戶端發送一個錯誤。ui
複製功能能夠單純地用於數據冗餘(data redundancy), 也能夠經過讓多個從服務器處理只讀命令請求來提高擴展性(scalability): 好比說, 繁重的 SORT 命令能夠交給附屬節點去運行。spa
能夠經過複製功能來讓主服務器免於執行持久化操做: 只要關閉主服務器的持久化功能, 而後由從服務器去執行持久化操做便可。
配置一個從服務器很是簡單, 只要在配置文件中增長如下的這一行就能夠了:
slaveof 192.168.1.1 6379
固然, 你須要將代碼中的 192.168.1.1 和 6379 替換成你的主服務器的 IP 和端口號。
另一種方法是調用 SLAVEOF 命令, 輸入主服務器的 IP 和端口, 而後同步就會開始:
127.0.0.1:6379> SLAVEOF 192.168.1.1 10086 OK
若是主服務器經過 requirepass 選項設置了密碼, 那麼爲了讓從服務器的同步操做能夠順利進行, 咱們也必須爲從服務器進行相應的身份驗證設置。
對於一個正在運行的服務器, 可使用客戶端輸入如下命令:
config set masterauth <password>
要永久地設置這個密碼, 那麼能夠將它加入到配置文件中:
masterauth <password>
當配置Redis複製功能時,強烈建議打開主服務器的持久化功能。 不然的話,因爲延遲等問題,部署的服務應該要避免自動拉起。
爲了幫助理解主服務器關閉持久化時自動拉起的危險性,參考一下如下會致使主從服務器數據所有丟失的例子:
1. 假設節點A爲主服務器,而且關閉了持久化。 而且節點B和節點C從節點A複製數據
2. 節點A崩潰,而後由自動拉起服務重啓了節點A. 因爲節點A的持久化被關閉了,因此重啓以後沒有任何數據
3. 節點B和節點C將從節點A複製數據,可是A的數據是空的, 因而就把自身保存的數據副本刪除。
在關閉主服務器上的持久化,並同時開啓自動拉起進程的狀況下,即使使用Sentinel來實現Redis的高可用性,也是很是危險的。 由於主服務器可能拉起得很是快,以致於Sentinel在配置的心跳時間間隔內沒有檢測到主服務器已被重啓,而後仍是會執行上面的數據丟失的流程。
不管什麼時候,數據安全都是極其重要的,因此應該禁止主服務器關閉持久化的同時自動拉起。
不管是初次鏈接仍是從新鏈接, 當創建一個從服務器時, 從服務器都將向主服務器發送一個 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.6 開始, 從服務器支持只讀模式, 而且該模式爲從服務器的默認模式。
只讀模式由 redis.conf 文件中的 slave-read-only 選項控制, 也能夠經過 CONFIG SET 命令來開啓或關閉這個模式。
只讀從服務器會拒絕執行任何寫命令, 因此不會出現由於操做失誤而將數據不當心寫入到了從服務器的狀況。
即便從服務器是隻讀的, DEBUG 和 CONFIG 等管理式命令仍然是可使用的, 因此咱們仍是不該該將服務器暴露給互聯網或者任何不可信網絡。 不過, 使用 redis.conf 中的命令更名選項, 咱們能夠經過禁止執行某些命令來提高只讀從服務器的安全性。
你可能會感到好奇, 既然從服務器上的寫數據會被重同步數據覆蓋, 也可能在從服務器重啓時丟失, 那麼爲何要讓一個從服務器變得可寫呢?
緣由是, 一些不重要的臨時數據, 仍然是能夠保存在從服務器上面的。 好比說, 客戶端能夠在從服務器上保存主服務器的可達性(reachability)信息, 從而實現故障轉移(failover)策略。
從 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-write
和 min-slaves-max-lag
所指定的條件, 那麼寫操做就不會被執行, 主服務器會向請求執行寫操做的客戶端返回一個錯誤。
如下是這個特性的兩個選項和它們所需的參數:
min-slaves-to-write <number of slaves>
min-slaves-max-lag <number of seconds>
詳細的信息能夠參考 Redis 源碼中附帶的 redis.conf
示例文件。