搜尋
首頁資料庫RedisRedis進階學習高可用之哨兵(總結分享)

這篇文章為大家帶來了關於Redis中高可用哨兵的相關知識,其中包括了作用架構、部署以及配置的相關問題,希望對大家有幫助。

Redis進階學習高可用之哨兵(總結分享)

推薦學習:Redis影片教學

#一、作用與架構

1.  作用

在介紹哨兵之前,先從宏觀角度回顧Redis實現高可用相關的技術。它們包括:持久化、複製、哨兵和集群,其主要作用和解決的問題是:

  • 持久化:持久化是最簡單的高可用方法(有時甚至不被歸為高可用的手段),主要作用是資料備份,即將資料儲存在硬碟,保證資料不會因行程退出而遺失。
  • 複製:複製是高可用Redis的基礎,哨兵和叢集都是在複製基礎上實現高可用的。複製主要實現了資料的多機備份,以及對於讀取操作的負載平衡和簡單的故障復原。缺陷:故障恢復無法自動化;寫入操作無法負載平衡;儲存能力受到單機的限制。
  • 哨兵:在複製的基礎上,哨兵實現了自動化的故障復原。缺陷:寫入操作無法負載平衡;儲存能力受到單機的限制。
  • 叢集:透過集群,Redis解決了寫入操作無法負載平衡,以及儲存能力受到單機限制的問題,實現了較為完善的高可用方案。

下面說回哨兵。

Redis Sentinel,即Redis哨兵,在Redis 2.8版本開始引入。 哨兵的核心功能是主節點的自動故障轉移。 以下是Redis官方文件對於哨兵功能的描述:

  • 監控(Monitoring):哨兵會不斷檢查主節點和從節點是否運作正常。
  • 自動故障轉移(Automatic failover):當主節點無法正常運作時,哨兵會開始自動故障轉移操作,它會將失效主節點的其中一個從節點升級為新的主節點,並讓其他從節點改為複製新的主節點。
  • 設定提供者(Configuration provider):客戶端在初始化時,透過連接哨兵來取得目前Redis服務的主節點位址。
  • 通知(Notification):哨兵可以將故障轉移的結果傳送給客戶端。

其中,監控和自動故障轉移功能,使得哨兵可以及時發現主節點故障並完成轉移;而配置提供者和通知功能,則需要在與客戶端的交互中才能體現。

這裡對「客戶端」一詞在文章中的用法做一個說明:在前面的文章中,只要透過API存取redis伺服器,都會稱為客戶端,包括redis-cli、Java客戶端Jedis等;為了方便區分說明,本文中的客戶端並不包括redis-cli,而是比redis-cli更加複雜:redis-cli使用的是redis提供的底層接口,而客戶端則對這些接口、功能進行了封裝,以便充分利用哨兵的配置提供者和通知功能。

2.  架構

典型的哨兵架構圖如下圖:

它由兩個部分組成,哨兵節點和資料節點:

  • 哨兵節點:哨兵系統由一個或多個哨兵節點組成,哨兵節點是特殊的redis節點,不儲存資料。
  • 資料節點:主節點和從節點都是資料節點。

二、部署

這部分將部署一個簡單的哨兵系統,包含1個主節點、2個從節點和3個哨兵節點。方便起見:所有這些節點都部署在一台機器上(區域網路IP:192.168.92.128),使用連接埠號碼區分;節點的配置盡可能簡化。

1.  部署主從節點

哨兵系統中的主從節點,與普通的主從節點配置是一樣的,並不需要做任何額外配置。以下分別是主節點(port=6379)和2個從節點(port=6380/6381)的設定文件,配置都比較簡單,不再詳述。

#redis-6379.conf
port 6379
daemonize yes
logfile "6379.log"
dbfilename "dump-6379.rdb"
#redis-6380.conf
port 6380
daemonize yes
logfile "6380.log"
dbfilename "dump-6380.rdb"
slaveof 192.168.92.128 6379
#redis-6381.conf
port 6381
daemonize yes
logfile "6381.log"
dbfilename "dump-6381.rdb"
slaveof 192.168.92.128 6379
redis-server redis-6379.conf
redis-server redis-6380.conf
redis-server redis-6381.conf

節點啟動後,連接主節點查看主從狀態是否正常。配置完成後,依序啟動主節點和從節點:

2.  部署哨兵節點

哨兵節點本質上是一個特殊的Redis節點。

3個哨兵節點的配置幾乎是完全一樣的,主要差異在於連接埠號的不同(26379/26380/26381),以下以26379節點為例介紹節點的設定與啟動方式;設定部分盡量簡化,更多配置會在後面介紹。

