厲害了!原來Redis是這樣集群的
“Redis用過嗎?”
“用過。”
“能談談對Redis集群的認識嗎?”
“額……”
這是一段真實的面試經歷。
最近,各大互聯(lián)網公司都開始了裁員,導致大量互聯(lián)網從業(yè)人員又開始了艱辛的求職路。老手自不必說,但對于久在項目里但基本只是使用Redis的程序員們來說,估計這問題得難倒一部分人。
Redis集群方式共有三種:主從模式,哨兵模式,cluster(集群)模式。下面我們來一起看卡這三種模式分別是如何工作的吧。
主從模式
主從模式是三種集群方式里最簡單的。它主要是基于Redis的主從復制特性架構的。通常我們會設置一個主節(jié)點,N個從節(jié)點。

默認情況下,主節(jié)點負責處理使用者的IO操作,而從節(jié)點則會對主節(jié)點的數據進行備份,并且也會對外提供讀操作的處理。這樣做有兩個目的:備份數據,負載均衡。
備份數據
主從模式下,當某一節(jié)點損壞時,因為其會將數據備份到其它Redis實例上,這樣做在很大程度上可以恢復丟失的數據。
負載均衡
主從模式下,主節(jié)點和從節(jié)點是讀寫分離的。使用者不僅可以從主節(jié)點上讀取數據,還可以很方便的從從節(jié)點上讀取到數據,這在一定程度上緩解了主機的壓力。
當然,從節(jié)點也是能夠支持寫入數據的,只不過從從節(jié)點寫入的數據不會同步到主節(jié)點以及其它的從節(jié)點下。
從以上,我們不難看出Redis在主從模式下,必須保證主節(jié)點不會宕機——一旦主節(jié)點宕機,其它節(jié)點不會競爭稱為主節(jié)點,此時,Redis將喪失寫的能力。這點在生產環(huán)境中,是致命的。所以Redis為我們引入了另一種集群模式——哨兵模式。
哨兵模式
哨兵模式是基于主從模式做的一定變化,它能夠為Redis提供了高可用性。在實際生產中,服務器難免不會遇到一些突發(fā)狀況:服務器宕機,停電,硬件損壞等。這些情況一旦發(fā)生,其后果往往是不可估量的。而哨兵模式在一定程度上能夠幫我們規(guī)避掉這些意外導致的災難性后果。
其實,哨兵模式的核心還是主從復制。只不過相對于主從模式在主節(jié)點宕機導致不可寫的情況下,多了一個競選機制——從所有的從節(jié)點競選出新的主節(jié)點。競選機制的實現,是依賴于在系統(tǒng)中啟動一個sentinel進程。

sentinel特點
- 監(jiān)控
- 它會監(jiān)聽主服務器和從服務器之間是否在正常工作。
- 通知
- 它能夠通過API告訴系統(tǒng)管理員或者程序,集群中某個實例出了問題。
- 故障轉移
- 它在主節(jié)點出了問題的情況下,會在所有的從節(jié)點中競選出一個節(jié)點,并將其作為新的主節(jié)點。
- 提供主服務器地址
- 它還能夠向使用者提供當前主節(jié)點的地址。這在故障轉移后,使用者不用做任何修改就可以知道當前主節(jié)點地址。
就sentinel而言,其當然也具備一定集群能力,Redis sentinel本身就是一個分布式系統(tǒng)。但sentinel集群,和其他的集群有點不一樣。sentinel可以通過發(fā)布與訂閱來自動發(fā)現Redis集群上的其它sentinel。sentinel在發(fā)現其它sentinel進程后,會將其放入一個列表中,這個列表存儲了所有已被發(fā)現的sentinel。
集群中的所有sentinel不會并發(fā)著去對同一個主節(jié)點進行故障轉移。故障轉移只會從第一個sentinel開始,當第一個故障轉移失敗后,才會嘗試下一個。當選擇一個從節(jié)點作為新的主節(jié)點后,故障轉移即成功了(而不會等到所有的從節(jié)點配置了新的主節(jié)點后)。這過程中,如果重啟了舊的主節(jié)點,那么就會出現無主節(jié)點的情況,這種情況下,只能重啟集群。
當競選出新的主節(jié)點后,被選為新的主節(jié)點的從節(jié)點的配置信息會被sentinel改寫為舊的主節(jié)點的配置信息。完成改寫后,再將新主節(jié)點的配置廣播給所有的從節(jié)點。
Cluster(集群)模式
Cluster(集群)模式的出現是為了解決Redis單機容量有限的問題的。該種模式會將Redis中數據按照一定規(guī)則劃分到多臺機器上。這種模式有兩個特點:
能夠在多個節(jié)點之間自動拆分數據集。
當節(jié)點的子集遇到故障或無法與群集的其余部分通信時,能夠繼續(xù)操作。
Redis集群中有16384個散列槽。而Redis群集中的每個節(jié)點只負責哈希槽的一個子集。
例如,您可能擁有一個包含3個節(jié)點的集群,其中:
- 節(jié)點A包含從0到5500的散列槽。
- 節(jié)點B包含從5501到11000的散列槽。
- 節(jié)點C包含從11001到16383的散列槽。
這允許使用者輕松添加和刪除集群中的節(jié)點。例如,如果我想添加一個新節(jié)點D,我需要將一些哈希槽從節(jié)點A,B,C移動到D.同樣,如果我想從群集中刪除節(jié)點A,我只需移動A服務的哈希槽。到B和C.當節(jié)點A為空時,我可以完全從集群中刪除它。
因為將哈希槽從一個節(jié)點移動到另一個節(jié)點不需要停止操作,添加和刪除節(jié)點,或者更改節(jié)點所持有的哈希槽的百分比,所以不需要任何停機時間。