這篇文章是對黃建宏第三部分的總結/學習筆記。redis
所謂的高可用,其實也就是這一部分介紹的幾個點,即 複製 + 哨兵 + 集羣。算法
目的
複製的目的是數據一致,就是從要達到和主的數據一致。服務器
流程
1.一開始,即初次
2.後面網絡
一開始是發送同步命令,同步數據,數據達到一致。
後面是新的命令,主會把新的命令轉發給從。數據結構
實現原理
兩種方法,
1.數據法
2.命令法異步
1.舊版很低效
2.新版經過部分同步,解決低效socket
若是斷線重連,舊版每次同步全部數據,而新版只同步掉線這段時間的數據。
並且同步數據很是耗時,咱們應該儘量的減小數據的複製,特別是避免每次複製全部數據,這樣就能夠避免每次複製了重複的數據。tcp
增量複製的細節
既然是增量複製,那麼就要記錄複製的進度。事實上,哪怕是全量複製,也有一箇中介文件,即RDB文件。如今,增量複製,只是多了一個要記錄進度的要求。學習
爲何從斷線重連主的時候,可能切換主?
就是有可能鏈接的不是同一個主,爲何?線程
爲何還要弄一個緩衝區? 服務器端已經有了偏移量,爲何還要弄一個緩衝區?
爲何還要緩衝區?
做用
用於主從鏈接的檢測。
基於心跳檢測實現的幾個功能?
異常
複製的時候,可能出現兩種異常
1.長時間掉線,由於宕機了
2.短期臨時掉線,由於網絡緣由
若是是長時間掉線,在重連以後,也能夠複製掉線這段時間的全部命令。具體實現技術是,部分丟失命令重同步。
若是是短期臨時掉線,由於網絡緣由,那麼這個時候只是某一個命令丟失,也能夠針對這一個命令進行重發。具體實現技術是,1.客戶端(從節點),發送心跳 2.服務器發送丟失的某個命令。
不論是哪種狀況,長時間多命令,仍是短期臨時的某一個命令,都是根據服務器端(主節點)緩衝區+偏移量來解決命令丟失而後重發的問題。
心跳自己的實現原理是什麼?
首先,要理解的是,心跳的做用是什麼,做用是:
1.是否能夠通訊
2.通訊數據自己
至於具體的方式是什麼還真不重要,只要能達到目的就可了:
1.ping
2.tcp socket
通常來講,心跳不光光是檢查是否能夠通訊,並且要通訊數據,因此通常就不使用ping,並且tcp socket通訊。具體表現出來的形式是:
1.客戶端發送數據
好比,redis的心跳包含,心跳命令名字 + 偏移量。
2.服務器接受數據
若是發現和客戶端偏移量不同,就知道剛剛的那個命令丟失了,如今要重發,便可。
心跳時間間隔
1s。若是超過1s,即認爲命令丟失,須要重發丟失命令。
先來一個圖
首先,要明白一個大前提,那就是哨兵也是一個節點,只不過是一個沒有數據的節點,那要它何用?監控數據節點。
哨兵節點之間互相通訊嗎?通訊。 而RocketMQ監控節點之間是不通訊的,監控節點只與數據節點通訊。
還有一點,每一個哨兵節點是與全部數據節點保持通訊(即監控)。哨兵節點之間,也是每一個哨兵節點會與其餘全部的哨兵節點通訊,由於升級數據節點爲主的時候,會選擇一個leader哨兵節點。
如何配置被監控的數據節點?
有兩種方式,
1.一開始就在哨兵節點配置文件配置好,而後啓動的時候,加載
2.或者,先啓動哨兵節點,再啓動主數據節點(配置好哨兵節點),註冊到哨兵節點
不論是哪種方式,都是監控主節點,那從節點是怎麼監控的呢?由於能夠從主數據節點獲取到從數據節點的信息,因此也就能夠監控到從數據節點。
數據結構
哨兵節點和主數據節點創建鏈接,必須有兩種鏈接:
1.命令
2.訂閱hello
命令就是發送命令到主數據節點。
訂閱hello是幹嗎的?訂閱就是訂閱主題,目的是實現哨兵節點之間的通訊。由於全部哨兵節點都訂閱數據節點的同一個主題,若是有某一個哨兵節點發送數據到數據節點,那麼全部哨兵節點都會收到訂閱數據(包括髮送數據的哨兵節點它本身也會收到,由於它也訂閱了該數據節點的主題)。具體數據是1.輸入數據是定時幾秒發送命令2.輸出數據是各個節點(哨兵節點和數據節點)的信息,好比,ip port之類的信息,若是這些信息有變動,那麼就更新。
總結
哨兵和哨兵之間的通訊,與哨兵和數據節點的通訊是不一樣的。
哨兵和數據節點是直接通訊,由於有配置ip port。
而哨兵如何其餘哨兵,是由於每一個哨兵都監控了數據節點,而且都訂閱了數據節點的同一個主題,因此,只要某一個哨兵發送數據到數據節點,其餘哨兵就會收到這些信息,從而就知道了別的全部哨兵的存在了(包括ip port等信息數據)。因此,哨兵之間沒有直接通訊,而是間接的經過數據節點的主題來通訊,因此也就不須要哨兵節點之間互相配置ip port。
哨兵與哨兵的第一次通訊,是經過數據節點的訂閱主題間接的實現鏈接和通訊。完成第一次通訊以後,就獲得了對方的信息,立刻還會互相雙向建立命令鏈接,進行命令通訊,以便及時更新對方的信息。
注意
哨兵和數據節點之間,是有兩種鏈接:1,訂閱鏈接 2,命令鏈接。
而,哨兵之間,只有一種鏈接,那就是命令鏈接,由於訂閱的是數據節點,哨兵之間不須要互相訂閱。
訂閱鏈接和命令鏈接的區別是什麼?
首先,訂閱鏈接的對象是,哨兵訂閱數據節點,哨兵之間不會互相訂閱;
命令鏈接的對象是,全部節點之間,包括哨兵/數據節點和哨兵/哨兵,注意主數據節點和主數據節點不通訊。
其次,做用,訂閱鏈接的做用是,全部的哨兵節點都要訂閱同一個數據節點的同一個主題,目的是能夠自動發現別的哨兵,訂閱鏈接算是第一次通訊,建立數據;而數據鏈接的做用是,用於後來定時更新數據。
哪些節點之間是有鏈接/通訊的?
1.哨兵和全部的節點(包括主和從)都有鏈接 再細分爲兩種,一種是哨兵和數據節點是訂閱鏈接+命令鏈接,一直是哨兵之間只有命令鏈接沒有訂閱鏈接由於不須要訂閱鏈接。
2.主和本身的從/多從 + 哨兵
3.從和本身的主且只有一個主 + 哨兵
還有,鏈接都是異步鏈接,什麼是異步鏈接?
哨兵檢測數據節點是否下線 兩種方法
1.主觀
2.客觀
如何實現?基於命令鏈接。
主觀就是我的認爲的意思,在這裏是當前這個哨兵認爲,具體的判斷算法是,一段時間內(幾十秒),一直收不到命令鏈接(ping命令)的響應(數據節點會組裝響應數據),那麼就認爲數據節點下線。
而客觀是,數據節點真的已經下線,什麼叫真的,就是不少哨兵都檢測到數據節點確實已經鏈接不上了,那麼就認爲該數據節點真的掛了。具體算法是: 1.哨兵1檢測到數據節點掛了
2.哨兵1詢問其餘的哨兵節點是否真的掛了
3.其餘哨兵節點都一致認爲數據節點確實掛了
4.哨兵1就把數據節點狀態置位下線
5.其餘哨兵也是同理處理
至於什麼叫一致認爲,這個數字可配置,規定是幾個,就是幾個,並且每一個哨兵規定的可能不同,總之,只要最終計算獲得的數量大於這個值,那麼就認爲是客觀下線。
就算是主觀下線,一段時間內,這個時間也是可配置,不一樣哨兵可能配置的值也不同。
總結
雖然下線有兩種,可是判斷一個數據節點是否下線的標誌是,主觀和客觀都要知足。主觀是單個哨兵認爲下線,並記錄下線信息,客觀是配置數量的哨兵互相通訊獲得對方的下線信息,而後計算數量,最終才確認下線。
下線以後,怎麼辦?選擇新的主數據節點。具體步驟是:
1.哨兵之間先選一個leader哨兵
2.leader哨兵實現故障轉移,說是故障轉移,其實就是升級其中的某一個從數據節點爲主,降級主數據節點爲新的主節點的從
選leader哨兵的算法?
1.輸入數據
包含字段:
1)是否下線 //0未下線,1下線
2)是檢測是否下線仍是選leader //*檢測是否下線,當前哨兵runId就是選leader
3)計數 //一開始是0
說明
因爲選leader的命令和檢測是否下線的命令是同一個命令,只是有個參數不一樣,用於標識當前命令是選Leade仍是檢測是否下線。
2.輸出數據
包含字段:
1)是否下線 //0未下線,1下線
2)是檢測是否下線仍是選leader //*檢測是否下線,當前哨兵runId就是選leader
3)計數 //若是贊成,每次加1
關於計數
舉個例子
1.哨兵1申請哨兵2,成功,加1
2.哨兵1申請哨兵3,成功,再加1
3.哨兵1的計數如今是2,過半,成爲leader
注:什麼紀元不紀元,其實就是計算數量。每次申請別人是否贊成本身成爲leader,若是贊成,這個字段的值就加1,最終總數超過一半的哨兵,那麼就是leader。由於申請的時候,有前後順便,誰最早過半,誰就是leader。
選從數據節點的算法?
按如下幾項的前後順序,依次進行排序,最終獲得一個從數據節點。
1.是否下線
2.優先級
3.偏移量 4.服務器id
細節以下
首先,獲得全部的節點的集合。
是否下線指,1.過濾已經下線的(客觀下線)2.過濾幾秒以內沒有響應的(主觀下線)3.過濾幾毫秒以內沒有響應的(臨時網絡問題),總之,就是過濾掉下線或網絡通訊很差的。
剩下的,再按優先級排序。優先級是指?全部的任何一個優先級,都是一個值爲數字的字段,好比線程優先級,或者應用程序裏常常會使用到的優先級。
偏移量最大,說明數據最新。
最後,服務器id排序。
完成,選出一個從數據節點。
節點之間通訊的幾種不一樣類型?
1.訂閱鏈接
2.命令鏈接
3.info命令
4.ping
前面兩種是鏈接,命令包括設置這樣的操做,好比設置從爲主(slaveof no one)。 info和ping是爲了獲取狀態信息,便是否通訊正常等。
但凡是涉及到監控通訊狀態是否正常的,基本上都是幾秒一次。
slaveof no one,表示設置爲主,slaveof ip port,表示設置爲ip/port的從,slaveof 參數,這個命令是由哨兵發出的。
步驟
1.先選擇一個哨兵leader
2.再選擇一個從節點進行升級
這裏面最重要的是如何選擇,即選擇的算法是什麼。
黃建宏