這篇文章為大家帶來了關於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 :哨兵節點之間可以透過此指令詢問主節點是否下線,從而對是否客觀下線做出判斷
強制對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重新上線後,它會成為新的主節點的從節點。
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中文網其他相關文章!

Redis是现在最热门的key-value数据库,Redis的最大特点是key-value存储所带来的简单和高性能;相较于MongoDB和Redis,晚一年发布的ES可能知名度要低一些,ES的特点是搜索,ES是围绕搜索设计的。

本篇文章给大家带来了关于redis的相关知识,其中主要介绍了关于redis的一些优势和特点,Redis 是一个开源的使用ANSI C语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式存储数据库,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于redis的相关知识,其中主要介绍了Redis Cluster集群收缩主从节点的相关问题,包括了Cluster集群收缩概念、将6390主节点从集群中收缩、验证数据迁移过程是否导致数据异常等,希望对大家有帮助。

本篇文章给大家带来了关于redis的相关知识,其中主要介绍了Redis实现排行榜及相同积分按时间排序,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,希望对大家有帮助。

本篇文章给大家带来了关于redis的相关知识,其中主要介绍了关于原子操作中命令原子性的相关问题,包括了处理并发的方案、编程模型、多IO线程以及单命令的相关内容,下面一起看一下,希望对大家有帮助。

本篇文章给大家带来了关于redis的相关知识,其中主要介绍了bitmap问题,Redis 为我们提供了位图这一数据结构,位图数据结构其实并不是一个全新的玩意,我们可以简单的认为就是个数组,只是里面的内容只能为0或1而已,希望对大家有帮助。

本篇文章给大家带来了关于redis的相关知识,其中主要介绍了Redis实现排行榜及相同积分按时间排序,本文通过实例代码给大家介绍的非常详细,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于redis的相关知识,其中主要介绍了关于实现秒杀的相关内容,包括了秒杀逻辑、存在的链接超时、超卖和库存遗留的问题,下面一起来看一下,希望对大家有帮助。


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SublimeText3 Linux新版
SublimeText3 Linux最新版

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

SublimeText3漢化版
中文版,非常好用

記事本++7.3.1
好用且免費的程式碼編輯器

Dreamweaver Mac版
視覺化網頁開發工具