首頁  >  文章  >  資料庫  >  Redis高可用的兩種實作方案是什麼

Redis高可用的兩種實作方案是什麼

王林
王林轉載
2023-05-27 19:42:121123瀏覽

Redis中為了實現高可用(High Availability,簡稱HA),採用如下兩個方式:

  • ##主從複製資料。

  • 採用哨兵監控資料節點的運作情況,一旦主節點出現問題由從節點頂繼續進行服務。

主從複製

Redis中主從節點複製資料有全量複製和部分複製之分。

舊版全量複製功能的實現

全量複製使用snyc指令來實現,其流程是:

  • 從伺服器向主伺服器發送sync命令。

  • 主伺服器在收到sync指令之後,呼叫bgsave指令產生***的rdb文件,將這個檔案同步給從伺服器,這樣從伺服器載入這個rdb檔案之後,狀態就會和主伺服器執行bgsave指令時候的一致。

  • 主伺服器將保存在命令緩衝區中的寫入命令同步給從伺服器,從伺服器執行這些命令,這樣從伺服器的狀態就跟主伺服器目前狀態一致了。

舊版全量複製功能,其***的問題是從伺服器斷線重連時,即便在從伺服器上已經有一部分資料了,也需要進行全量複製,這樣做的效率很低,於是新版的Redis在這部分做了改進。

新版全量複製功能的實作

Redis的最新版本採用psync指令取代了sync指令,psync指令不僅可以實現完全同步,還可以實作部分同步。

複製偏移

執行複製的雙方,主從伺服器,分別會維護一個複製偏移量:

  • 主伺服器每次向從伺服器同步了N位元組資料之後,將修改自己的複製偏移量N。

  • 從伺服器每次從主伺服器同步了N位元組資料之後,將修改自己的複製偏移 N。

複製積壓緩衝區

主伺服器內部維護了一個固定長度的先進先出隊列做為複製積壓緩衝區,其默認大小為1MB。

在主伺服器進行指令傳播時,不僅會將寫入指令同步到從伺服器,還會將寫入指令寫入複製積壓緩衝區。

伺服器運行ID

每個Redis伺服器,都有其運行ID,運行ID由伺服器在啟動時自動生成,主伺服器會將自己的運行ID傳送給從伺服器,而從伺服器會將主伺服器的運行ID保存起來。

從伺服器Redis斷線重連之後進行同步時,就是根據執行ID來判斷同步的進度:

  • 如果從伺服器上面儲存的主伺服器執行ID與目前主伺服器運行ID一致,則認為這次斷線重連連接的是先前複製的主伺服器,主伺服器可以繼續嘗試部分同步操作。

  • 否則,如果前後兩次主伺服器執行ID不相同,則認為是完成全同步流程。

psync指令流程

有了前面的準備,下面開始分析psync指令的流程:

  • 如果從伺服器之前沒有複製過任何主伺服器,或者之前執行過slaveof no one命令,那麼從伺服器就會向主伺服器發送psync ? -1命令,請求主伺服器進行資料的全量同步。

  • 否則,如果前面從伺服器已經同步過部分數據,那麼從伺服器向主伺服器發送psync 命令,其中runid是上一次主伺服器的運行id,offset是目前從伺服器的複製偏移量。

前面兩種情況主伺服器收到psync指令之後,會出現以下三種可能:

  • 主伺服器回傳fullresync 回复,表示主伺服器要求與從伺服器進行完整的資料全量同步操作。目前主伺服器的運行id為runid,複製偏移量為offset。

  • 如果主伺服器回應 continue,那麼表示主伺服器與從伺服器進行部分資料同步操作,將從伺服器缺少的資料同步過來即可。

  • 如果主伺服器回應-err,那麼表示主伺服器版本低於2.8,識別不了psync命令,此時從伺服器將向主伺服器發送sync命令,執行完整的全量數據同步。

哨兵機制概述

Redis使用哨兵機制來實作高可用(HA),其大概運作原理是:

  • Redis使用一組哨兵(sentinel)節點來監控主從redis服務的可用性。

  • 一旦發現Redis主節點失效,就會選出一個哨兵節點作為***(leader)。

  • 哨兵***再從剩餘的從Redis節點中選出一個Redis節點作為新的主Redis節點對外服務。

以上將Redis節點分成兩類:

  • 哨兵節點(sentinel):負責監控節點的運作。

  • 資料節點:即正常服務客戶端請求的Redis節點,有主從之分。