#sentinel-26379.conf
port 26379
daemonize yes
logfile "26379.log"
sentinel monitor mymaster 192.168.92.128 6379 2

哨兵节点的启动有两种方式,二者作用是完全相同的:其中,sentinel monitor mymaster 192.168.92.128 6379 2 配置的含义是:该哨兵节点监控192.168.92.128:6379这个主节点,该主节点的名称是mymaster,最后的2的含义与主节点的故障判定有关:至少需要2个哨兵节点同意,才能判定主节点故障并进行故障转移。

redis-sentinel sentinel-26379.conf
redis-server sentinel-26379.conf --sentinel

3.  总结

按照上述方式配置和启动之后,整个哨兵系统就启动完毕了。可以通过redis-cli连接哨兵节点进行验证

哨兵系统的搭建过程,有几点需要注意:

(1)哨兵系统中的主从节点,与普通的主从节点并没有什么区别,故障发现和转移是由哨兵来控制和完成的。

(2)哨兵节点本质上是redis节点。

(3)每个哨兵节点,只需要配置监控主节点,便可以自动发现其他的哨兵节点和从节点。

(4)在哨兵节点启动和故障转移阶段,各个节点的配置文件会被重写(config rewrite)。

三、客户端访问哨兵系统

上一小节演示了哨兵的两大作用:监控和自动故障转移,本小节则结合客户端演示哨兵的另外两个作用:配置提供者和通知。

1.  代码示例

在介绍客户端的原理之前,先以Java客户端Jedis为例,演示一下使用方法:下面代码可以连接我们刚刚搭建的哨兵系统,并进行各种读写操作(代码中只演示如何连接哨兵,异常处理、资源关闭等未考虑)。

public static void testSentinel() throws Exception {
         String masterName = "mymaster";
         Set<String> sentinels = new HashSet<>();
         sentinels.add("192.168.92.128:26379");
         sentinels.add("192.168.92.128:26380");
         sentinels.add("192.168.92.128:26381");
         JedisSentinelPool pool = new JedisSentinelPool(masterName, sentinels); //初始化过程做了很多工作
         Jedis jedis = pool.getResource();
         jedis.set("key1", "value1");
         pool.close();
}

Jedis客户端对哨兵提供了很好的支持。如上述代码所示,我们只需要向Jedis提供哨兵节点集合和masterName,构造JedisSentinelPool对象;然后便可以像使用普通redis连接池一样来使用了:通过pool.getResource()获取连接,执行具体的命令。2.  客户端原理

在整个过程中,我们的代码不需要显式的指定主节点的地址,就可以连接到主节点;代码中对故障转移没有任何体现,就可以在哨兵完成故障转移后自动的切换主节点。之所以可以做到这一点,是因为在JedisSentinelPool的构造器中,进行了相关的工作;主要包括以下两点:

(1)遍历哨兵节点,获取主节点信息:遍历哨兵节点,通过其中一个哨兵节点+masterName获得主节点的信息;该功能是通过调用哨兵节点的sentinel get-master-addr-by-name命令实现,该命令示例如下:

一旦获得主节点信息,停止遍历(因此一般来说遍历到第一个哨兵节点,循环就停止了)。

(2)增加对哨兵的监听:这样当发生故障转移时,客户端便可以收到哨兵的通知,从而完成主节点的切换。具体做法是:利用redis提供的发布订阅功能,为每一个哨兵节点开启一个单独的线程,订阅哨兵节点的+switch-master频道,当收到消息时,重新初始化连接池。

3.  总结

通过客户端原理的介绍,可以加深对哨兵功能的理解:

(1)配置提供者:客户端可以通过哨兵节点+masterName获取主节点信息,在这里哨兵起到的作用就是配置提供者。

需要注意的是,哨兵只是配置提供者,而不是代理。二者的区别在于:如果是配置提供者,客户端在通过哨兵获得主节点信息后,会直接建立到主节点的连接,后续的请求(如set/get)会直接发向主节点;如果是代理,客户端的每一次请求都会发向哨兵,哨兵再通过主节点处理请求。

举一个例子可以很好的理解哨兵的作用是配置提供者,而不是代理。在前面部署的哨兵系统中,将哨兵节点的配置文件进行如下修改:

sentinel monitor mymaster 192.168.92.128 6379 2
改为
sentinel monitor mymaster 127.0.0.1 6379 2

