【Redis學習筆記】聊聊Redis的高可用性 (High Usability)(上)
這個系列是個人學習Redis的一點記錄,希望對大家有幫助
若有錯誤,歡迎指正
我們為什麼需要高可用性?
我們知道,Redis作為一個記憶體資料庫,自然在物理層面上就奠定其高效能的基礎,也就是常說的QPS(Queries Per Second)很高。
由於是記憶體資料庫,其高效能的背後也有當機的風險,學過一點計算機組成原理的,或是對計算機硬體稍有了解的朋友,應該都對記憶體的特性不陌生------斷電清空內容。
有人抬槓說,我們Redis有RDB(Redis Database)和AOF(Append Only File)這樣的持久化方案,何必害怕當機,資料存在檔案裡了。
這一點光就今天討論的可用性
因此,我們必須找到一個在效能與可用性之間兼得的方案。
什麼是高可用?
John Carnell在《Spring Microservice In Action》中如此描述高可用:
需要能夠支援 “熱”叢集環境,…可以跨多個節點共享。如果一個節點變得不可用,叢集中的其他節點應該能夠接管工作
從這句話中,可以窺見高可用性的概念無非三點:
- 熱叢集:實時更新同步熱資料,每個節點內部的資料都不過時。
- 共享:叢集內的資訊互通有無
- 接管工作:叢集內節點當機(master)時,應該上一個替補(slave),並且這個替補能夠完全接管當機節點之前的工作。
Redis的高可用
Redis作為一個成熟的,被廣泛使用的分散式的,KV型的NoSQL產品,以上的特性自然是被很好地實現了,我們由簡至繁地來看看Redis的方案吧。
簡單實現:Redis主從模式
Redis的主從模式之所以被認為是簡單實現,是因為其雖然實現了其所謂的高可用性的 三點,但是其方式,或者說帶給開發人員和運維人員的體驗是地獄一般的,如果這種資料庫產品有“豆瓣評分”,我會給 3/10
。
主從模式很簡單,就是設定一個redis的主節點
主節點擁有與客戶端(Client)的互動權(讀/寫),而從節點只能根據主節點的資料或者變化進行拷貝、更新,或是被客戶端讀(read-only)。
(客戶端可以認為是Jedis、Redis Desktop Manager、redis-cli等等)
接下來就是這個主從模式反人類的地方了:
這是主節點宕機的場景,這個場景下,運維人員要做的是:
- 把一個從節點(slave)升為主節點(master)
- 將其他從節點的拷貝地址轉移到新的主節點上
- 客戶端更新修改主節點地址
而這一切,都要手動完成
試想,這是在阿里的機房裡,並且此時正好是雙十一購物節。
好吧,我已經看到運維和架構師在寫辭呈了。
不光如此,這種傳統的主從模式還有其他弊端:
-
主節點效能被捆綁在單個機器上,寫的效能和儲存能力受單個機器拖累,單機效能提升成本較大,且容易發生邊際效應遞減。
-
備份時永遠以主節點為準,無論是增加新的key,還是修改value,都需要 從節點 向 主節點 作備份,此時,如果發生同步中斷,從節點 會請求全量同步,在大專案下,必然導致毫秒級甚至秒級的卡頓,這是產品經理和使用者難以接受的。
-
當然在全量同步時還會發生其他問題,這裡不再展開,請參考這裡
Sentinel架構(Redis哨兵模式)
既然主從模式是對運維的考驗,那麼,我們(Redis開發者們)就得對症下藥,把運維的雙手解放出來,專心於維護核心業務,而不是來維護輪子。
哨兵
Redis開發者們引入了哨兵(Sentinel)機制,所謂哨兵,即執行在伺服器上的哨兵程序。
哨兵程序,是一種監控程序,有點像Netflix Eureka的監控機制,它們每隔一段時間向Redis節點們作一次檢查。(如每隔十秒傳送PING包,或者叫心跳包)
(實際上,上圖也呈現了,哨兵節點之間也存在監控關係,使得哨兵服務本身更加健壯。)
回到高可用,哨兵模式又是如何實現以上幾條原則的呢?
“熱”叢集
熱叢集的實現,與傳統主從模式幾乎無差,無非是主從拷貝的那一套。
共享
這裡的共享涉及到三類物件:
- Redis節點
- 哨兵節點
- 客戶端
比如,主節點一旦有故障,哨兵節點發送的PING包會timeout(見計算機網路ICMP - PING指令原理),隨後,哨兵節點通知其他節點(其他Redis節點、其他哨兵以及客戶端)
接管工作
Sentinel模式的好處就是,主從更換是由程式自動執行的(運維落淚)
那麼,既然是自動更換,就要定下規則,要按照基本法、選舉法,去產生…
我們不如把這個Redis的叢集的運作看作是一場模擬政治遊戲
master是現任總統,slave是兩位副總統。
現在總統(Master)不再能夠勝任自己的職務,需要議會(哨兵叢集Sentinel Group)作一個彈劾仲裁。
當有一位議員(哨兵)同意彈劾,我們稱作主觀下線(Subjective Down)。
當半數以上的議員(哨兵)同意彈劾,我們稱其為客觀下線(Objective Down)。
根據所謂 “民主” 的精神,需要半數以上的議員同意彈劾,才能啟動彈劾程式。
彈劾過程必須公平公開公正,彈劾後必須通知全體成員。(客戶端、從節點、其他哨兵)
主觀下線與客觀下線
tip:
- 主觀下線既針對主節點,也針對從節點
- 客觀下線只針對主節點
主觀下線: 此時有一個哨兵節點對某個主/從節點的PING包超時,該哨兵分享訊息到其他節點,此時不採取接管措施。
客觀下線: 上面講了,標記了主節點為主觀下線的哨兵節點,會通知其他哨兵節點,當標記了主觀下線的哨兵達到一定數量 quorum
時,主節點將被認為是客觀下線(此時對於傳送PING包的頻率也會隨之提高)
授權: 當存在客觀下線的情況,我們不能立刻開始“彈劾程式”,需要一定數量的授權majority of the Sentinels
才能開始。
接管
國不可一日無聖,彈劾完總統後,就要選出一個臨時總統,人選自然是從 slaves 裡來。
議員們需要通過某種流程,同時選出一個議員來執行這一項彈劾決議。(選出一個哨兵來通知從節點和新的主節點更新配置)
其中一個Sentinel 將通知被選上的從節點,這個訊息也要公開。
接下來就是被彈劾的總統與臨時總統的工作交接了。(新的主節點更改配置,從節點向新的主節點作備份複製)
仍然有問題
雖然哨兵模式消除了運維人員手動維護節點接管的的痛點,但是仍然不能解決上面提到的幾個問題:
- 哨兵模式本身只是在主從模式上增加哨兵的特性,並不能解決單機儲存帶來的效能瓶頸。
- 哨兵模式增加的哨兵本身就是一種資源上的開銷,以實現自動化運維。
- 全量同步問題上仍然是鴕鳥姿態(不解決),並且系統的伸縮性存在嚴重問題。
總結
主從模式是對高可用的一種可行實現,而哨兵模式本質上就是一種自上而下的優化------能解決一部分問題,但是沒能抓住本質。
若是在高突發高併發的場景下,如何才能真正地提高效能呢?那可能需要一點破壞性創新。
下期會介紹 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 ! ! !