以上是大體的流程,這個流程需要解決以下幾個問題:

  • 如何監控Redis資料節點?

  • 如何確定一個Redis資料節點失效?

  • 如何選擇一個哨兵***節點?

  • 哨兵節點選擇新的主Redis節點的依據是什麼?

以下來逐一回答這些問題。

三個監控任務

哨兵節點透過三個定時監控任務監控Redis資料節點的服務可用性。

info指令

每隔10秒,每個哨兵節點都會向主、從Redis資料節點發送info指令,取得新的拓樸資訊。

Redis拓撲結構資訊包括了:

  • 本節點角色:主或從。

  • 主從節點的位址、連接埠資訊。

這樣,哨兵節點就能從info指令中自動獲取到從節點信息,因此那些後續才加入的從節點資訊不需要明確配置就能自動感知。

向__sentinel__:hello頻道同步訊息

每隔2秒,每個哨兵節點將會向Redis資料節點的__sentinel__:hello頻道同步自身得到的主節點資訊以及目前哨兵節點的訊息,由於其他哨兵節點也訂閱了這個頻道,因此實際上這個操作可以交換哨兵節點之間關於主節點以及哨兵節點的資訊。

這一操作實際上完成了兩件事: * 發現新的哨兵節點:如果有新的哨兵節點加入,此時保存下來這個新哨兵節點的信息,後續與該哨兵節點建立連接。用下列方式重寫: * 交換主節點的狀態訊息,以便後續客觀地判斷主節點是否已下線。

向資料節點做心跳探測

每隔1秒,每個哨兵節點都會向主、從資料節點以及其他sentinel節點發送ping指令做心跳偵測,這個心跳偵測是後續主觀判斷資料節點下線的依據。

主觀下線和客觀下線

主觀下線

##上面三個監控任務中的第三個探測心跳任務,如果在配置的down-after-milliseconds之後沒有收到有效回复,那麼就認為該數據節點「主觀下線(sdown)」。

為什麼稱為「主觀下線」?因為在一個分散式系統中,有多個機器在一起聯動工作,網路可能出現各種狀況,僅憑一個節點的判斷還不足以認為一個資料節點下線了,這就需要後面的「客觀下線」。

客觀下線

當一個哨兵節點認為主節點主觀下線時,該哨兵節點需要通過」sentinel is-master-down-by addr」指令向其他哨兵節點諮詢該主節點是否下線了,如果有超過半數的哨兵節點都回答了下線,此時認為主節點「客觀下線」。

選舉哨兵***

當主節點客觀下線時,需要選出一個哨兵節點做為哨兵***,以完成後續選出新的主節點的工作。

這個選舉的大致想法是:

  • 每個哨兵節點透過向其他哨兵節點發送」sentinel is-master-down-by addr」指令來申請成為哨兵***。

  • 而每個哨兵節點在收到一個」sentinel is-master-down-by addr」指令時,只允許給***個節點投票,其他節點的該指令都會被拒絕。

  • 如果一個哨兵節點收到了半數以上的同意票,則成為哨兵***。

  • 如果前面三步驟在一定時間內都沒有選出一個哨兵***,將會重新開始下一次選舉。

可以看到,這個選舉***的流程很像raft中選舉leader的流程。

選出新的主節點

在剩下的Redis從節點中,依照下列順序來選擇新的主節點:

  • #過濾掉「不健康」的資料節點:例如主觀下線、斷線的從節點、五秒內沒有回復過哨兵節點ping指令的節點、與主節點失聯的從節點。

  • 如果存在slave-priority(從節點優先權)***的從節點,則傳回該節點;否則繼續執行後續流程。

  • 選擇複製偏移量***的從節點,這表示這個從節點上面的資料最完整,如果存在則傳回不存在則繼續後面的流程。

  • 到了這裡,所有剩餘從節點的狀態都是一樣的,選擇runid最小的從節點。

提升新的主節點

選擇了新的主節點之後,還需要***的流程讓該節點成為新的主節點:

  • 哨兵***往上一步選出的從節點發出「slaveof no one」指令,讓該節點成為主節點。

  • 哨兵***向剩餘的從節點發送命令,讓它們成為新主節點的從節點。

  • 哨兵節點集合會將原來的主節點更新為從節點,當其復原之後命令它去複製新的主節點的資料。

#

以上是Redis高可用的兩種實作方案是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除