基礎的Redis
同步使用很是簡單,配置主從同步可讓從節點徹底複製節點。無論主節點發生任何事,從節點會在連接斷開以後自動重連。redis
這個機制工做使用了三臺機子:數據庫
key
過時或者回收等。Redis
默認使用高性能高延遲的異步複製,這是大部分Redis
使用場景的天然複製模式。從節點按期異步的從主節點獲取大量的數據。緩存
能夠在客戶端使用WAIT
命令來請求同步複製確認的數據。然而WATI
命令只能確保指定數量的數據被複制到其餘實例:數據寫入依舊會在故障轉移或者因故障轉移的致使的緣由中丟失,取決於Redis
持久化配置。你能夠查看Sentinel
或者Redis Cluster
文檔查看更多關於高可用和故障轉移的信息。接下來的文檔主要歸納Redis
簡單的數據同步的一些基本的特徵。安全
接下來是一些關於Redis
同步很重要的事實:網絡
Redis
使用異步複製,從節點異步的從主節點獲取大量的數據。Redis 4.0
之後,全部的子從節點都將從主節點收到相同的複製流。Redis
同步在主節點是非堵塞的。這意味着主節點能夠繼續處理請求,當一個或者多個從節點作初始化數據同步或者增量同步的時候。Redis
從節點在複製流來的的時候返回一個錯誤給客戶端,在初始化同步的時候,舊的數據集將被刪除,行的數據必須被加載。從節點將會在這個短暫時間窗口堵塞正在進來的鏈接(這將在巨大的數據集上花費長達許多秒的時間)。從Redis 4.0
開始,刪除就數據將會在另外一個線程進行,可是加載新的初始化數據集依舊會在主線程執行,而且堵塞從節點。O(N)
的慢查詢操做能夠由從節點分擔),同步是可伸縮的,也是安全可靠的。AOF
。可是這個操做要很是當心,由於重啓住節點將清空數據集:若是此時從節點去同步它,將會讓從節點也清空。若是使用Redis
同步,強烈建議在主節點和從節點都打開持久化。若是這由於擔憂延遲致使磁盤緩慢,實例應該經過修改配置,避免在重啓的時候自動重啓。
爲了更好的理解在持久化關閉的時候,自動重啓是很是危險的,檢查下面數據數據從主節點和從節點都消失的模式:併發
當Redis Sentinel
用來作高可用的時候,主節點上將會關閉持久化,同時也關閉自動重啓。好比主節點能夠快速重啓,快到Sentinel
都來不及捕捉錯誤因此上面歸納的失敗的模式就發生了。less
任什麼時候候數據安全都是重要的是,當主節點使用同步並關閉持久化的時候,自動重啓也要被關閉異步
Redis
同步是怎麼工做的每個Redis
主節點有一個同步ID,是一個巨大的位隨機字符串標記數據集。同時主節點也爲發送到從節點的同步流提供一個增加偏移量,爲了讓從節點更新數據集狀態。同步偏移量即便在沒有從節點;連接的時候也會增加,因此每一次都將產生一對:性能
Replication ID, offset
標記主機數據集精確的版本
當從節點鏈接到主節點的時候,他們使用PSYNC
命令發送他們目前爲止執行的舊的同步ID和偏移量。這種方式下,主節點能夠值發送增加部分,然而,若是主節點沒有足夠的日誌備份,或者從節點使用了一個過去的同步ID,主節點沒法找到他,就會發生全量同步:這種狀況下,從節點將會獲得一個完成的數據複製集,重新開始。
更多全量同步工做的方式:
主節點開始一個後臺進程保存數據,產生一個RDB
文件。同時開始緩存從客戶端來的全部寫命令。當後臺保存進程完成,主節點將會把數據文件發送給從節點,他保存在磁盤中,而後加載到內存。主節點也會立刻發送緩存命令到從節點。這將會以Redis
協議自己相同的命令流格式完成。
你能夠足跡經過telnet
嘗試。在服務店正在執行一些工做的時候鏈接Redis
端口併發送SYNC
命令。你能夠看到大部分的傳輸而且主節點收到的全部命令都會telnet
中打印出來。事實上SYNC
是一箇舊的協議,不在新的Redis
實例上使用,可是依舊向後兼容的:他不容許從新增量同步,因此PSYNC
用來代替他。ui
正常狀況下,一個全量同步須要建立一個RDB
文件,而後從磁盤中讀取這個文件,再發送給從節點。
然而磁盤讀取是很是慢的,這將給主節點形成很是大的壓力。Redis 2.8.18
之後支持無盤同步。在這種設置下,子進程能夠直接經過網絡發送RDB
給從節點,從而避免使用磁盤當作中間存儲。
配置Redis
同步是很簡單的,添加如下命令到配置文件就能夠了:
slaveof 192.168.1.1 6379
固然你必須使用你主節點的IP和端口覆蓋192.168.1.1 6379
參數。當你使用SLAVEOF
命令的時候,主節點就會開始同步數據到從節點
固然還有一些參數用來開啓同步日誌,讓主節點加載到內存中去執行增量同步。能夠查看Redis
發行版中的redis.conf
文件查看更新信息。
無盤同步可使用repl-diskless-sync
配置參數開啓。延遲傳輸從而等待更多子節點連接主節點可使用repl-diskless-sync-delay
配置參數控制。更多栗子請查閱發行版中的redis.conf
文件。
Read-only slave
從Redis 2.6
開始,從節點支持只讀模式,而且這是默認開啓的。這個行爲能夠用slave-read-only
來控制,能夠在redis.conf
修改,也可使用CONFIG SET
來設置。
只讀的本身誒單拒絕全部的寫命令,因此不可能寫入從節點,由於會發生錯誤。這並不覺得這這個特性是爲了在不被信任的網絡和客戶端中暴露本身,由於管理命令,好比像DEBUG
、CONFIG
之類的依舊可使用。固然,只讀實例的安全性能夠經過在redus.conf
中的rename-command
禁用命令來提高。
你可能會想爲何要容許只讀的從節點實例能夠被改成可寫的。這些寫入的數據將會被主節點再次同步數據的時候刪除,這裏有幾個合理的用戶場景來講明爲何要短暫的在可寫從節點存儲數據。
好比統計慢Set
或者Sorted Set
操做,並存儲他們到本地,這是一個可寫從節點很常見的用戶場景
然而,要記住,4.0
之前的可寫從節點沒辦法作到key
的過時時間設置,這意味着,若是你使用EXPIRE
或者其餘命令去設置一個key
最大的TTL
,這個key
將會泄露,你將沒法使用讀命令找到他,你將會在key
的統計中看到他,而且他依舊佔據着內存。因此,在一般狀況下可寫從節點使用TTL
將會致使問題(4.0版本之前)。
Redis 4.0 RC3
和更新的版本徹底解決了這個發生在key
寫入超過63個數據庫的問題(可是默認狀況下Redis
實例只有16個數據庫),而且如今可寫從節點能夠像主節點同樣驅逐過時的key
,
一樣須要記住的是從Redis4.0
之後,從節點寫入的數據只存在本地,不會傳播到鏈接到該子節點的子從節點,子從節點接收到的同步流將會和最高的主節點發送給中間節點如出一轍。下面是栗子:
A ---> B ---> C
即便B
是可寫的,C也不會看到B寫入的數據,只會看到A中的數據
若是你的主節點經過requirepass
配置屬性設置了密碼,設置從節點使用密碼同步也是很是簡單的:
使用redis-cli
鏈接從節點,輸入:
config set masterauth <password>
爲了永遠記住他,添加到配置文件中:
masterauth <password>
Redis 2.8
之後,能夠設置主節點只有在有N臺從節點連接的時候能夠寫入請求。
然而,由於Redis
使用的是異步複製,因此沒有辦法保證從節點確實收到的給定的寫入請求,縱遊一個窗口期的數據丟失。
接下來是解釋這個特性是如何工做的:
This is how the feature works:
ping
主節點,告知它全部的複製流工做了。ping
若是至少有N個從節點,若是少於延遲M秒,則寫入將被接受。
你可能以爲經最大努力保證數據安全的機制,雖然數據一致性沒法保證,可是至少只是幾秒的時間窗口內丟失數據。一般狀況下範圍數據丟失可比無範圍數據丟失好多了。
若是條件不知足,主節點將會返回一個錯誤,而且寫入請求將不被接受
下面是這個特性的兩個配置參數:
min-slaves-to-write <number of slaves> min-slaves-max-lag <number of seconds>
查看更多信息,能夠查閱打包在Redis
發行版中的redis.config
。
How Redis replication deals with expires on keys
Redis
同步是如何解決key
的過時的Redis
過時容許key
有一個有限的生存時間。這種特性依賴於實例多時間的控制,從節點正確的複製key
和過時,就是這些key
被lua
修改過。
爲了實現這種特性,Redis
不能信任主節點和從節點時鐘同步的能力,由於這沒法解決這個問題而且還會致使靜態條件和數據集分離,因此Redis
使用三個主要技術來保證過時key
的同步:
key
過時,而是等待主節點讓key
過時。當主節點讓一個key
過時(或者由於LRU
被移除),它同步發往全部從節點的DEL
命令。key
,由於這時候主節點沒法提供一個DEL
命令。爲了解決這個問題,從節點只用它本身的邏輯時鐘報告說這個key
不存在,而且只供讀操做,並不去影響數據集的一致性(而後新的命令就會從主節點來)。這種方式下,從節點就避免了邏輯上過時的key
還存在的問題。在真實的團推中,一個用從節點抓取的HTML
片斷將會避免返回已經比指望存在時間多的緩存。Lua
腳本執行的時候,key
將不會過時,當Lua
腳本執行的時候,概念上來說,主節點的時間是中止的。因此一個key
在腳本執行期間,要麼存在,要麼不存在。這防止key
在腳本運行中間的時候過時,這也是爲了發送相同的腳本到全部的從節點,保證了對數據集的影響是一致的。當一個從節點晉升爲主節點,他將會開始獨立的過時key
,不須要舊的主節點的任何幫助。
Docker
和NAT
中配置同步當使用Docker
或者其餘容器技術作端口轉發或網絡地址轉換的時候,Redis
同步有一些須要額外注意,特別是使用Redis Sentinel
或者其餘系統時,主節點INFO
、ROLE
命令須要輸出並掃描,用來發現從節點地址。
問題在ROLE
命令,和同步章節的INFO
輸出,當發送請求到主節點實例的時候,使用NAT
的環境可能和從節點實例邏輯地址不一樣(能夠用來鏈接從節點的那個地址)。
一樣的,從節點將會被以配置文件中配置的監聽的端口列出,這可能會和轉發的端口不一樣,要注意端口可能被重映射。
爲了解決這個問題,從Redid 3.2.2
開始,強制要求從節點聲明一個任意的IP和端口給主節點。這兩個配置指定是:
slave-announce-ip 5.5.5.5 slave-announce-port 1234
這被記錄在Redis
發行版的redis.conf
文件中。
INFO
和ROLE
命令有兩個命令提供了不少關於主節點和從節點當前的同步參數。一個是INFO
。若是這個命令被以INFO replication
的方式調用,則只顯示和同步緊密相關的信息。另外一個更加計算機友好
的命令是ROLE
,提供了主節點和從節點同步的狀態,同步偏移,列出已鏈接的從節點等。
Redis 4.0
之後支持重啓和故障轉移後的增量從新同步,當一個實例在故障轉之後提高爲主節點,他依舊能夠從舊的主節點那邊執行增量從新同步。爲了作到這一點,從節點記住了從前的主節點的的同步ID和偏移,因此,能夠提供部分的記錄去鏈接從節點,儘管他們請求的是舊的同步ID。
然而,晉升的從及誒單提供的新的同步ID將會不一樣,由於他構建了一個不一樣的數據集歷史。好比,有時候,主節點能夠返回可使用而且能夠繼續接受寫入,因此在晉升的從節點使用相同的同步ID將會破壞規則,即一個同步ID和偏移對只標記一個數據集。
此外,當優雅關閉或者重啓的時候,從節點能夠存儲從主節點同步必須的信息到RDB
文件中。這對升級頗有用,當必須的時候,最好在從節點使用SHUTDOWN
命令去執行一個保存-退出操做。