在主從複製中,數據庫分爲兩類:主數據庫(master)和從數據庫(slave)。node
當slave啓動後,主動向master發送SYNC命令。master接收到SYNC命令後在後臺保存快照(RDB持久化)和緩存保存快照這段時間的命令,而後將保存的快照文件和緩存的命令發送給slave。slave接收到快照文件和命令後加載快照文件和緩存的執行命令。redis
爲了在主節點子集發生故障或沒法與大多數節點通訊時保持可用,Redis Cluster使用主從模型,其中每一個哈希槽具備從1(主節點自己)到N個副本(N個) -1個其餘從屬節點)。在具備節點A,B,C的示例集羣中,若是節點B失敗,則集羣將沒法繼續,由於咱們再也不有辦法爲5501-11000範圍內的哈希槽提供服務。算法
可是,在建立集羣(或稍後)時,咱們向每一個主節點添加一個從屬節點,以便最終集羣由做爲主節點的A,B,C和做爲從屬節點的A1,B1,C1組成,若是節點B發生故障,系統將可以繼續。數據庫
節點B1複製B,而且B發生故障,羣集會將節點B1提高爲新的主節點,並將繼續正常運行。緩存
可是請注意,若是節點B和B1同時失敗,則Redis Cluster沒法繼續運行。安全
解決問題:服務器
解決Redis單例下,數據體量大與數據備份形成的性能瓶頸問題,redis cluster 主從模型很好的解決這個問題。能夠將讀寫操做分離到不一樣redis實例上,提升系統的吞吐量 網絡
引入新的問題:併發
一、配置重連問題dom
不一樣的redis實例,須要不一樣的ip和端口對應,若是某個實例下線了,須要從新更改配置進行重連
二、故障轉移問題
若是某個結點故障下線,沒法進行故障轉移,好比某個master下線,對應的slave結點也只能進行讀操做,沒法進行寫操做,替代不了master的功能。
特色以下:
缺點以下:
master節點在主從模式中惟一,若master掛掉,則redis沒法對外提供寫服務,不具有高可用性。
Redis 的 Sentinel 系統用於管理多個 Redis 服務器(instance)。
監控(Monitoring): Sentinel 會不斷地檢查你的主服務器和從服務器是否運做正常。
提醒(Notification): 當被監控的某個 Redis 服務器出現問題時, Sentinel 能夠經過 API 向管理員或者其餘應用程序發送通知。
自動故障遷移(Automatic failover): 當一個主服務器不能正常工做時, Sentinel 會開始一次自動故障遷移操做, 它會進行選舉,將其中一個從服務器升級爲新的主服務器, 並讓失效主服務器的其餘從服務器改成複製新的主服務器; 當客戶端試圖鏈接失效的主服務器時, 集羣也會向客戶端返回新主服務器的地址, 使得集羣可使用新主服務器代替失效服務器。
解決問題:
Sentinel哨兵模式,確實實現自動故障切換。提供穩定的服務,解決主從模型引入的新問題。
未解決的問題:
在哨兵模式中,仍然只有一個Master節點。當併發寫請求較大時,哨兵模式並不能緩解寫壓力。
特色以下:
從Redis 3.0
以後版本支持 Redis Cluster
集羣,Redis Cluster採用無中心結構,每一個節點保存數據和整個集羣狀態,每一個節點都和其餘全部節點鏈接。
目標:
高性能:
採用了主從複製的機制,Master 節點失效時 Slave 節點自動提高爲 Master 節點。若是 Cluster 中有N個 Master 節點,每一個 Master 擁有1個 Slave 節點,那麼這個 Cluster 的失效機率爲 1/(2*N-1),可用機率爲 1-1/(2*N-1)。
高可擴展:
可支持多達1000
個服務節點。隨時能夠向 Cluster 中添加新節點,或者刪除現有節點。Cluster 中每一個節點都與其它節點創建了相互鏈接
一致性:
Redis Cluster沒法保證強一致性。實際上,這意味着在某些狀況下,Redis Cluster可能會丟失系統承認給客戶端的寫入。
Redis Cluster可能丟失寫入的第一個緣由是由於它使用異步複製。這意味着在寫入期間會發生如下狀況:
B在回覆客戶端以前不會等待B1,B2,B3的確認,由於這會對Redis形成延遲性的延遲,所以,若是您的客戶端寫了一些東西,B會確認寫,可是在崩潰以前崩潰因爲可以將寫操做發送到其從屬服務器,所以一個從屬服務器(未接收到寫操做)能夠升級爲主服務器,從而永遠丟失該寫操做。
特色以下:
密鑰空間被劃分爲16384個插槽,有效地設置了16384個主節點的羣集大小的上限(可是建議的最大節點大小約爲1000個節點)。
羣集中的每一個主節點都處理16384個哈希槽的子集。當沒有正在進行的集羣從新配置時(即哈希槽從一個節點移動到另外一個節點),該集羣是穩定的。當羣集穩定時,單個哈希槽將由單個節點提供服務(可是,服務節點能夠具備一個或多個從屬設備,在發生網絡分裂或故障的狀況下能夠替換該從屬設備,而且能夠用於擴展)可接受過期數據的讀取操做)。
鍵映射到哈希槽的基本算法:HASH_SLOT = CRC16(key) mod 16384
哈希標籤是一種確保在同一哈希槽中分配多個密鑰的方法。這用於在Redis Cluster中實現多鍵操做。
爲了實現哈希標籤,在某些狀況下,密鑰的哈希槽以略有不一樣的方式計算。若是密鑰包含一個「{...}」圖案僅之間子 {
和}
,以得到散列時隙被散列。可是,因爲可能存在屢次出現{
或}
算法由如下規則很好地指定:
{
字符。}
字符的右{
{
和的第一次出現之間存在一個或多個字符}
。每一個節點在集羣中都有惟一的名稱。節點名稱是160位隨機數的十六進制表示形式,是在節點首次啓動時得到的(一般使用/ dev / urandom)。節點將其ID保存在節點配置文件中,並將永久使用相同的ID,或者至少在系統管理員未刪除節點配置文件或經過CLUSTER RESET命令請求硬重置的狀況下使用該ID 。
節點ID用於標識整個集羣中的每一個節點。給定節點能夠更改其IP地址,而無需也更改節點ID。羣集還可以檢測IP /端口的更改,並使用在羣集總線上運行的八卦協議進行從新配置。
節點ID並非與每一個節點關聯的惟一信息,而是惟一始終全局一致的信息。每一個節點還具備如下關聯的信息集。一些信息與該特定節點的集羣配置詳細信息有關,而且最終在整個集羣中保持一致。某些其餘信息(例如上次對節點執行ping操做)則是每一個節點本地的。
每一個節點都維護着有關羣集中其餘節點的如下信息:節點ID,節點的IP和端口,一組標誌,若是將節點標誌爲slave
,則該節點的主節點是什麼?對節點執行ping操做,最後一次接收到pong時,將顯示該節點的當前 配置時期(在本規範的後面部分進行說明),連接狀態以及最終服務的哈希槽集。
每一個Redis Cluster節點都有一個額外的TCP端口,用於接收來自其餘Redis Cluster節點的傳入鏈接。此端口與用於從客戶端接收傳入鏈接的普通TCP端口處於固定偏移量。要得到Redis Cluster端口,應在常規命令端口中添加10000。例如,若是Redis節點正在端口6379上偵聽客戶端鏈接,則羣集總線端口16379也將打開。
節點到節點的通訊僅使用羣集總線和羣集總線協議進行:羣集協議是由不一樣類型和大小的幀組成的二進制協議。未公開記錄集羣總線二進制協議,由於它不打算供外部軟件設備使用該協議與Redis Cluster節點通訊。可是,您能夠經過閱讀Redis Cluster源代碼中的cluster.h
和cluster.c
文件來獲取有關集羣總線協議的更多詳細信息 。
Redis Cluster是一個完整的網格,其中每一個節點都使用TCP鏈接與其餘每一個節點鏈接。
在N個節點的羣集中,每一個節點都有N-1個傳出TCP鏈接和N-1個傳入鏈接。
這些TCP鏈接始終保持活動狀態,而且不會按需建立。當節點但願對集羣總線中的ping作出迴應時,會在等待足夠長的時間以將節點標記爲不可訪問以前進行Pong響應,它將嘗試經過從頭開始從新鏈接來刷新與該節點的鏈接。
雖然Redis Cluster節點造成一個完整的網格,可是節點使用八卦協議和配置更新機制以免在正常狀況下在節點之間交換太多消息,所以交換的消息數量不是指數級的。
節點始終接受羣集總線端口上的鏈接,即便收到ping節點不受信任,甚至會在收到ping時回覆ping。可是,若是不將發送節點視爲羣集的一部分,則接收節點將丟棄全部其餘數據包。
一個節點僅以兩種方式將另外一個節點做爲羣集的一部分:
這意味着只要咱們在任何鏈接圖中加入節點,它們最終將自動造成徹底鏈接圖。這意味着羣集可以自動發現其餘節點,但前提是存在系統管理員強制創建的信任關係。
這種機制使羣集更加健壯,但能夠防止更改IP地址或其餘與網絡相關的事件後,不一樣的Redis羣集意外混合。