1. 程式人生 > 實用技巧 >【Redis學習筆記】聊聊Redis的高可用性 (High Usability)(上)

【Redis學習筆記】聊聊Redis的高可用性 (High Usability)(上)

這個系列是個人學習Redis的一點記錄,希望對大家有幫助
若有錯誤,歡迎指正

我們為什麼需要高可用性?

我們知道,Redis作為一個記憶體資料庫,自然在物理層面上就奠定其高效能的基礎,也就是常說的QPS(Queries Per Second)很高。

由於是記憶體資料庫,其高效能的背後也有當機的風險,學過一點計算機組成原理的,或是對計算機硬體稍有了解的朋友,應該都對記憶體的特性不陌生------斷電清空內容

有人抬槓說,我們Redis有RDB(Redis Database)和AOF(Append Only File)這樣的持久化方案,何必害怕當機,資料存在檔案裡了。

這一點光就今天討論的可用性

來說,無可厚非。但是倘若我們在生產中,如在把redis作為社交app的快取之類的場景下,一旦當機,redis程序反覆請求I/O,系統效能必定下降(誰又希望在刷微博的時候等上30s呢?)。

因此,我們必須找到一個在效能與可用性之間兼得的方案。

什麼是高可用?

John Carnell在《Spring Microservice In Action》中如此描述高可用:

需要能夠支援 “熱”叢集環境,…可以跨多個節點共享。如果一個節點變得不可用,叢集中的其他節點應該能夠接管工作

從這句話中,可以窺見高可用性的概念無非三點:

  1. 熱叢集:實時更新同步熱資料,每個節點內部的資料都不過時
  2. 共享:叢集內的資訊互通有無
    ,比如,一個節點當機,叢集內其他節點應該都會收到訊息。
  3. 接管工作:叢集內節點當機(master)時,應該上一個替補(slave),並且這個替補能夠完全接管當機節點之前的工作。

Redis的高可用

Redis作為一個成熟的,被廣泛使用的分散式的,KV型的NoSQL產品,以上的特性自然是被很好地實現了,我們由簡至繁地來看看Redis的方案吧。

簡單實現:Redis主從模式

Redis的主從模式之所以被認為是簡單實現,是因為其雖然實現了其所謂的高可用性的 三點,但是其方式,或者說帶給開發人員和運維人員的體驗是地獄一般的,如果這種資料庫產品有“豆瓣評分”,我會給 3/10

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-enwWgONO-1602401045961)(./images/conventional.jpg)]

主從模式很簡單,就是設定一個redis的主節點

(master)給他配置兩個從節點(slave)

主節點擁有與客戶端(Client)的互動權(讀/寫),而從節點只能根據主節點的資料或者變化進行拷貝、更新,或是被客戶端讀(read-only)。

(客戶端可以認為是Jedis、Redis Desktop Manager、redis-cli等等)

接下來就是這個主從模式反人類的地方了:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-8FJg4Ysh-1602401045963)(./images/deficiency.jpg)]

這是主節點宕機的場景,這個場景下,運維人員要做的是:

  1. 把一個從節點(slave)升為主節點(master)
  2. 將其他從節點的拷貝地址轉移到新的主節點上
  3. 客戶端更新修改主節點地址

而這一切,都要手動完成

試想,這是在阿里的機房裡,並且此時正好是雙十一購物節。

好吧,我已經看到運維和架構師在寫辭呈了。

不光如此,這種傳統的主從模式還有其他弊端

  • 主節點效能被捆綁在單個機器上,寫的效能和儲存能力受單個機器拖累,單機效能提升成本較大,且容易發生邊際效應遞減

  • 備份時永遠以主節點為準,無論是增加新的key,還是修改value,都需要 從節點 向 主節點 作備份,此時,如果發生同步中斷,從節點 會請求全量同步,在大專案下,必然導致毫秒級甚至秒級的卡頓,這是產品經理使用者難以接受的。

  • 當然在全量同步時還會發生其他問題,這裡不再展開,請參考這裡

Sentinel架構(Redis哨兵模式)

既然主從模式是對運維的考驗,那麼,我們(Redis開發者們)就得對症下藥,把運維的雙手解放出來,專心於維護核心業務,而不是來維護輪子

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-U5I4hUAk-1602401045965)(./images/Redis哨兵.jpg)]

哨兵

Redis開發者們引入了哨兵(Sentinel)機制,所謂哨兵,即執行在伺服器上的哨兵程序

