redis的多種模式 單機模式、主從模式、哨兵模式、集群模式


 

Redis有四種常見的運行模式,分別為:

單機模式

主從模式

哨兵模式

集群模式

1.單機模式

單機模式是指在單台服務器中運行的Redis程序,是最原始最基本的模式。

單機模式的優勢在於部署簡單只要安裝好Redis,並進行簡單配置即可,因為沒有其他Redis節點,因此費用低廉。

單機模式的缺點在於可靠性差,如果Redis宕機,那么服務也就會直接失效。同時因為Redis是單線程的,所以在單機上運行時受CPU的影響很大。

單機模式通常適合於在不需要很高的性能以及可靠性的小型業務場景。

2.主從模式

主從模式是指將一個Redis節點設置為主節點,其他Redis節點設置為從節點,通過將主節點的數據復制到其他的Redis服務器中(單向),此時請求會按規則訪問所有的Redis節點,因此主節點的訪問壓力也就被從節點所分擔了。並且當主節點宕機時,會將一個從節點提升為主節點,因此系統的可靠性也有所提高。

主從模式擴展了主節點的讀能力,但存儲和寫都受主節點的性能限制,並且該模式下數據存在大量冗余情況。

3.哨兵模式

哨兵模式是在主從模式的基礎上,增加了哨兵節點這一個概念。在哨兵模式中,節點分為哨兵節點和數據節點兩種:

哨兵節點可以是一個或多個,每個節點都是一種特殊的Redis節點,該節點並不存儲數據。

數據節點則由主節點和從節點組成,和之前的主從節點類似。

其中由哨兵節點負責監視數據節點,其原理是通過Ping方式判斷數據節點是否存活,如果Ping超時,則將該節點標記為主觀下線狀態,當有指定數量以上的哨兵節點也發現該數據節點處於主觀下線狀態,就將其標記為客觀下線狀態。

哨兵模式的優點是:

具備所有主從模式的優點(是主從模式的升級)

主從節點可以自動切換,增強了系統的可用性

缺點是哨兵節點也有幾率會發生宕機,從而引起集群的故障

4.集群模式

集群模式是通過數據分片的方式來將數據分配到不同的分片上,因此其數據冗余較小,其故障轉移也和哨兵模式類似。
 

 

 

redis的多種模式
都說了升級到哨兵模式,那之前用的不是哨兵模式,肯定還有其他模式。

單機模式、主從模式、哨兵模式、集群模式

單機模式

這個最簡單,一看就懂。

就是安裝一個redis,啟動起來,業務調用即可。具體安裝步驟和啟動步驟就不贅述了,網上隨便搜一下就有了。

單機在很多場景也是有使用的,例如在一個並非必須保證高可用的情況下。

咳咳咳,其實我們的服務使用的就是redis單機模式,所以來了就讓我改為哨兵模式。

說說單機的優缺點吧。

優點:

部署簡單,0成本。

成本低,沒有備用節點,不需要其他的開支。

高性能,單機不需要同步數據,數據天然一致性。

缺點:

可靠性保證不是很好,單節點有宕機的風險。

單機高性能受限於CPU的處理能力,redis是單線程的。

單機模式選擇需要根據自己的業務場景去選擇,如果需要很高的性能、可靠性,單機就不太合適了。

主從復制
主從復制,是指將一台Redis服務器的數據,復制到其他的Redis服務器。

前者稱為主節點(master),后者稱為從節點(slave);數據的復制是單向的,只能由主節點到從節點。

 

主從模式配置很簡單,只需要在從節點配置主節點的ip和端口號即可。

啟動主從節點的所有服務,查看日志即可以看到主從節點之間的服務連接。

從上面很容易就想到一個問題,既然主從復制,意味着master和slave的數據都是一樣的,有數據冗余問題。

在程序設計上,為了高可用性和高性能,是允許有冗余存在的。這點希望大家在設計系統的時候要考慮進去,不用為公司節省這一點資源。

對於追求極致用戶體驗的產品,是絕對不允許有宕機存在的。

