springboot redis 断线重连_Redis高可用方案实现
redis中為了實現(xiàn)高可用(High Availability,簡稱HA),采用了如下兩個方式:
- 主從復制數據。
- 采用哨兵監(jiān)控數據節(jié)點的運行情況,一旦主節(jié)點出現(xiàn)問題由從節(jié)點頂上繼續(xù)進行服務。
主從復制
redis中主從節(jié)點復制數據有全量復制和部分復制之分。
舊版本全量復制功能的實現(xiàn)
全量復制使用snyc命令來實現(xiàn),其流程是:
- 從服務器向主服務器發(fā)送sync命令。
- 主服務器在收到sync命令之后,調用bgsave命令生成最新的rdb文件,將這個文件同步給從服務器,這樣從服務器載入這個rdb文件之后,狀態(tài)就會和主服務器執(zhí)行bgsave命令時候的一致。
- 主服務器將保存在命令緩沖區(qū)中的寫命令同步給從服務器,從服務器執(zhí)行這些命令,這樣從服務器的狀態(tài)就跟主服務器當前狀態(tài)一致了。
舊版本全量復制功能,其最大的問題是從服務器斷線重連時,即便在從服務器上已經有一部分數據了,也需要進行全量復制,這樣做的效率很低,于是新版本的redis在這部分做了改進。
新版本全量復制功能的實現(xiàn)
新版本redis使用psync命令來代替sync命令,該命令既可以實現(xiàn)完整全同步也可以實現(xiàn)部分同步。
復制偏移量
執(zhí)行復制的雙方,主從服務器,分別會維護一個復制偏移量:
- 主服務器每次向從服務器同步了N字節(jié)數據之后,將修改自己的復制偏移量+N。
- 從服務器每次從主服務器同步了N字節(jié)數據之后,將修改自己的復制偏移量+N。
復制積壓緩沖區(qū)
主服務器內部維護了一個固定長度的先進先出隊列做為復制積壓緩沖區(qū),其默認大小為1MB。
在主服務器進行命令傳播時,不僅會將寫命令同步到從服務器,還會將寫命令寫入復制積壓緩沖區(qū)。
服務器運行ID
每個redis服務器,都有其運行ID,運行ID由服務器在啟動時自動生成,主服務器會將自己的運行ID發(fā)送給從服務器,而從服務器會將主服務器的運行ID保存起來。
從服務器redis斷線重連之后進行同步時,就是根據運行ID來判斷同步的進度:
- 如果從服務器上面保存的主服務器運行ID與當前主服務器運行ID一致,則認為這一次斷線重連連接的是之前復制的主服務器,主服務器可以繼續(xù)嘗試部分同步操作。
- 否則,如果前后兩次主服務器運行ID不相同,則認為是完成全同步流程。
psync命令流程
有了前面的準備,下面開始分析psync命令的流程:
- 如果從服務器之前沒有復制過任何主服務器,或者之前執(zhí)行過slaveof no one命令,那么從服務器就會向主服務器發(fā)送psync ? -1命令,請求主服務器進行數據的全量同步。
- 否則,如果前面從服務器已經同步過部分數據,那么從服務器向主服務器發(fā)送psync <runid> <offset>命令,其中runid是上一次主服務器的運行id,offset是當前從服務器的復制偏移量。
前面兩種情況主服務器收到psync命令之后,會出現(xiàn)以下三種可能:
- 主服務器返回+fullresync <runid> <offset>回復,表示主服務器要求與從服務器進行完整的數據全量同步操作。其中,runid是當前主服務器運行id,而offset是當前主服務器的復制偏移量。
- 如果主服務器應答+continue,那么表示主服務器與從服務器進行部分數據同步操作,將從服務器缺失的數據同步過來即可。
- 如果主服務器應答-err,那么表示主服務器版本低于2.8,識別不了psync命令,此時從服務器將向主服務器發(fā)送sync命令,執(zhí)行完整的全量數據同步。
哨兵機制
redis使用哨兵機制來實現(xiàn)高可用(HA),其大概工作原理是:
- redis使用一組哨兵(sentinel)節(jié)點來監(jiān)控主從redis服務的可用性。
- 一旦發(fā)現(xiàn)redis主節(jié)點失效,將選舉出一個哨兵節(jié)點作為領導者(leader)。
- 哨兵領導者再從剩余的從redis節(jié)點中選出一個redis節(jié)點作為新的主redis節(jié)點對外服務。
以上將redis節(jié)點分為兩類:
- 哨兵節(jié)點(sentinel):負責監(jiān)控節(jié)點的運行情況。
- 數據節(jié)點:即正常服務客戶端請求的redis節(jié)點,有主從之分。
以上是大體的流程,這個流程需要解決以下幾個問題:
- 如何對redis數據節(jié)點進行監(jiān)控?
- 如何確定一個redis數據節(jié)點失效?
- 如何選擇出一個哨兵領導者節(jié)點?
- 哨兵節(jié)點選擇新的主redis節(jié)點的依據是什么?
以下來逐個回答這些問題。
三個監(jiān)控任務
哨兵節(jié)點通過三個定時監(jiān)控任務監(jiān)控redis數據節(jié)點的服務可用性。
info命令
每隔10秒,每個哨兵節(jié)點都會向主、從redis數據節(jié)點發(fā)送info命令,獲取新的拓撲結構信息。
redis拓撲結構信息包括了:
- 本節(jié)點角色:主或從。
- 主從節(jié)點的地址、端口信息。
這樣,哨兵節(jié)點就能從info命令中自動獲取到從節(jié)點信息,因此那些后續(xù)才加入的從節(jié)點信息不需要顯式配置就能自動感知。
向__sentinel__:hello頻道同步信息
每隔2秒,每個哨兵節(jié)點將會向redis數據節(jié)點的__sentinel__:hello頻道同步自身得到的主節(jié)點信息以及當前哨兵節(jié)點的信息,由于其他哨兵節(jié)點也訂閱了這個頻道,因此實際上這個操作可以交換哨兵節(jié)點之間關于主節(jié)點以及哨兵節(jié)點的信息。
這一操作實際上完成了兩件事情: * 發(fā)現(xiàn)新的哨兵節(jié)點:如果有新的哨兵節(jié)點加入,此時保存下來這個新哨兵節(jié)點的信息,后續(xù)與該哨兵節(jié)點建立連接。 * 交換主節(jié)點的狀態(tài)信息,作為后續(xù)客觀判斷主節(jié)點下線的依據。
向數據節(jié)點做心跳探測
每隔1秒,每個哨兵節(jié)點向主、從數據節(jié)點以及其他sentinel節(jié)點發(fā)送ping命令做心跳探測,這個心跳探測是后續(xù)主觀判斷數據節(jié)點下線的依據。
主觀下線和客觀下線
主觀下線
上面三個監(jiān)控任務中的第三個探測心跳任務,如果在配置的down-after-milliseconds之后沒有收到有效回復,那么就認為該數據節(jié)點“主觀下線(sdown)”。
為什么稱為“主觀下線”?因為在一個分布式系統(tǒng)中,有多個機器在一起聯(lián)動工作,網絡可能出現(xiàn)各種狀況,僅憑一個節(jié)點的判斷還不足以認為一個數據節(jié)點下線了,這就需要后面的“客觀下線”。
客觀下線
當一個哨兵節(jié)點認為主節(jié)點主觀下線時,該哨兵節(jié)點需要通過”sentinel is-master-down-by addr”命令向其他哨兵節(jié)點咨詢該主節(jié)點是否下線了,如果有超過半數的哨兵節(jié)點都回答了下線,此時認為主節(jié)點“客觀下線”。
選舉哨兵領導者
當主節(jié)點客觀下線時,需要選舉出一個哨兵節(jié)點做為哨兵領導者,以完成后續(xù)選出新的主節(jié)點的工作。
這個選舉的大體思路是:
- 每個哨兵節(jié)點通過向其他哨兵節(jié)點發(fā)送”sentinel is-master-down-by addr”命令來申請成為哨兵領導者。
- 而每個哨兵節(jié)點在收到一個”sentinel is-master-down-by addr”命令時,只允許給第一個節(jié)點投票,其他節(jié)點的該命令都會被拒絕。
- 如果一個哨兵節(jié)點收到了半數以上的同意票,則成為哨兵領導者。
- 如果前面三步在一定時間內都沒有選出一個哨兵領導者,將重新開始下一次選舉。
可以看到,這個選舉領導者的流程很像raft中選舉leader的流程。
選出新的主節(jié)點
在剩下的redis從節(jié)點中,按照以下順序來選擇新的主節(jié)點:
- 過濾掉“不健康”的數據節(jié)點:比如主觀下線、斷線的從節(jié)點、五秒內沒有回復過哨兵節(jié)點ping命令的節(jié)點、與主節(jié)點失聯(lián)的從節(jié)點。
- 選擇slave-priority(從節(jié)點優(yōu)先級)最高的從節(jié)點,如果存在則返回不存在則繼續(xù)后面的流程。
- 選擇復制偏移量最大的從節(jié)點,這意味著這個從節(jié)點上面的數據最完整,如果存在則返回不存在則繼續(xù)后面的流程。
到了這里,所有剩余從節(jié)點的狀態(tài)都是一樣的,選擇runid最小的從節(jié)點。
提升新的主節(jié)點
選擇了新的主節(jié)點之后,還需要最后的流程讓該節(jié)點成為新的主節(jié)點:
- 哨兵領導者向上一步選出的從節(jié)點發(fā)出“slaveof no one”命令,讓該節(jié)點成為主節(jié)點。
- 哨兵領導者向剩余的從節(jié)點發(fā)送命令,讓它們成為新主節(jié)點的從節(jié)點。
- 哨兵節(jié)點集合會將原來的主節(jié)點更新為從節(jié)點,當其恢復之后命令它去復制新的主節(jié)點的數據。
歡迎移步搜索關注公眾號:互聯(lián)網架構師之路(hlw_architector),獲取最新架構材料。
總結
以上是生活随笔為你收集整理的springboot redis 断线重连_Redis高可用方案实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: react安装_超全面详细一条龙教程!从
- 下一篇: startindex 不能大于字符串长度