redis通訊與高可用叢集原理

廣州蘆葦科技Java開發團隊發表於2019-01-25

上一篇文章介紹了單機版的redis的持久化與過期鍵刪除原理。現在介紹一下叢集的redis的通訊與叢集的原理,好!廢話不多說,讓我們開始吧。。。

redis通訊

redis是一個小系統,那麼為了讓這個系統可以穩定地工作,通訊便是不可缺少的功能,redis的通訊通過事件機制來實現,它的事件有兩種,檔案事件和時間事件

檔案事件

檔案事件主要用於執行命令,如寫入寫出等。。檔案事件通過套接字來進行通訊,套接字裡面說明了這個事件具體是什麼任務,見下圖

enter description here

由圖我們可以知道,redis的檔案事件處理器由以下部分組成

  1. 套接字:用於按照一定的規則封裝事件的任務。
  2. I/O多路複用程式:檔案事件處理器使用I/O多路複用程式來監聽多個套接字,並根據套接字所執行的任務為套接字 關聯不同的事件處理器
  3. 檔案事件分派器:檔案事件分派器將將所有的檔案事件放在一個佇列裡面,然後逐個取出交給事件處理器處理,所以說redis是單執行緒的
  4. 事件處理器:處理事件
時間事件

時間事件分為定時事件和週期性事件

  1. 定時事件:讓程式在指定時間執行的定時任務
  2. 週期性事件:週期性執行的事件,如過期鍵刪除中的定期刪除
  3. 時間事件的實現

enter description here

伺服器將所有的時間事件放在一個無序的連結串列(不按照when來進行排序),每當時間事件執行器執行,就遍歷這個佇列查詢已經到時間的事件然後呼叫相應的處理器進行處理

事件排程

在檔案事件和時間事件同時存在的時候,如何進行排程?

1、首先檔案事件是隻要有檔案事件到達就馬上執行

2、對於時間事件它的執行方式則是

  • 2-1 獲取最快要開始執行的時間事件的時間
  • 2-2 阻塞等待最近的需要執行的時間事件的到來
  • 2-3 時間到來,執行時間事件

3、事件排程(檔案事件與時間事件共存)--》aeProcessEvent 函式,函式的原理如圖(不貼程式碼了)見它的原理圖

enter description here

意思就是不斷處理檔案事件,當時間事件到來則開始處理時間事件,沒有事件則進入阻塞狀態,不斷迴圈。但是需要注意的是,這些事件都不是搶佔式的,而是一個接著一個執行,當然,如果一個事件執行的時間超越某個臨界值的時候,這個事件會自動break,然後儲存狀態等待下次執行

4、例項

上面解釋那麼多肯定都不如一個例項來得清楚,那麼讓我們來個例項

開始時間 結束時間 動作
0 10 建立一個在100毫秒執行的事件事件
11 30 等待檔案事件
31 50 檔案事件到達,處理檔案事件
51 85 等待檔案事件
85 130 檔案事件到達,執行檔案事件
130 150 處理時間事件(0毫秒建立的時間事件)

從上面的例子可以看出檔案事件到來,且處理器空閒的話就立馬執行,時間事件在時間到來的時候,如果處理器空閒,則執行,處理器不空閒,需要等到當前檔案事件執行完了之後才進行處理,而不進行搶佔式排程。

Redis叢集的原理

主從複製

在redis中,可以通過複製配置檔案然後啟動一個新的redis(redis叢集搭建,下個文章講解),新的redis可用通過slaveof命令讓一個伺服器成為另個伺服器的從伺服器,現在先讓我們從單個主機和單個從機的簡單的情況探討redis叢集中的叢集與資料一致性(基於redis2.8以上的版本)

(筆者畫風隨意,讀者請見諒)

enter description here

redis主從複製分為兩部分同步與命令傳播

為了簡單說明,我將從一條時間線進行說明

初次進行主從複製-->redis執行中命令同步-->redis當機重啟後資料同步

1、初次主從複製

當從機剛剛啟動,則它需要從主機同步資料,也就是將主機的資料同步一份給從機,首先主機收到salveof命令後,

  • 主機以當前狀態為節點執行BGSAVE命令,生成一個RDB檔案然後發給從機
  • 主機生成一個緩衝區記錄從當前開始所執行的命令
  • 從機先拿到主機發來的RDB檔案進行同步
  • 從機拿到緩衝區裡面的命令,然後執行,至此,同步完成,這種方式也叫做“同步”

2、redis執行中命令同步

對於執行中同步,redis採用偏移量機制和複製積壓緩衝區機制

2-1偏移量機制

