解說redis中如何實現高可用

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

  • 主從復制數據。
  • 采用哨兵監控數據節點的運行情況,一旦主節點出現問題由從節點頂上繼續進行服務。

主從復制

redis中主從節點復制數據有全量復制和部分復制之分。

舊版本全量復制功能的實現

全量復制使用snyc命令來實現,其流程是:

  • 從服務器向主服務器發送sync命令。
  • 主服務器在收到sync命令之后,調用bgsave命令生成最新的rdb文件,將這個文件同步給從服務器,這樣從服務器載入這個rdb文件之后,狀態就會和主服務器執行bgsave命令時候的一致。
  • 主服務器將保存在命令緩沖區中的寫命令同步給從服務器,從服務器執行這些命令,這樣從服務器的狀態就跟主服務器當前狀態一致了。

舊版本全量復制功能,其最大的問題是從服務器斷線重連時,即便在從服務器上已經有一部分數據了,也需要進行全量復制,這樣做的效率很低,于是新版本的redis在這部分做了改進。

新版本全量復制功能的實現

新版本redis使用psync命令來代替sync命令,該命令既可以實現完整全同步也可以實現部分同步。

復制偏移量

執行復制的雙方,主從服務器,分別會維護一個復制偏移量:

  • 主服務器每次向從服務器同步了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> <offset>命令,其中runid是上一次主服務器的運行id,offset是當前從服務器的復制偏移量。

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

  • 主服務器返回+fullresync <runid> <offset>回復,表示主服務器要求與從服務器進行完整的數據全量同步操作。其中,runid是當前主服務器運行id,而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”命令,讓該節點成為主節點。
  • 哨兵領導者向剩余的從節點發送命令,讓它們成為新主節點的從節點。
  • 哨兵節點集合會將原來的主節點更新為從節點,當其恢復之后命令它去復制新的主節點的數據。

感謝你耐心看完了文章...

轉載于:https://juejin.im/post/5cdc186f6fb9a032484d8a3d

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/448813.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/448813.shtml
英文地址,請注明出處:http://en.pswp.cn/news/448813.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

OpenCL memory object 之 Global memory (1)

這篇日志是學習AMD OpenCL文檔時候的總結。 OpenCL用memory object在host和device之間傳輸數據&#xff0c;memory object由runtime&#xff08;運行庫&#xff0c;driver的一部分&#xff09;來管理。 OpenCL中的內存對象包括buffer以及image&#xff0c;buffer是一維數據元素…

Docker: dockerfile 使用介紹

Docker簡介 前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 Docker項目提供了構建在Linux內核功能之上&#xff0c;協同在一起的的高級工具。其目標是幫助開發和運維人員更容易地跨系統跨…

【Hello CSS】第六章-文檔流與排版

作者&#xff1a;陳大魚頭github&#xff1a; KRISACHAN正常流 什么是“正常流”&#xff1f; 其實就是我們日常所說的“文檔流”。 在W3C官方文檔里對應的是“normal flow”。 正常流的盒子屬于格式化上下文(FC)&#xff0c;在CSS2.2中可以是表格、塊或內聯。 在CSS3中引入了f…

創建型模式---工廠模式

工廠模式 在工廠設計模式中&#xff0c;客戶端可以請求一個對象&#xff0c;而無需要知道這個對象來自哪里&#xff0c;也就是使用哪個類來生成這個對象。工廠背后的思想是簡化對象的創建。與客戶端自己基于類實例化直接創建對象相比&#xff0c;基于一個中心化函數來實現&…

OpenCL memory object 之 Global memory (2)

當我們用clCreateBuffer, clCreateImage創建OpenCL memory object時候&#xff0c;我們需要輸入一個flag參數&#xff0c;這個參數決定memory object的位置。 cl_mem clCreateBuffer (cl_context context, cl_mem_flags flags, size_t size, void *host_ptr, cl_int *errc…

數據結構進階篇-跳表

大家想必都知道&#xff0c;數組和鏈表的搜索操作的時間復雜度都是O(N)的&#xff0c;在數據量大的時候是非常耗時的。對于數組來說&#xff0c;我們可以先排序&#xff0c;然后使用二分搜索&#xff0c;就能夠將時間復雜度降低到O(logN)&#xff0c;但是有序數組的插入是一個O…

查看本機ssh公鑰,生成公鑰

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 查看ssh公鑰方法&#xff1a; 1.通過命令窗口&#xff1a;打開你的git bash 窗口&#xff0c;進入.ssh目錄&#xff1a;cd ~/.ssh&…

如何實現動態水球圖 --》 echars結合echarts-liquidfill實現

