我們知道,為了幫助數據庫緩解高并發的壓力,我們會上reids緩存幫助數據庫分攤,雖說常見場景的并發量還不足以讓redis宕機,但假設出現了極高的并發場景,redis依舊是有宕機的可能的,畢竟單點部署的redis容易出現的問題很多,而為了優化這一點,reids就衍生出了許多集群來幫助reids來實現高可用。
1.什么是redis的集群,redis的集群都有哪些
? ? ?redis集群是 redis 官方提供的分布式解決方案,用于將數據自動分片到多個節點上,實現數據的拓展,同時提供高可用性,通過redis的集群可以幫助redis解決一些單點布置會發生的一系列故障問題。
? ? ?redis的集群主要是分主從集群,哨兵集群以及分片集群,當然還存在其他的為特殊需求所構建的集群,不過我們重點需要學習的就是這三種集群。
2.redis的主從集群
? ? ?當部署的單點redis宕機以后,大量的請求就會打入數據庫,為了解決這種情況我們就會部署多個redis來組成主從集群,從中的節點分為主節點和從節點兩個身份,主節點只允許寫入數據而從節點只允許讀取數據,而從節點的數據通過主從復制來從主節點中獲取數據。
? ? ?主從復制具體的是分成兩種形式,分別是全量復制和增量復制,接下來我會區分二者講解:
全量復制:
執行時機:當部署新的從節點或者舊的從節點在宕機很久后恢復
基本概念:意味著從節點會復制主節點的全量數據
底層實現:主節點執行bgsave的命令生成RDB文件,發送給從節點,而從節點獲取到RDB文件后會加載到內存當中,這就獲取了全量數據,假設RDB文件制作過程中又有新的寫命令進入,那就通過將命令存入暫存區,在同步完后發送。
增量復制:
執行時機:當從節點已經包含一定數據,且一直正常運行或宕機時間不長
基本概念:意味著從節點會不斷的獲取主節點新增的數據
底層實現:當主從完成全量復制以后會通過TCP維持一個主從的長連接,這樣在獲取到新的寫操作命令后,主節點就會異步的將這些寫命令發送給從節點。
? ? ?這里有個小知識點,為什么全量復制要使用RDB而非AOF?這個原因有兩點,第一是RDB保存的二進制的數據文件,而AOF保存的是寫命令,相比之下RDB的文件更小更輕巧。第二就是RDB的數據恢復速度很快,而AOF的是執行寫命令操作,這樣效率就很慢了。
? ? ?這樣的一個集群具有兩個好處,首先部署多臺redis可以分散請求,降低單點的并發量,其次即使主節點依舊被海量壓力沖跨,或者出現意外導致宕機,可以通過主從集群的特性來選舉新的主節點,并同時監控宕機的主節點在恢復后設置為從節點。
3.redis的哨兵集群
? ? ?我們可以想象一個場景,按照redis自己所處的主從情況之下,我們會發現假設主節點宕機,就需要手動的從多個從節點中推舉出一個新的主節點,再手動的轉從為主,這光是看著就很麻煩,因此redis就創造了哨兵集群,哨兵集群能夠自動監控所有redis節點的狀態,假設主節點宕機,就會自動的做主從故障的轉移,這樣就會方便許多。
? ? ?那哨兵集群究竟是怎么知道主節點宕機的呢?
? ? ?哨兵集會和其他節點建立一個心跳檢測,不斷的向主節點發送ping的命令,而一旦發現主節點長時間沒有回應,這個哨兵節點就會判斷主節點為主觀下線,但是一個哨兵節點長時間接受不到主節點回應的因素是很多的,例如網絡因素等,因此只能判斷為主觀下線,所以一般來說只有一個集群中超半數的哨兵節點都認為主節點下線,這個主節點才會被判斷為客觀下線。
? ? ?在哨兵節點判斷主節點宕機以后,如何選擇新的主節點呢?
? ? ?首先哨兵集群會通過raft的leader算法來選舉哨兵當中的leader節點,后用這個leader節點來選舉新的主節點,具體的規則如下:? ? ? ? ? ??
? ? ?在選取新的主節點后,會通過主從復制將新選舉的主節點的數據復制給其他從節點,之后就會將新的主節點數據發送給客戶端。
? ? ?而在設置好新的主節點后,哨兵leader依舊會繼續監視舊的主節點,當舊的主節點恢復后就會將其設置為新的從節點。
4.redis的分片集群
? ? ?對比最原始的主從集群,我們會發現幾個問題:
? ? ?首先不論主節點還是從節點存儲的都是全量數據,雖說在創建主從的時候是部署了多臺redis,但在最終的存儲量依舊是要看主節點的內存量的,因此原始的主從內存量是單機情況內存是不夠的,就算勉強夠用,也會導致RDB文件變大使得每次數據復制的速度變慢。
? ? ?其次就是只有單一的主節點能執行寫操作,假設需要設置另一個類型的數據庫,就無法拓展新的寫操作命令。
? ? ?正因為有這兩個問題存在,redis的分片集群也就誕生了,redis的分片集群是部署多臺redis組成集群,每個redis節點都可以單獨做寫操作,并且可以分散存儲數據,不過這里有一個問題,就是redis節點可能會出現宕機的情況,為了解決這個問題,我們會對每個節點做主從,因此分片集群可以粗略當成多個主從集群組成的集群。
? ? ?為了做數據分片,分片集群準備了16384個hash槽,將這些槽平均分給不同的節點,當數據進入時,使用CRC16算法去獲取到數據應當存儲槽的位置,不過在槽發生擴容縮容的時候可能會導致槽的位置遷移,不過分片集群會做一個檢測,假設槽與對應的節點不匹配,就會通知客戶端并重新匹配。
? ? ?為了完成節點之間的通信,redis集群利用了Gossip協議,具體方式如下:
而分片集群的主從故障也是通過Gossip協議來檢測其他的節點而非像基礎的哨兵集群,各個主節點會互相檢測,假設一半以上主節點認為某個主節點宕機,就會通過其從節點找出新的主節點,再用fail通知其他的節點。
今天的分享就到這里了,希望這篇博客能給你一些幫助,讓你對關于redis的集群的問題得到進一步的提升,在面試的時候能從容面對面試官。