從零單排學Redis【鉑金二】

前言

只有光頭才能變強

好的,今天咱們要上【鉑金二】了,若是尚未上鉑金的,趕忙先去蹭蹭經驗再回來(否則不帶你上分了):git

在上篇中拋出了一個問題:github

拋個問題:若是從服務器掛了,不要緊,咱們通常會有多個從服務器,其餘的請求能夠交由沒有掛的從服務器繼續處理。若是主服務器掛了,怎麼辦?由於咱們的寫請求由主服務器處理,只有一臺主服務器,那就沒法處理寫請求了?

Redis提供了哨兵(Sentinal)機制供咱們解決上面的狀況。若是主服務器掛了,咱們能夠將從服務器升級爲主服務器,等到舊的主服務器(掛掉的那個)重連上來,會將它(掛掉的主服務器)變成從服務器。數據庫

  • 這個過程叫作主備切換(故障轉移)

在正常的狀況下,主從加哨兵(Sentinal)機制是這樣子的:服務器

正常狀況下

主服務器掛了,主從複製操做就停止了,而且哨兵系統是能夠察覺出主服務掛了。:網絡

Sentinel能夠察覺主服務掉線,複製操做停止。

Redis提供哨兵機制能夠將選舉一臺從服務器變成主服務器架構

選舉一臺從服務器變成主服務器

而後舊的主服務器若是重連了,會變成從服務器:app

舊的主服務器若是重連了,會變成從服務器

這篇文章主要講講Redis的哨兵(Sentinal)機制的一些細節。但願看完對你們有所幫助~異步

1、哨兵(Sentinal)機制

High Availability: Redis Sentinel is the official high availability solution for Redis.

哨兵(Sentinal)機制主要用於實現Redis的高可用性,主要的功能以下:ide

  • Monitoring. Sentinel constantly checks if your master and slave instances are working as expected.學習

    • Sentinel不停地監控Redis主從服務器是否正常工做
  • Notification. Sentinel can notify the system administrator, another computer programs, via an API, that something is wrong with one of the monitored Redis instances.

    • 若是某個Redis實例有故障,那麼哨兵負責發送消息通知管理員
  • Automatic failover. If a master is not working as expected, Sentinel can start a failover process where a slave is promoted to master, the other additional slaves are reconfigured to use the new master, and the applications using the Redis server informed about the new address to use when connecting.

    • 若是主服務器掛掉了,會自動將從服務器提高爲主服務器(包括配置都會修改)。
  • Configuration provider. Sentinel acts as a source of authority for clients service discovery: clients connect to Sentinels in order to ask for the address of the current Redis master responsible for a given service. If a failover occurs, Sentinels will report the new address.

    • Sentinel能夠做爲配置中心,可以提供當前主服務器的信息。

下面來具體講講Sentinel是如何將從服務器提高爲主服務器的。

tips:Sentinel可讓咱們的Redis實現高可用,Sentinel做爲這麼一個組件,自身也必然是高可用的( 不多是單點的)

1.1啓動和初始化Sentinel

首先咱們要知道的是:Sentinel本質上只是一個運行在特殊模式下的Redis服務器。由於Sentinel作的事情和Redis服務器是不同的,因此它們的初始化是有所區別的(好比,Sentinel在初始化的時候並不會載入AOF/RDB文件,由於Sentinel根本就不用數據庫)。

而後,在啓動的時候會將普通Redis服務器的代碼替換成Sentinel專用代碼。(因此Sentinel雖然做爲Redis服務器,可是它不能執行SET、DBSIZE等等命令,由於命令表的代碼被替換了)

接着,初始化Sentinel的狀態,並根據給定的配置文件初始化Sentinel監視的主服務器列表

初始化

最後,Sentinel會建立兩個連向主服務器的網絡鏈接

  • 命令鏈接(發送和接收命令)
  • 訂閱鏈接(訂閱主服務器的_sentinel_:hello頻道)

建立網絡鏈接

1.2獲取和更新信息

Sentinel經過主服務器發送INFO命令來得到主服務器屬下全部從服務器的地址信息,併爲這些從服務器建立相應的實例結構。

更新實例結構