主從同步完成後,主從均記錄一個變數offset,每執行一條命令,offest加1,從機也是如此,故而只要比較主機和從機的offest的大小,主機offest減去從機offest就知道他們兩差幾條資料

2-2複製積壓緩衝區機制

redis中有一個複製積壓緩衝區,他的大小預設為1m,採用先進先出的方式記錄最近執行的命令,當命令還未到1m則往裡面不斷放入最近執行的命令,大於1m後拋棄最老的命令,放入最新的命令

2-3同步

  • 計算偏移量:主機offest減從機offest中得到主從相差幾條資料;
  • 主機通過偏移量從複製積壓緩衝區裡面取從機缺少的那幾條資料發給從機;
  • 從機執行後便完成同步,這便是命令傳播

3、當機後同步

主機當機,則從機上位,成為新的主機,然後老的主機啟動成為從機,從機當機則啟動還是從機,這兩種情況均會導致主從不一致,那麼這種情況下,同步方案如下:

  • 通過offest得到主從之間差了多少條命令。
  • 如果偏移量差不大於複製積壓緩衝區大小,也就是當機丟失的命令在複製積壓緩衝區裡面還能找到,則拿出裡面的命令執行一遍就可以恢復。
  • 如果已經超出了複製積壓緩衝區大小,則需要進行RDB來進行同步,也就是和初次同步時那樣。
redis叢集

這是一篇理論性的文章,那麼叢集搭建的過程我將在下一篇文章裡面進行介紹,假設我們已經有一個叢集,三主三從,分別為7001、7002、7003、7004、7005、7006

enter description here

1、記憶體地址管理

在進行叢集后,redis預設將整個記憶體非為16384塊(也可以自己分),也就是0-16383,在進行搭建的時候,我們可以指定每組主機管理的地址,最終會形成一個表,如下

enter description here

它記錄了每個主機所處理的地址,如7001處理0-5000,7002處理5001-10000,7002處理10001-16383

2、命令處理

我們知道redis叢集裡面任何一個主機都可以處理所有命令,那麼他們是如何做到的呢,看圖

enter description here

命令到來,先通過CRC16演算法算出這條命令具體要對那個槽做操作,如果就是這個主節點管理的曹,則處理,如果不是,則先執行move命令,跳轉到正確的主節點,然後執行命令

3、當機與選舉 當主機當機後,從機如何變成主機,就需要進行選舉,選舉是一個很有趣的過程,首先需要明白一點,就是主機才有投票的權力

例子就以上面三主三從為例,假設7001當機,選舉如下

  • 從機7004將通過廣播向叢集傳送一條訊息,意思就是為自己拉票,
  • 如果此時主機還沒有套票給其他從機則這個主機會將票投給第一個向他拉票的從機,
  • 如果有一個從機得到半數主機以上的票則當選為新的主機(假設除去已經當機的主機還有N個主機,則從機需要得到N/2+1的票才能當選為主機)
  • 至此新主機上位,原來的主機會重啟變為從機

合理性

這種選舉看起來有點隨便呀,真是這樣?仔細一想,其實這種選舉方式恰好選舉出了網路狀態最好的從機,是很不錯的選舉

一些需要避免的問題----》選舉失敗,從機無法變為主機

例子

enter description here
看上圖,假設03主機當機,那麼就可能出現主機選舉失敗的可能

06 和 07 均廣播拉票,如果主機01將票給了06,主機02將票給了07,那麼兩個從機均得到一票,均不滿足N/2+1的票,兩個都不能當選,故而選舉失敗,這種錯誤是可以人為避免的。

4、可用性分析

4-1 穩定性 就以剛才的三主三從為例,他的生存能力已經非常的強,任何一臺機子當機都不會導致整個叢集不可用,當然有種情況就是某個叢集的某一組主機和從機全部當機,那麼就會導致叢集不可用,如01和04同時當機,那麼這組主從管理的0-5000這5001個槽將不能被管理,導致叢集不可用

4-2 可用性 在設定叢集之後,主機主要負責寫,而從機負責讀,實現讀寫分離,大大加強了redis效能。

總結

前面的連篇文章都只是介紹了redis的一些原理,下一篇文章我將從實踐的角度開始介紹叢集的搭建和使用,喜歡的話可以關注一下呦,您的關注是我前進的動力。

增鑫

廣州蘆葦科技Java開發團隊

蘆葦科技-廣州專業網際網路軟體服務公司

抓住每一處細節 ,創造每一個美好

關注我們的公眾號,瞭解更多

想和我們一起奮鬥嗎?lagou搜尋“ 蘆葦科技 ”或者投放簡歷到 server@talkmoney.cn 加入我們吧

redis通訊與高可用叢集原理

關注我們,你的評論和點贊對我們最大的支援

相關文章