(2)通知:哨兵节点在故障转移完成后,会将新的主节点信息发送给客户端,以便客户端及时切换主节点。然后,将前述客户端代码在局域网的另外一台机器上运行,会发现客户端无法连接主节点;这是因为哨兵作为配置提供者,客户端通过它查询到主节点的地址为127.0.0.1:6379,客户端会向127.0.0.1:6379建立redis连接,自然无法连接。如果哨兵是代理,这个问题就不会出现了。

四、基本原理

前面介绍了哨兵部署、使用的基本方法,本部分介绍哨兵实现的基本原理。

1.  哨兵節點支援的命令

哨兵節點作為運行在特殊模式下的redis節點,其支援的命令與普通的redis節點不同。在維運中,我們可以透過這些指令查詢或修改哨兵系統;不過更重要的是,哨兵系統要實現故障發現、故障轉移等各種功能,離不開哨兵節點之間的通信,而通信的很大一部分是透過哨兵節點支援的命令來實現的。以下介紹哨兵節點支援的主要命令。

(1)基礎查詢:透過這些指令,可以查詢哨兵系統的拓樸結構、節點資訊、設定資訊等。

  • info sentinel:獲取監控的所有主節點的基本資訊
  • sentinel masters:取得監控的所有主節點的詳細資訊
  • ##sentinel master mymaster:取得監控的主節點mymaster的詳細資訊
  • sentinel slaves mymaster:取得監控的主節點mymaster的從節點的詳細資料
  • sentinel sentinels mymaster:取得監控的主節點mymaster的哨兵節點的詳細資訊
  • sentinel get-master-addr-by-name mymaster:取得監控的主節點mymaster的地址信息,前文已有介紹
  • sentinel is-master-down-by-addr :哨兵節點之間可以透過此指令詢問主節點是否下線,從而對是否客觀下線做出判斷
(2)增加/移除對主節點的監控

sentinel monitor mymaster2 192.168.92.128 16379 2:與部署哨兵節點時設定檔中的sentinel monitor功能完全一樣,不再詳述

sentinel remove mymaster2:取消目前哨兵對主節點mymaster2的監控節點

(3)強制故障轉移

sentinel failover mymaster:此指令可以

強制對mymaster執行故障轉移,即便目前的主節點運作良好;例如,如果目前主節點所在機器即將報廢,便可以提前透過failover指令進行故障轉移。

2.  基本原理

關於哨兵的原理,關鍵在於了解以下概念。

(1)定時任務:每個哨兵節點維護了3個定時任務。定時任務的功能分別如下:透過向主從節點發送info指令取得最新的主從結構;透過發布訂閱功能取得其他哨兵節點的資訊;透過向其他節點發送ping指令進行心跳偵測,判斷是否下線。

(2)主觀下線:在心跳偵測的定時任務中,如果其他節點超過一定時間沒有回复,哨兵節點就會將其進行主觀下線。顧名思義,主觀下線的意思是一個哨兵節點「主觀地」判斷下線;與主觀下線相對應的是客觀下線。

(3)客觀下線:哨兵節點在對主節點進行主觀下線後,會透過sentinel is-master-down-by-addr指令詢問其他哨兵節點該主節點的狀態;如果判斷主節點下線的哨兵數量達到一定數值,則對該主節點進行客觀下線。

需要特別注意的是,客觀下線是主節點才有的概念;如果從節點和哨兵節點發生故障,被哨兵主觀下線後,不會再有後續的客觀下線和故障轉移操作。

(4)選舉領導者哨兵節點:當主節點被判斷客觀下線以後,各個哨兵節點會進行協商,選出一個領導者哨兵節點,並由該領導者節點對其進行故障轉移操作。

監視該主節點的所有哨兵都有可能被選為領導者,選舉使用的演算法是Raft演算法;Raft演算法的基本想法是先到先得:即在一輪選舉中,哨兵A向B發送成為領導者的申請,如果B沒有同意過其他哨兵,則會同意A成為領導者。選舉的具體過程這裡不做詳細描述,一般來說,哨兵選擇的過程很快,誰先完成客觀下線,一般就能成為領導者。

(5)故障轉移:選出的領導者哨兵,開始進行故障轉移操作,該操作大體可分為3個步驟:

    在從節點中選擇新的主節點:選擇的原則是,先過濾掉不健康的從節點;然後選擇優先順序最高的從節點(由slave-priority指定);如果優先權無法區分,則選擇複製偏移量最大的從節點;如果仍無法區分,則選擇runid最小的從節點。
  • 更新主從狀態:透過slaveof no one指令,讓選出來的從節點成為主節點;並透過slaveof指令讓其他節點成為其從節點。
  • 將已經下線的主節點(即6379)設定為新的主節點的從節點,當6379重新上線後,它會成為新的主節點的從節點。
