本專欄與Redis相關的文章redis
Redis Sentinel機制與用法(一)
Redis Sentinel機制與用法(二)
Jedis的JedisSentinelPool源代碼分析
Jedis的Sharded源代碼分析
Redis 主從 Replication 的配置
詳解Redis SORT命令
JedisCommand接口說明segmentfault
本文參考翻譯自 《Redis Replication documentation》
Redis的replication機制容許slave從master那裏經過網絡傳輸拷貝到完整的數據備份。具備如下特色:緩存
當有須要使用到replication機制時,通常都會強烈建議把master的持久化開關打開。即便爲了不持久化帶來的延遲影響,不把持久化開關打開,那麼也應該把master配置爲不會自動啓動的。安全
爲了更好地理解當一個不進行持久化的master若是容許自動啓動所帶來的危險性。能夠看看下面這種失敗情形:微信
假設咱們有一個redis節點A,設置爲master,而且關閉持久化功能,另外兩個節點B和C是它的slave,並從A複製數據。
若是A節點崩潰了致使全部的數據都丟失了,它會有重啓系統來重啓進程。可是因爲持久化功能被關閉了,因此即便它重啓了,它的數據集是空的。
而B和C依然會經過replication機制從A複製數據,因此B和C會從A那裏複製到一份空的數據集,並用這份空的數據集將本身自己的非空的數據集替換掉。因而就至關於丟失了全部的數據。
即便使用一些HA工具,好比說sentinel來監控master-slaves集羣,也會發生上述的情形,由於master可能崩潰後迅速恢復。速度太快而致使sentinel沒法察覺到一個failure的發生。網絡
當數據的安全很重要、持久化開關被關閉而且有replication發生的時候,那麼應該禁止實例的自啓動。架構
若是你爲master配置了一個slave,無論這個slave是不是第一次鏈接上Master,它都會發送一個SYNC
命令給master請求複製數據。併發
master收到SYNC
命令後,會在後臺進行數據持久化,持久化期間,master會繼續接收客戶端的請求,它會把這些可能修改數據集的請求緩存在內存中。當持久化進行完畢之後,master會把這份數據集發送給slave,slave會把接收到的數據進行持久化,而後再加載到內存中。而後,master再將以前緩存在內存中的命令發送給slave。less
當master與slave之間的鏈接因爲某些緣由而斷開時,slave可以自動重連Master,若是master收到了多個slave併發鏈接請求,它只會進行一次持久化,而不是一個鏈接一次,而後再把這一份持久化的數據發送給多個併發鏈接的slave。異步
當master和slave斷開重連後,通常都會對整份數據進行復制。但從redis2.8版本開始,支持部分複製。
從2.8版本開始,slave與master可以在網絡鏈接斷開重連後只進行部分數據複製。
master會在其內存中建立一個複製流的等待隊列,master和它全部的slave都維護了複製的數據下標和master的進程id,所以,當網絡鏈接斷開後,slave會請求master繼續進行未完成的複製,從所記錄的數據下標開始。若是進程id變化了,或者數據下標不可用,那麼將會進行一次所有數據的複製。
支持部分數據複製的命令是PSYNC
通常狀況下,一次複製須要將內存的數據寫到硬盤中,再將數據從硬盤讀進內存,再發送給slave。
對於速度比較慢的硬盤,這個操做會給master帶來性能上的損失。Redis2.8版本開始,實驗性地加上了無硬盤複製的功能。這個功能能將數據從內存中直接發送到slave,而不用通過硬盤的存儲。
不過這個功能目前處於實驗階段,還未正式發佈。
與replication相關的配置比較簡單,只須要把下面一行加到slave的配置文件中:
slaveof 192.168.1.1 6379
你只須要把ip地址和端口號改一下。固然,你也能夠經過客戶端發送SLAVEOF
命令給slave。
部分數據複製有一些可調的配置參數,請參考redis.conf文件。
無硬盤複製功能能夠經過repl-diskless-sync
來配置,另一個配置項repl-diskless-sync-delay
用來配置當收到第一個請求時,等待多個slave一塊兒來請求之間的間隔時間。
從redis2.6版本開始,slave支持只讀模式,並且是默認的。能夠經過配置項slave-read-only
來進行配置,而且支持客戶端使用CONFIG SET
命令來動態修改配置。
只讀的slave會拒絕全部的寫請求,只讀的slave並非爲了防範不可信的客戶端,畢竟一些管理命令例如DEBUG
和CONFIG
在只讀模式下仍是可使用的。若是確實要確保安全性,那麼能夠在配置文件中將一些命令從新命名。
也許你會感到很奇怪,爲何可以將一個只讀模式的slave恢復爲可寫的呢,儘管可寫,可是隻要slave一同步master的數據,就會丟失那些寫在slave的數據。不過仍是有一些合法的應用場景須要存儲瞬時數據會用到這個特性。不過,以後可能會考慮廢除掉這個特性。
Setting a slave to authenticate to a master
若是master經過requirepass
配置項設置了密碼,slave每次同步操做都須要驗證密碼,能夠經過在slave的配置文件中添加如下配置項:
masterauth <password>
也能夠經過客戶端在運行時發送如下命令:
config set masterauth <password>
從redis2.8版本開始,master能夠被配置爲,只有當master當前有至少N個slave鏈接着的時候才接受寫數據的請求。
然而,因爲redis是異步複製的,因此它並不能保證slave會受到一個寫請求,因此總有一個數據丟失的時間窗口存在。
這個機制的工做原理以下所示:
若是master有至少N個slave,而且ping心跳的超時不超過M秒,那麼它就會接收寫請求。
也許你會認爲這情形好似CAP理論中弱化版的C(consistency),由於寫請求並不能保證數據的一致性,但這樣作,至少數據丟失被限制在了限定的時間內。即M秒。
若是N和M的條件都沒法達到,那麼master會回覆一個錯誤信息。寫請求也不會被處理。
有兩個配置項用來配置上文中提到的N和M:
min-slaves-to-write <number of slaves> min-slaves-max-lag <number of seconds>
若是須要了解更多,請查閱redis.conf配置文件。