當發現有新的從服務器出現時,除了建立對應的從服務器實例結構,Sentinel還會建立命令鏈接和訂閱鏈接。

建立鏈接

在Sentinel運行的過程當中,經過命令鏈接會以每兩秒一次的頻率向監視的主從服務器_sentinel_:hello頻道發送命令(主要發送Sentinel自己的信息,監聽主從服務器的信息),並經過訂閱鏈接接收_sentinel_:hello頻道的信息。

  • 這樣一來一回,咱們就能夠更新每一個Sentinel實例結構的信息

1.3判斷主服務器是否下線了

判斷主服務器是否下線有兩種狀況:

  • 主觀下線

    • Sentinel會以每秒一次的頻率向與它建立命令鏈接的實例(包括主從服務器和其餘的Sentinel)發送PING命令,經過PING命令返回的信息判斷實例是否在線
    • 若是一個主服務器down-after-milliseconds毫秒內連續向Sentinel發送無效回覆,那麼當前Sentinel就會主觀認爲該主服務器已經下線了。
  • 客觀下線

    • 當Sentinel將一個主服務器判斷爲主觀下線之後,爲了確認該主服務器是否真的下線,它會向一樣監視該主服務器的Sentinel詢問,看它們是否也認爲該主服務器是否下線。
    • 若是足夠多的Sentinel認爲該主服務器是下線的,那麼就斷定該主服務爲客觀下線,並對主服務器執行故障轉移操做。
在多少毫秒內無效回覆才認定主服務器是主觀下線的,以及有多少個Sentinel認爲主服務器是下線才認定爲客觀下線。這都是 能夠配置

1.4選舉領頭Sentinel和故障轉移

當一個主服務器認爲爲客觀下線之後,監視這個下線的主服務器的各類Sentinel會進行協商,選舉出一個領頭的Sentinel,領頭的Sentinel會對下線的主服務器執行故障轉移操做。

選舉領頭Sentinel的規則也比較多,總的來講就是 先到先得(哪一個快,就選哪一個)

選舉出領頭的Sentinel以後,領頭的Sentinel會對已下線的主服務器執行故障轉移操做,包括三個步驟:

  • 在已下線主服務器屬下的從服務器中,挑選一個轉換爲主服務器
  • 讓已下線主服務器屬下的全部從服務器改成複製新的主服務器
  • 已下線的主服務器從新鏈接時,讓他成爲新的主服務器的從服務器
  • (這三步實際上就是文章開頭的圖片)

挑選某一個從服務器做爲主服務器也是有策略的,大概以下:

  • (1)跟master斷開鏈接的時長
  • (2)slave優先級
  • (3)複製offset
  • (4)run id

最後

這篇文章主要講解了Sentinel的做用和工做的基本過程(我以爲已經基本OK了),其中也涉及到了不少的細節,這裏我就沒有一一整理出來了。想要深刻學習的同窗最好本身看看書或者文檔~~

tips:目前爲止的主從+哨兵架構能夠說Redis是高可用的,但要清楚的是:Redis仍是會 丟失數據

丟失數據有兩種狀況:

  • 異步複製致使的數據丟失

    • 有部分數據還沒複製到從服務器,主服務器就宕機了,此時這些部分數據就丟失了
  • 腦裂致使的數據丟失

    • 有時候主服務器脫離了正常網絡,跟其餘從服務器不能鏈接。此時哨兵可能就會認爲主服務器下線了(而後開啓選舉,將某個從服務器切換成了主服務器),可是實際上主服務器還運行着。這個時候,集羣裏就會有兩個服務器(也就是所謂的腦裂)。
    • 雖然某個從服務器被切換成了主服務器,可是可能客戶端還沒來得及切換到新的主服務器,客戶端還繼續寫向舊主服務器寫數據。舊的服務器從新鏈接時,會做爲從服務器複製新的主服務器(這意味着舊數據丟失)。

能夠經過如下兩個配置儘可能減小數據丟失的可能:

min-slaves-to-write 1
min-slaves-max-lag 10

從零單排學Redis【鉑金三】,敬請期待~

參考資料:

  • 《Redis設計與實現》
  • 《Redis實戰》

若是你以爲我寫得還不錯,瞭解一下:

帥的人都關注了

相關文章
相關標籤/搜索