五、設定與實作建議

1.  設定

以下介紹幾個與哨兵相關的設定。

(1) sentinel monitor {masterName} {masterIp} {masterPort} {quorum}

sentinel monitor是哨兵最核心的配置,在前文講述部署哨兵節點時已說明,其中:masterName指定了主節點名稱,masterIp和masterPort指定了主節點位址,quorum是判斷主節點客觀下線的哨兵量閾值:當判定主節點下線的哨兵數達到quorum時,對主節點進行客觀下線。建議取值為哨兵數量的一半加1。

(2) sentinel down-after-milliseconds {masterName} {time}

sentinel down-after-milliseconds與主觀下線的判斷有關:哨兵使用ping指令對其他節點進行心跳檢測,如果其他節點超過down-after-milliseconds配置的時間沒有回复,哨兵就會將其進行主觀下線。此配置對主節點、從節點和哨兵節點的主觀下線判定都有效。

down-after-milliseconds的預設值是30000,即30s;可以根據不同的網路環境和應用要求來調整:值越大,對主觀下線的判定會越寬鬆,好處是誤判的可能性很小,壞處是故障發現和故障轉移的時間變長,客戶端等待的時間也會變長。例如,如果應用程式對可用性要求較高,則可以將值適當調小,當故障發生時盡快完成轉移;如果網路環境相對較差,可以適當提高該閾值,避免頻繁誤判。

(3) sentinel parallel-syncs {masterName} {number}

sentinel parallel-syncs與故障轉移之後從節點的複製有關:它規定了每次向新的主節點發起複製操作的從節點個數。例如,假設主節點切換完成之後,有3個從節點要向新的主節點發起複製;如果parallel-syncs=1,則從節點會一個一個開始複製;如果parallel-syncs=3,則3個從節點會一起開始複製。

parallel-syncs取值越大,從節點完成複製的時間越快,但是對主節點的網路負載、硬碟負載造成的壓力也越大;應根據實際情況設定。例如,如果主節點的負載較低,而從節點對服務可用的要求較高,可以適量增加parallel-syncs值。 parallel-syncs的預設值是1。

(4) sentinel failover-timeout {masterName} {time}

sentinel failover-timeout與故障轉移逾時的判斷有關,但是該參數不是用來判斷整個故障轉移階段的逾時,而是其幾個子階段的超時,例如如果主節點晉升從節點時間超過timeout,或從節點向新的主節點發起複製操作的時間(不包括複製資料的時間)超過timeout,都會導致故障轉移逾時失敗。

failover-timeout的預設值為180000,即180s;如果逾時,則下一次該值會變成原來的2倍。

(5)除上述幾個參數外,還有一些其他參數,如安全驗證相關的參數,這裡不做介紹。

2.  實務建議

(1)哨兵節點的數量應不止一個,一方面增加哨兵節點的冗餘,避免哨兵本身成為高可用的瓶頸;另一方面減少對下線的誤判。此外,這些不同的哨兵節點應部署在不同的實體機上。

(2)哨兵節點的數量應該是奇數,以便於哨兵透過投票做出「決策」:領導者選舉的決策、客觀下線的決策等。

(3)各個哨兵節點的配置應一致,包括硬體、參數等;此外,所有節點都應該使用ntp或類似服務,保證時間準確、一致。

(4)哨兵的配置提供者和通知客戶端功能,需要客戶端的支持才能實現,如前文所說的Jedis;如果開發者使用的庫未提供相應支持,則可能需要開發者自己實現。

(5)當哨兵系統中的節點在docker(或其他可能進行連接埠對映的軟體)中部署時,應特別注意連接埠對映可能會導致哨兵系統無法正常運作,因為哨兵的工作是基於與其他節點的通信,而docker的連接埠對映可能導致哨兵無法連接到其他節點。例如,哨兵之間互相發現,依賴它們對外宣稱的IP和port,如果某個哨兵A部署在做了端口映射的docker中,那麼其他哨兵使用A宣稱的port無法連接到A。

六、總結

本文首先介紹了哨兵的作用:監控、故障轉移、設定提供者和通知;然後講述了哨兵系統的部署方法,以及透過客戶端存取哨兵系統的方法;再然後簡要說明了哨兵實現的基本原理;最後給出了關於哨兵實踐的一些建議。

在主從複製的基礎上,哨兵引入了主節點的自動故障轉移,進一步提高了Redis的高可用性;但是哨兵的缺陷同樣很明顯:哨兵無法對從節點進行自動故障轉移,在讀寫分離場景下,從節點故障會導致讀服務不可用,需要我們對從節點做額外的監控、切換操作。