主從模式在很多系統設計時都會考慮,一個master掛在多個slave節點,當master服務宕機,會選舉產生一個新的master節點,從而保證服務的高可用性。

主從模式的優點:

一旦 主節點宕機,從節點 作為 主節點 的 備份 可以隨時頂上來。

擴展 主節點 的 讀能力,分擔主節點讀壓力。

高可用基石:除了上述作用以外,主從復制還是哨兵模式和集群模式能夠實施的基礎,因此說主從復制是Redis高可用的基石。

也有相應的缺點,比如我剛提到的數據冗余問題:

一旦 主節點宕機,從節點 晉升成 主節點,同時需要修改 應用方 的 主節點地址,還需要命令所有 從節點 去 復制 新的主節點,整個過程需要 人工干預。

主節點 的 寫能力 受到 單機的限制。

主節點 的 存儲能力 受到 單機的限制。

哨兵模式
剛剛提到了,主從模式,當主節點宕機之后,從節點是可以作為主節點頂上來,繼續提供服務的。

但是有一個問題,主節點的IP已經變動了,此時應用服務還是拿着原主節點的地址去訪問,這...

於是,在Redis 2.8版本開始引入,就有了哨兵這個概念。

在復制的基礎上,哨兵實現了自動化的故障恢復。

 

如圖,哨兵節點由兩部分組成,哨兵節點和數據節點:

哨兵節點:哨兵系統由一個或多個哨兵節點組成,哨兵節點是特殊的redis節點,不存儲數據。

數據節點:主節點和從節點都是數據節點。

訪問redis集群的數據都是通過哨兵集群的,哨兵監控整個redis集群。

一旦發現redis集群出現了問題,比如剛剛說的主節點掛了,從節點會頂上來。但是主節點地址變了,這時候應用服務無感知,也不用更改訪問地址,因為哨兵才是和應用服務做交互的。

Sentinel 很好的解決了故障轉移,在高可用方面又上升了一個台階,當然Sentinel還有其他功能。

比如 主節點存活檢測、主從運行情況檢測、主從切換。

Redis的Sentinel最小配置是 一主一從。

說下哨兵模式監控的原理

每個Sentinel以 每秒鍾 一次的頻率,向它所有的 主服務器、從服務器 以及其他Sentinel實例 發送一個PING 命令。

 

如果一個 實例(instance)距離最后一次有效回復 PING命令的時間超過 down-after-milliseconds 所指定的值,那么這個實例會被 Sentinel標記為 主觀下線。

如果一個 主服務器 被標記為 主觀下線,那么正在 監視 這個 主服務器 的所有 Sentinel 節點,要以 每秒一次 的頻率確認 該主服務器是否的確進入了 主觀下線 狀態。

如果一個 主服務器 被標記為 主觀下線,並且有 足夠數量 的 Sentinel(至少要達到配置文件指定的數量)在指定的 時間范圍 內同意這一判斷,那么這個該主服務器被標記為 客觀下線。

在一般情況下, 每個 Sentinel 會以每 10秒一次的頻率,向它已知的所有 主服務器 和 從服務器 發送 INFO 命令。

當一個 主服務器 被 Sentinel標記為 客觀下線 時,Sentinel 向 下線主服務器 的所有 從服務器 發送 INFO 命令的頻率,會從10秒一次改為 每秒一次。

