Redis數據庫主從複製html
Redis 支持簡單且易用的主從複製(master-slave replication)功能, 該功能可讓從服務器(slave server)成爲主服務器(master server)的精確複製品。如下是關於Redis複製功能的幾個重要方面:node
q Redis 使用異步複製。從Redis 2.8 開始,從服務器會以每秒一次的頻率向主服務器報告複製流(replication stream)的處理進度。web
q 一個主服務器能夠有多個從服務器。redis
q 不只主服務器能夠有從服務器,從服務器也能夠有本身的從服務器,多個從服務器之間能夠構成一個圖狀結構。數據庫
q 複製功能不會阻塞主服務器:即便有一個或多個從服務器正在進行初次同步,主服務器也能夠繼續處理命令請求。安全
q 複製功能也不會阻塞從服務器:只要在 redis.conf 文件中進行了相應的設置,即便從服務器正在進行初次同步,服務器也可使用舊版本的數據集來處理命令查詢。不過,在從服務器刪除舊版本數據集並載入新版本數據集的那段時間內,鏈接請求會被阻塞。能夠配置從服務器, 讓它在與主服務器之間的鏈接斷開時, 向客戶端發送一個錯誤。bash
q 複製功能能夠單純地用於數據冗餘(data redundancy), 也能夠經過讓多個從服務器處理只讀命令請求來提高擴展性(scalability):好比說,繁重的SORT命令能夠交給附屬節點去運行。服務器
q 能夠經過複製功能來讓主服務器免於執行持久化操做:只要關閉主服務器的持久化功能,而後由從服務器去執行持久化操做便可。網絡
當配置Redis複製功能時,強烈建議打開主服務器的持久化功能。 不然的話,因爲延遲等問題,部署的服務應該要避免自動拉起。less
爲了幫助理解主服務器關閉持久化時自動拉起的危險性,參考一下如下會致使主從服務器數據所有丟失的例子:
1. 假設節點A爲主服務器,而且關閉了持久化。 而且節點B和節點C從節點A複製數據
2. 節點A崩潰,而後由自動拉起服務重啓了節點A. 因爲節點A的持久化被關閉了,因此重啓以後沒有任何數據
3. 節點B和節點C將從節點A複製數據,可是A的數據是空的, 因而就把自身保存的數據副本刪除。
在關閉主服務器上的持久化,並同時開啓自動拉起進程的狀況下,即使使用Sentinel來實現Redis的高可用性,也是很是危險的。 由於主服務器可能拉起得很是快,以致於Sentinel在配置的心跳時間間隔內沒有檢測到主服務器已被重啓,而後仍是會執行上面的數據丟失的流程。
不管什麼時候,數據安全都是極其重要的,因此應該禁止主服務器關閉持久化的同時自動拉起。
注:在開啓主從複製的時候,強烈建議開啓持久化功能。
1、不管是初次鏈接仍是從新鏈接, 當創建一個從服務器時, 從服務器都將向主服務器發送一個 SYNC 命令。
2、接到 SYNC 命令的主服務器將開始執行 BGSAVE , 並在保存操做執行期間, 將全部新執行的寫入命令都保存到一個緩衝區裏面。
3、當 BGSAVE 執行完畢後, 主服務器將執行保存操做所得的 .rdb 文件發送給從服務器, 從服務器接收這個 .rdb 文件, 並將文件中的數據載入到內存中。
4、以後主服務器會以 Redis 命令協議的格式, 將寫命令緩衝區中積累的全部內容都發送給從服務器。
從服務器能夠在主從服務器之間的鏈接斷開時進行自動重連, 在 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 :
q 若是主服務器是 Redis 2.8 或以上版本,那麼從服務器使用 PSYNC 命令來進行同步。
q 若是主服務器是 Redis 2.8 以前的版本,那麼從服務器使用 SYNC 命令來進行同步。
配置一個從服務器很是簡單, 只要在配置文件中增長如下的這一行就能夠了:
slaveof 10.0.0.16 6379 #<==主服務器的IP和端口
另一種方法是調用 SLAVEOF 命令, 輸入主服務器的 IP 和端口, 而後同步就會開始:
10.0.0.11:6379> SLAVEOF 10.0.0.16 6379 OK
從 Redis 2.6 開始, 從服務器支持只讀模式, 而且該模式爲從服務器的默認模式。只讀從服務器會拒絕執行任何寫命令, 因此不會出現由於操做失誤而將數據不當心寫入到了從服務器的狀況。
即便從服務器是隻讀的, DEBUG 和 CONFIG 等管理式命令仍然是可使用的, 因此咱們仍是不該該將服務器暴露給互聯網或者任何不可信網絡。 不過, 使用 redis.conf 中的命令更名選項, 咱們能夠經過禁止執行某些命令來提高只讀從服務器的安全性。
配置參數以下:
slave-read-only yes
若是主服務器經過 requirepass 選項設置了密碼, 那麼爲了讓從服務器的同步操做能夠順利進行, 咱們也必須爲從服務器進行相應的身份驗證設置。
對於一個正在運行的服務器, 可使用客戶端輸入如下命令:
config set masterauth <password>
要永久地設置這個密碼, 那麼能夠將它加入到配置文件中:
masterauth <password>
從 Redis 2.8 開始, 爲了保證數據的安全性, 能夠經過配置, 讓主服務器只在有至少 N 個當前已鏈接從服務器的狀況下, 才執行寫命令。
不過, 由於 Redis 使用異步複製, 因此主服務器發送的寫數據並不必定會被從服務器接收到, 所以, 數據丟失的可能性仍然是存在的。
如下是這個特性的運做原理:
1、從服務器以每秒一次的頻率 PING 主服務器一次, 並報告複製流的處理狀況。
2、主服務器會記錄各個從服務器最後一次向它發送 PING 的時間。
3、用戶能夠經過配置, 指定網絡延遲的最大值 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>
1) slave-serve-stale-data yes
#<==與master失聯的應對方式,yes時會回覆客戶端舊的數據;no會提示報錯「SYNC with master in progress」
2) repl-diskless-sync no
#<==是否啓動無盤同步方式,即便用socket作同步策略而不會使用到disk。(磁盤IO慢,且帶寬足夠大時可選擇採用。但該功能目前還不處實驗狀態,建議選擇關閉)
3) repl-diskless-sync-delay 5
#<==當repl-diskless-sync設置爲yes時,設置傳輸前的等待時間。要禁用該功能可配置爲0。
4) repl-disable-tcp-nodelay no
#<==tcp延時的優化,默認爲no。在很是高的網絡trafiic條件或者主備距離遠時,可開啓爲yes。
5) slave-priority 100
#<==從節點的優先級。數字越低級別越高,0表示不會被提高帶master。