此外,哨兵仍然沒有解決寫入操作無法負載均衡、及存儲能力受到單機限制的問題;這些問題的解決需要使用集群,我將在後面的文章中介紹,歡迎關注。

推薦學習:《Redis影片教學》、《2022最新redis面試題大全及答案

以上是Redis進階學習高可用之哨兵(總結分享)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:CSDN。如有侵權,請聯絡admin@php.cn刪除
REDIS的角色:探索數據存儲和管理功能REDIS的角色:探索數據存儲和管理功能Apr 22, 2025 am 12:10 AM

Redis在數據存儲和管理中扮演著關鍵角色,通過其多種數據結構和持久化機製成為現代應用的核心。 1)Redis支持字符串、列表、集合、有序集合和哈希表等數據結構,適用於緩存和復雜業務邏輯。 2)通過RDB和AOF兩種持久化方式,Redis確保數據的可靠存儲和快速恢復。

REDIS:了解NOSQL概念REDIS:了解NOSQL概念Apr 21, 2025 am 12:04 AM

Redis是一種NoSQL數據庫,適用於大規模數據的高效存儲和訪問。 1.Redis是開源的內存數據結構存儲系統,支持多種數據結構。 2.它提供極快的讀寫速度,適合緩存、會話管理等。 3.Redis支持持久化,通過RDB和AOF方式確保數據安全。 4.使用示例包括基本的鍵值對操作和高級的集合去重功能。 5.常見錯誤包括連接問題、數據類型不匹配和內存溢出,需注意調試。 6.性能優化建議包括選擇合適的數據結構和設置內存淘汰策略。

REDIS:現實世界的用例和示例REDIS:現實世界的用例和示例Apr 20, 2025 am 12:06 AM

Redis在現實世界中的應用包括:1.作為緩存系統加速數據庫查詢,2.存儲Web應用的會話數據,3.實現實時排行榜,4.作為消息隊列簡化消息傳遞。 Redis的多功能性和高性能使其在這些場景中大放異彩。

REDIS:探索其功能和功能REDIS:探索其功能和功能Apr 19, 2025 am 12:04 AM

Redis脫穎而出是因為其高速、多功能性和豐富的數據結構。 1)Redis支持字符串、列表、集合、散列和有序集合等數據結構。 2)它通過內存存儲數據,支持RDB和AOF持久化。 3)從Redis6.0開始引入多線程處理I/O操作,提升了高並發場景下的性能。

Redis是SQL還是NOSQL數據庫?答案解釋了Redis是SQL還是NOSQL數據庫?答案解釋了Apr 18, 2025 am 12:11 AM

RedisisclassifiedasaNoSQLdatabasebecauseitusesakey-valuedatamodelinsteadofthetraditionalrelationaldatabasemodel.Itoffersspeedandflexibility,makingitidealforreal-timeapplicationsandcaching,butitmaynotbesuitableforscenariosrequiringstrictdataintegrityo

REDIS:提高應用程序性能和可擴展性REDIS:提高應用程序性能和可擴展性Apr 17, 2025 am 12:16 AM

Redis通過緩存數據、實現分佈式鎖和數據持久化來提升應用性能和可擴展性。 1)緩存數據:使用Redis緩存頻繁訪問的數據,提高數據訪問速度。 2)分佈式鎖:利用Redis實現分佈式鎖,確保在分佈式環境中操作的安全性。 3)數據持久化:通過RDB和AOF機制保證數據安全性,防止數據丟失。

REDIS:探索其數據模型和結構REDIS:探索其數據模型和結構Apr 16, 2025 am 12:09 AM

Redis的數據模型和結構包括五種主要類型:1.字符串(String):用於存儲文本或二進制數據,支持原子操作。 2.列表(List):有序元素集合,適合隊列和堆棧。 3.集合(Set):無序唯一元素集合,支持集合運算。 4.有序集合(SortedSet):帶分數的唯一元素集合,適用於排行榜。 5.哈希表(Hash):鍵值對集合,適合存儲對象。

REDIS:對其數據庫方法進行分類REDIS:對其數據庫方法進行分類Apr 15, 2025 am 12:06 AM

Redis的數據庫方法包括內存數據庫和鍵值存儲。 1)Redis將數據存儲在內存中,讀寫速度快。 2)它使用鍵值對存儲數據,支持複雜數據結構,如列表、集合、哈希表和有序集合,適用於緩存和NoSQL數據庫。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。