Sentinel和其他 Sentinel 協商 主節點 的狀態,如果 主節點處於 SDOWN`狀態,則投票自動選出新的主節點。將剩余的 從節點 指向 新的主節點 進行 數據復制。

當沒有足夠數量的 Sentinel 同意 主服務器 下線時, 主服務器 的 客觀下線狀態 就會被移除。當 主服務器 重新向 Sentinel的PING命令返回 有效回復 時,主服務器 的 主觀下線狀態 就會被移除。

哨兵模式的優缺點

​ 優點:

哨兵模式是基於主從模式的,所有主從的優點,哨兵模式都具有。

主從可以自動切換,系統更健壯,可用性更高。

Sentinel 會不斷的檢查 主服務器 和 從服務器 是否正常運行。當被監控的某個 Redis 服務器出現問題,Sentinel 通過API腳本向管理員或者其他的應用程序發送通知。

​ 缺點:

Redis較難支持在線擴容,對於集群,容量達到上限時在線擴容會變得很復雜。

 

我的任務

我部署的redis服務就如上圖所示,三個哨兵節點,三個主從復制節點。

使用java的jedis去訪問我的redis服務,下面來一段簡單的演示代碼(並非工程里面的代碼):

public static void testSentinel() throws Exception {
//mastername從配置中獲取或者環境變量,這里為了演示
String masterName = "master";
Set<String> sentinels = new HashSet<>();
// sentinel的IP一般會從配置文件獲取或者環境變量,這里為了演示
sentinels.add("192.168.200,213:26379");
sentinels.add("192.168.200.214:26380");
sentinels.add("192.168.200.215:26381");

//初始化過程做了很多工作
JedisSentinelPool pool = new JedisSentinelPool(masterName, sentinels); 
//獲取到redis的client
Jedis jedis = pool.getResource();
//寫值到redis
jedis.set("key1", "value1");
//讀取數據
jedis.get("key1");
}

 


集群模式
主從不能解決故障自動恢復問題,哨兵已經可以解決故障自動恢復了,那到底為啥還要集群模式呢?

主從和哨兵都還有另外一些問題沒有解決,單個節點的存儲能力是有上限,訪問能力是有上限的。

Redis Cluster 集群模式具有 高可用、可擴展性、分布式、容錯 等特性。

Cluster 集群模式的原理

通過數據分片的方式來進行數據共享問題,同時提供數據復制和故障轉移功能。

之前的兩種模式數據都是在一個節點上的,單個節點存儲是存在上限的。集群模式就是把數據進行分片存儲,當一個分片數據達到上限的時候,就分成多個分片。

數據分片怎么分?

集群的鍵空間被分割為16384個slots(即hash槽),通過hash的方式將數據分到不同的分片上的。

CRC16是一種循環校驗算法,這里不是我們研究的重點,有興趣可以看看。

這里用了位運算得到取模結果,位運算的速度高於取模運算。

 

有一個很重要的問題,為什么是分割為16384個槽?這個問題可能會被面試官隨口一問

數據分片之后怎么查,怎么寫?

 

讀請求分配給slave節點,寫請求分配給master,數據同步從master到slave節點。

讀寫分離提高並發能力,增加高性能。

如何做到水平擴展?

 

master節點可以做擴充,數據遷移redis內部自動完成。

當你新增一個master節點,需要做數據遷移,redis服務不需要下線。

舉個栗子:上面的有三個master節點,意味着redis的槽被分為三個段,假設三段分別是0~7000,7001~12000、12001~16383。

現在因為業務需要新增了一個master節點,四個節點共同占有16384個槽。

槽需要重新分配,數據也需要重新遷移,但是服務不需要下線。

redis集群的重新分片由redis內部的管理軟件redis-trib負責執行。redis提供了進行重新分片的所有命令,redis-trib通過向節點發送命令來進行重新分片。

如何做故障轉移?

 

假如途中紅色的節點故障了,此時master3下面的從節點會通過 選舉 產生一個主節點。替換原來的故障節點。

此過程和哨兵模式的故障轉移是一樣的。

總結
每種模式都有各自的優缺點,在實際使用場景中要根據業務特點去選擇合適的模式。

redis是一個非常常用的中間件,作為一個使用者來說,學習成本一點不高。

如果作為一個很好的中間件去研究的話,還是有很多值得學習和借鑒的地方。比如redis的各種數據結構(動態字符串、跳躍表、集合、字典等)、高效的內存分配(jemalloc)、高效的IO模型等等。

每個點都可以深入研究,在后期設計高並發、高可用系統的時候融入進去。
參考:Redis四種運行模式

參考:Redis的四種模式,單機、主從、哨兵、集群


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM