redis學習(七)redis主從複製
redis主從複製
1.redis主從複製的作用
redis的定位是一個高可用的資料伺服器,可是在實際生產環境下,單機的redis伺服器是無法滿足真正意義上的高可用性的。
第一,單機的redis伺服器很容易發生單點故障,即使redis提供了各種持久化的方法來避免資料的丟失,但是物理上的故障(硬碟損毀等)還是無法完全避免的。
第二,如果對單臺機器的效能進行縱向拓展,無論是CPU,記憶體還是磁碟容量都很容易達到瓶頸,無法滿足實際需求。
針對這些問題,redis提供了 複製(replication) 的功能,通過"主從(一主多從)"和"叢集(多主多從)"的方式對redis的服務進行水平擴充套件,用多臺redis伺服器共同構建一個高可用的redis服務系統。
在這裡,我們主要介紹redis的主從複製功能。
2.redis主從複製介紹
在redis的複製概念模型中,分為 "主(master)" 和 "從(slave)" 兩種角色型別的伺服器,從伺服器 "服從" 主伺服器。主伺服器既可以讀也可以寫,而從伺服器原則上只允許讀操作(通過修改配置,從伺服器也可以執行寫入操作),同時負責接收和同步主伺服器上的資料。主伺服器和從伺服器是一對多的關係,從伺服器也可以擁有從伺服器,以此類推。
可以看到主從結構下的redis伺服器叢集節點的拓撲結構是一棵樹。
使用了主從結構的redis系統,一般是讀寫分離的:"主庫負責寫入,在寫入的同時和從庫進行資料的同步;而從庫負責讀取操作。"
一主多從的結構下,不會出現單點故障,同時可用性也得到了保障。由於負責讀取的從庫相對較多,因此很適合讀多寫少(例如:電商)的場景。
使用redis的主從複製功能比較簡單,只需要在從伺服器啟動的配置檔案中新增slaveof "IP" "PORT"配置即可,同時redis也允許其它的方式來實現這一目的(啟動時命令列引數、redis命令等)。可以通過 info replication 來檢視當前redis伺服器在主從複製中的狀態。
6381埠 從庫狀態
6379埠 主庫狀態
3.redis主從複製原理
1.從伺服器初始化
當從伺服器啟動時,會向主伺服器傳送 SYNC 命令,請求同步資料。主伺服器接收到訊息之後,進行RDB持久化,並生成一個快照檔案;與此同時,主伺服器會將生成快照期間新執行的命令快取起來。在快照檔案生成完畢之後,主伺服器將RDB快照檔案和快取下來的命令一併傳送給從伺服器,從伺服器首先載入接收到的RDB快照檔案,接著執行被快取下來的新命令,完成主從資料的初始化同步操作。
2.從伺服器保持同步
從伺服器在同步完成之後,主伺服器接收到的所有命令都會非同步的傳送給從伺服器用來保持主從資料的一致性。
3.從伺服器故障後處理
當從伺服器崩潰之後,重啟之後進行初始化,會自動的同步主伺服器的資料。在redis的2.8版本之後,redis採用了 "增量複製" 的方式優化了從伺服器的初始化同步資料的過程。
4.主伺服器故障後處理
當主伺服器崩潰之後,首先需要手動的選擇一個從伺服器升級為主伺服器(需要手動調整所有相關的從伺服器),然後啟動之前已經崩潰的主伺服器作為從伺服器回到系統中。
可以看到,redis在主伺服器崩潰之後需要繁瑣的人工干預來恢復服務,特別是在主資料庫禁止了持久化之後,上述步驟不能錯亂,否則會導致主資料庫重啟後恢復了錯誤資料,進而導致從資料庫也同步錯誤資料這一災難性後果。為此,redis提供了哨兵機制,用於自動化的監控和維持分散式redis系統的良好運轉。
4.redis哨兵
1.哨兵的介紹
redis的設計者為了讓redis能夠在主從模式下實現故障恢復的自動化,為此提供了redis的哨兵功能。哨兵是一個獨立於資料伺服器的程序,用於監控redis資料伺服器的狀態,當主從模式下最關鍵的主伺服器出現故障時,能夠被哨兵自動的察覺。同時哨兵會在剩餘的從伺服器中 "選舉" 出新的主伺服器,達到自動化恢復系統服務的目的。
2.哨兵的使用
redis提供了 redis-sentinel 指令碼用於部署哨兵,啟動時通過指定的哨兵配置檔案來對哨兵的行為進行靈活的控制。哨兵的配置檔案中至少需要包含被哨兵監控的主伺服器IP、埠、投票決定數目,當然也可以配置諸如 down-after-milliseconds (傳送 ping 命令的時間間隔,用於監聽)等選項。
sentinel monitor "master_name" "IP" "PORT"
down-after-milliseconds "milliseconds" ("milliseconds"大於1000時,預設為1000)
3.哨兵的工作方式
哨兵啟動時會與主伺服器建立連線,並且間接的獲得所屬從伺服器資訊,完成哨兵的初始化。哨兵初始化完成之後,會週期性的和主從伺服器、其它哨兵節點(通過訊息頻道的訂閱/釋出)進行通訊。
哨兵每10秒會向所有伺服器傳送一次 INFO 命令,獲得相關redis伺服器的當前狀態以便決定是否需要故障恢復。
當一個哨兵在 down-after-milliseconds 規定時間內未收到主伺服器的響應,則當前哨兵 "主觀" 認為主伺服器下線,同時和監視當前系統的其它哨兵進行投票決定,當超過當前哨兵配置中投票決定的數目時,則當前哨兵 "客觀" 認為主伺服器下線,哨兵叢集會選舉出領導哨兵來進行主從伺服器叢集主從狀態的切換(使用Raft演算法)。
5.redis主從複製總結
1.樂觀複製策略
redis的主從複製採用的是樂觀複製的策略,在一定的時間內允許主從伺服器的資料不完全一致,但是保持主從資料庫資料的最終一致性(按照 CAP定理 ,放棄了 C (強一致性))。
這意味著redis主從伺服器之間的資料複製操作時非同步的,主伺服器不等待從伺服器返回複製的結果,可以立即處理新的寫入命令。這一策略使得主伺服器的效能在複製時不會受到太大影響,但是從伺服器會出現短時間內資料不一致的情況。redis允許使用者配置主庫的 min-slaves-to-write (代表至少N臺從伺服器完成複製,才允許主伺服器寫入)和 min-slaves-max-lag (允許從伺服器斷開連線的時間)這兩個配置項來控制分割槽中資料不一致的影響。
2.和叢集的區別
redis的主從複製特性為redis帶來了很高的讀取可用性,但是對於海量資料的持久化儲存是力不從心的。因為主從複製結構下,任意的節點都儲存了100%的儲存資料,所以能夠儲存的資料規模還是受限於單例伺服器儲存容量的大小。
為此,在單主多從結構的基礎上,redis還提供了叢集特性。通過將儲存資料合理的分片儲存在不同的redis節點上,通過叢集水平擴容之後的redis叢集擁有了極高的讀寫可用性和分割槽容錯性。為了理解更強大、複雜的叢集特性其基礎之一就是redis的主從複製原理。