哨兵程序,是一種監控程序,有點像Netflix Eureka的監控機制,它們每隔一段時間向Redis節點們作一次檢查。(如每隔十秒傳送PING包,或者叫心跳包

(實際上,上圖也呈現了,哨兵節點之間也存在監控關係,使得哨兵服務本身更加健壯。)

回到高可用,哨兵模式又是如何實現以上幾條原則的呢?

“熱”叢集

熱叢集的實現,與傳統主從模式幾乎無差,無非是主從拷貝的那一套。

共享

這裡的共享涉及到三類物件:

  • Redis節點
  • 哨兵節點
  • 客戶端

比如,主節點一旦有故障,哨兵節點發送的PING包會timeout(見計算機網路ICMP - PING指令原理),隨後,哨兵節點通知其他節點(其他Redis節點、其他哨兵以及客戶端)

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-OL3GN6cI-1602401045967)(./Redis哨兵%202.jpg)]

接管工作

Sentinel模式的好處就是,主從更換是由程式自動執行的(運維落淚)

那麼,既然是自動更換,就要定下規則,要按照基本法、選舉法,去產生…

我們不如把這個Redis的叢集的運作看作是一場模擬政治遊戲

master是現任總統,slave是兩位副總統。

現在總統(Master)不再能夠勝任自己的職務,需要議會(哨兵叢集Sentinel Group)作一個彈劾仲裁

當有一位議員(哨兵)同意彈劾,我們稱作主觀下線(Subjective Down)。

當半數以上的議員(哨兵)同意彈劾,我們稱其為客觀下線(Objective Down)。

根據所謂 “民主” 的精神,需要半數以上的議員同意彈劾,才能啟動彈劾程式。

彈劾過程必須公平公開公正,彈劾後必須通知全體成員。(客戶端、從節點、其他哨兵)

主觀下線與客觀下線

tip

  • 主觀下線既針對主節點,也針對從節點
  • 客觀下線只針對主節點

主觀下線: 此時有一個哨兵節點對某個主/從節點的PING包超時,該哨兵分享訊息到其他節點,此時不採取接管措施

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-eEnRdFMb-1602401045969)(./images/Page1%204.jpg)]

客觀下線: 上面講了,標記了主節點為主觀下線的哨兵節點,會通知其他哨兵節點,當標記了主觀下線的哨兵達到一定數量 quorum時,主節點將被認為是客觀下線(此時對於傳送PING包的頻率也會隨之提高)
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-bMPUW8bL-1602401045971)(./images/Page2%204.jpg)]

授權: 當存在客觀下線的情況,我們不能立刻開始“彈劾程式”,需要一定數量的授權majority of the Sentinels才能開始。

接管

國不可一日無聖,彈劾完總統後,就要選出一個臨時總統,人選自然是從 slaves 裡來。

議員們需要通過某種流程,同時選出一個議員來執行這一項彈劾決議。(選出一個哨兵來通知從節點新的主節點更新配置)

其中一個Sentinel 將通知被選上的從節點,這個訊息也要公開

接下來就是被彈劾的總統與臨時總統的工作交接了。(新的主節點更改配置,從節點向新的主節點作備份複製

仍然有問題

雖然哨兵模式消除了運維人員手動維護節點接管的的痛點,但是仍然不能解決上面提到的幾個問題:

  1. 哨兵模式本身只是在主從模式上增加哨兵的特性,並不能解決單機儲存帶來的效能瓶頸。
  2. 哨兵模式增加的哨兵本身就是一種資源上的開銷,以實現自動化運維
  3. 全量同步問題上仍然是鴕鳥姿態(不解決),並且系統的伸縮性存在嚴重問題。

總結

主從模式是對高可用的一種可行實現,而哨兵模式本質上就是一種自上而下的優化------能解決一部分問題,但是沒能抓住本質

若是在高突發高併發的場景下,如何才能真正地提高效能呢?那可能需要一點破壞性創新。

下期會介紹 Redis Cluster叢集模式。


文中的政治體制與時政新聞,請不要對號入座,謝謝


參考致謝

https://blog.csdn.net/weixin_30329623/article/details/95551492

https://juejin.im/post/6844904191236767751

https://www.cnblogs.com/Eugene-Jin/p/10819601.html

https://redis.io/topics/sentinel

https://juejin.im/entry/6844903766534127624


GOOD LUCK ! ! !