1&#xff09;項目中作為項目依賴&#xff0c;安裝到項目當中(注意必須要結合echars) npm install echarts vue-echarts --save npm install echarts-liquidfill --save 2&#xff09;在需要使用水晶球的組件里引入liquidFill.js import echarts-liquidfill/src/liquidFill.js;…

OpenCL memory object 之選擇傳輸path

對應用程序來說&#xff0c;選擇合適的memory object傳輸path可以有效提高程序性能。 下面先看一寫buffer bandwidth的例子&#xff1a; 1. clEnqueueWriteBuffer()以及clEnqueueReadBuffer() 如果應用程序已經通過malloc 或者mmap分配內存&#xff0c;CL_MEM_USE_HOST_PTR是個…

struts入門超詳細

https://blog.csdn.net/yerenyuan_pku/article/details/52652262轉載于:https://www.cnblogs.com/liuna369-4369/p/10870873.html

RabbitMQ 從入門到精通 (一)

目錄 1. 初識RabbitMQ2. AMQP3.RabbitMQ的極速入門4. Exchange(交換機)詳解4.1 Direct Exchange4.2 Topic Exchange4.3 Fanout Exchange5. Message 消息1. 初識RabbitMQ RabbitMQ 是一個開源的消息代理和隊列服務器&#xff0c;用來通過普通協議在完全不同的應用之間共享數據&a…

接收并解析消息體傳參、解析 json 參數

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1.場景&#xff1a;postman 發送了一個 post 請求&#xff0c;如下&#xff1a; 2. 解析方式為用一個 vo 對象來接收 json。把 json 中的…

OpenCL memory object 之 傳輸優化

首先我們了解一些優化時候的術語及其定義&#xff1a; 1、deferred allocation&#xff08;延遲分配&#xff09;&#xff0c; 在第一次使用memory object傳輸數據時&#xff0c;runtime才對memory object真正分配空間。 這樣減少了資源浪費&#xff0c;但第一次使用時要慢一些…

VBS使文本框的光標位于所有字符后

有時候在文本框里會顯示一部分提示信息&#xff0c;用戶在這些提示信息后面輸入文本&#xff0c;但是將焦點設置于文本框后&#xff0c;光標總是在文本框的最前面&#xff0c; 用戶輸入的時候需要按"-->"鍵將光標移到最后才能輸入&#xff0c;這樣的操作很不爽。我…

記錄ionic 最小化應用時所遇的問題

ionic3與ionic4最小化插件安裝不一樣&#xff1a; ionic3安裝方法&#xff1a; $ ionic cordova plugin add cordova-plugin-appminimize $ npm install --save ionic-native/app-minimize4 并在app.module.ts中 注入依賴&#xff1a; import { AppMinimize } from ionic-nativ…

解決 --- Docker 啟動時報錯:iptables:No chain/target/match by the name

問題&#xff1a;jenkins的docker containner啟動失敗&#xff0c;報錯&#xff1a;failed programming external connectivity … iptables: No chain/target/match by that name” docker 服務啟動的時候&#xff0c;docker服務會向iptables注冊一個鏈&#xff0c;以便讓dock…

AMD OpenCL 大學課程

AMD OpenCL大學課程是非常好的入門級OpenCL教程&#xff0c;通過看教程中的PPT&#xff0c;我們能夠很快的了解OpenCL機制以及編程方法。下載地址&#xff1a;http://developer.amd.com/zones/OpenCLZone/universities/Pages/default.aspx 教程中的英文很簡單&#xff0c;我相信…

第一篇 計算機基礎

1.什么是編程語言 python和中文、英語一樣、都是一門語言&#xff0c;只要是語言&#xff0c;其實就庫看成是一種事物與另一種事物溝通的介質。python屬于編程語言&#xff0c;編程語言是程序員與計算機之間溝通的介質&#xff1b;中文和英文則是人與人之間溝通的介質。 2.什么…

47.QT-QChart之曲線圖,餅狀圖,條形圖使用

1.使用準備 在pro中, 添加QT charts 然后在界面頭文件中添加頭文件并聲明命名空間,添加: #include <QtCharts> QT_CHARTS_USE_NAMESPACE 2.QChart之曲線圖 繪制曲線圖需要用到3個類 QSplineSeries: 用于創建有由一系列數據組成的曲線.類似的還有QPieSeries(餅圖數據). Q…

Docker 部署應用、jar 工程 docker 方式部署

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1. 把要部署的工程打成一個jar包。&#xff08;我的工程叫 gentle &#xff09; 打 jar 的方法&#xff1a;超簡單方法&#xff1a; Int…