天天看點

redis 哨兵_深入學習Redis :哨兵前言一、作用和架構二、部署三、用戶端通路哨兵系統

前言

在 深入學習Redis(3):主從複制 中曾提到,Redis主從複制的作用有資料熱備、負載均衡、故障恢複等;但主從複制存在的一個問題是故障恢複無法自動化。本文将要介紹的哨兵,它基于Redis主從複制,主要作用便是解決主節點故障恢複的自動化問題,進一步提高系統的高可用性。

文章主要内容如下:首先介紹哨兵的作用和架構;然後講述哨兵系統的部署方法,以及通過用戶端通路哨兵系統的方法;然後簡要說明哨兵實作的基本原理;最後給出關于哨兵實踐的一些建議。文章内容基于Redis 3.0版本。

一、作用和架構

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 哨兵_深入學習Redis :哨兵前言一、作用和架構二、部署三、用戶端通路哨兵系統

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

  • 哨兵節點:哨兵系統由一個或多個哨兵節點組成,哨兵節點是特殊的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

節點啟動後,連接配接主節點檢視主從狀态是否正常,如下圖所示:

redis 哨兵_深入學習Redis :哨兵前言一、作用和架構二、部署三、用戶端通路哨兵系統

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

按照上述方式配置和啟動之後,整個哨兵系統就啟動完畢了。可以通過redis-cli連接配接哨兵節點進行驗證,如下圖所示:可以看出26379哨兵節點已經在監控mymaster主節點(即192.168.92.128:6379),并發現了其2個從節點和另外2個哨兵節點。

redis 哨兵_深入學習Redis :哨兵前言一、作用和架構二、部署三、用戶端通路哨兵系統

此時如果檢視哨兵節點的配置檔案,會發現一些變化,以26379為例:

redis 哨兵_深入學習Redis :哨兵前言一、作用和架構二、部署三、用戶端通路哨兵系統

其中,dir隻是顯式聲明了資料和日志所在的目錄(在哨兵語境下隻有日志);known-slave和known-sentinel顯示哨兵已經發現了從節點和其他哨兵;帶有epoch的參數與配置紀元有關(配置紀元是一個從0開始的計數器,每進行一次上司者哨兵選舉,都會+1;上司者哨兵選舉是故障轉移階段的一個操作,在後文原理部分會介紹)。

3. 示範故障轉移

哨兵的4個作用中,配置提供者和通知需要用戶端的配合,本文将在下一章介紹用戶端通路哨兵系統的方法時詳細介紹。這一小節将示範當主節點發生故障時,哨兵的監控和自動故障轉移功能。

(1)首先,使用kill指令殺掉主節點:

redis 哨兵_深入學習Redis :哨兵前言一、作用和架構二、部署三、用戶端通路哨兵系統

(2)如果此時立即在哨兵節點中使用info Sentinel指令檢視,會發現主節點還沒有切換過來,因為哨兵發現主節點故障并轉移,需要一段時間。

redis 哨兵_深入學習Redis :哨兵前言一、作用和架構二、部署三、用戶端通路哨兵系統

(3)一段時間以後,再次在哨兵節點中執行info Sentinel檢視,發現主節點已經切換成6380節點。

redis 哨兵_深入學習Redis :哨兵前言一、作用和架構二、部署三、用戶端通路哨兵系統

但是同時可以發現,哨兵節點認為新的主節點仍然有2個從節點,這是因為哨兵在将6380切換成主節點的同時,将6379節點置為其從節點;雖然6379從節點已經挂掉,但是由于哨兵并不會對從節點進行客觀下線(其含義将在原理部分介紹),是以認為該從節點一直存在。當6379節點重新啟動後,會自動變成6380節點的從節點。下面驗證一下。

(4)重新開機6379節點:可以看到6379節點成為了6380節點的從節點。

redis 哨兵_深入學習Redis :哨兵前言一、作用和架構二、部署三、用戶端通路哨兵系統

(5)在故障轉移階段,哨兵和主從節點的配置檔案都會被改寫。

對于主從節點,主要是slaveof配置的變化:新的主節點沒有了slaveof配置,其從節點則slaveof新的主節點。

對于哨兵節點,除了主從節點資訊的變化,紀元(epoch)也會變化,下圖中可以看到紀元相關的參數都+1了。

redis 哨兵_深入學習Redis :哨兵前言一、作用和架構二、部署三、用戶端通路哨兵系統

4. 總結

哨兵系統的搭建過程,有幾點需要注意:

(1)哨兵系統中的主從節點,與普通的主從節點并沒有什麼差別,故障發現和轉移是由哨兵來控制和完成的。

(2)哨兵節點本質上是redis節點。

(3)每個哨兵節點,隻需要配置監控主節點,便可以自動發現其他的哨兵節點和從節點。

(4)在哨兵節點啟動和故障轉移階段,各個節點的配置檔案會被重寫(config rewrite)。

(5)本章的例子中,一個哨兵隻監控了一個主節點;實際上,一個哨兵可以監控多個主節點,通過配置多條sentinel monitor即可實作。

三、用戶端通路哨兵系統

上一小節示範了哨兵的兩大作用:監控和自動故障轉移,本小節則結合用戶端示範哨兵的另外兩個作用:配置提供者和通知。

1. 代碼示例

在介紹用戶端的原理之前,先以Java用戶端Jedis為例,示範一下使用方法:下面代碼可以連接配接我們剛剛搭建的哨兵系統,并進行各種讀寫操作(代碼中隻示範如何連接配接哨兵,異常處理、資源關閉等未考慮)。

public static void testSentinel() throws Exception {

String masterName = "mymaster";

Set 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

繼續閱讀