那些年用過的Redis集羣架構(含面試解析)

原文鏈接:https://www.cnblogs.com/rjzheng/p/10360619.html

引言

今天是2019年2月12號,也就是大年初八,我接到了高中同學劉有碼面試失利的消息。

他面試的時候,身份是某知名公司的小碼農一枚,卻因爲不懂自己生產上Redis是如何部署的,導致面試失敗!

人間慘劇,莫過於此。

接到他面試失利的消息,我差點發出豬一樣的笑聲,顯然是平時太少關注孤獨煙這個公衆號!

我提筆6次,放筆6次,差點因爲過於興奮而沒法編下去。最後還是硬着頭皮寫下了本文!

因此,今天我們來談談Redis集羣這個話題,需要說明的是本文

  • 適合人羣:不知道自己生產redis集羣架構,以及對Redis集羣不瞭解的人
  • 不適合羣: 對自己生產Redis集羣架構非常瞭解的人

本文預計分兩個部分

  • 第一部分:講講Redis集羣架構的發展
  • 第二部分:煙哥彩蛋環節,講講面試注意事項!

ps:煙哥彩蛋環節的內容,小白必背!必背!必背!

 

正文

老規矩,我還是以循序漸進的方式來講,我一共經歷過三套集羣架構的演進!

Replication+Sentinel

這套架構使用的是社區版本推出的原生高可用解決方案,其架構圖如下!
在這裏插入圖片描述
這裏Sentinel的作用有三個:

  • 監控:Sentinel 會不斷的檢查主服務器和從服務器是否正常運行。
  • 通知:當被監控的某個redis服務器出現問題,Sentinel通過API腳本向管理員或者其他的應用程序發送通知。
  • 自動故障轉移:當主節點不能正常工作時,Sentinel會開始一次自動的故障轉移操作,它會將與失效主節點是主從關係 的其中一個從

節點升級爲新的主節點,並且將其他的從節點指向新的主節點。

工作原理就是,當Master宕機的時候,Sentinel會選舉出新的Master,並根據Sentinel中client-reconfig-script腳本配置的內容,去動態修改VIP(虛擬IP),將VIP(虛擬IP)指向新的Master。我們的客戶端就連向指定的VIP即可!
故障發生後的轉移情況,可以理解爲下圖
在這裏插入圖片描述
缺陷:

  1. 主從切換的過程中會丟數據
  2. Redis只能單點寫,不能水平擴容

 

Proxy+Replication+Sentinel

這裏的Proxy目前有兩種選擇:Codis和Twemproxy。我經歷這套架構的時間爲2015年,當時我好像諮詢過我的主管爲啥不用Codis和Redis官網的Redis Cluster。原因有二:

  1. 據說是因爲Codis開源的比較晚,考慮到更換組件的成本問題。畢竟本來運行好好的東西,你再去換組件,風險是很大的。
  2. Redis Cluster在2015年還是試用版,不保證會遇到什麼問題,因此不敢嘗試。

所以我沒接觸過Codis,之前一直用的是Twemproxy作爲Proxy。

這裏以Twemproxy爲例說明,如下圖所示
在這裏插入圖片描述
工作原理如下

  • 前端使用Twemproxy+KeepAlived做代理,將其後端的多臺Redis實例分片進行統一管理與分配
  • 每一個分片節點的Slave都是Master的副本且只讀
  • Sentinel持續不斷的監控每個分片節點的Master,當Master出現故障且不可用狀態時,Sentinel會通知/啓動自動故障轉移等動作
  • Sentinel 可以在發生故障轉移動作後觸發相應腳本(通過 client-reconfig-script 參數配置 ),腳本獲取到最新的Master來修改Twemproxy配置

缺陷:

  1. 部署結構超級複雜
  2. 可擴展性差,進行擴縮容需要手動干預
  3. 運維不方便

 

Redis Cluster

我經歷這套架構的時間爲2017年,在這個時間Redis Cluster已經很成熟了!你們在網上能查到的大部分缺點,在我接觸到的時候基本已經解決!

比如沒有完善的運維工具?可以參照一下搜狐出的CacheCloud

比如沒有公司在生產用過?我接觸到的時候,百度貼吧,美團等大廠都用過了。

比如沒有Release版?我接觸到的時候距離Redis Cluster發佈Release版已經很久。

而且畢竟是官網出的,肯定會一直維護、更新下去,未來必定會更加成熟、穩定。換句話說,Redis不倒,Redis Cluster就不會放棄維護。所以,我推薦還是這套架構!

如下圖所示
在這裏插入圖片描述
工作原理如下

  • 客戶端與Redis節點直連,不需要中間Proxy層,直接連接任意一個Master節點
  • 根據公式HASH_SLOT=CRC16(key) mod 16384,計算出映射到哪個分片上,然後Redis會去相應的節點進行操作

具有如下優點:

  1. 無需Sentinel哨兵監控,如果Master掛了,Redis Cluster內部自動將Slave切換Master
  2. 可以進行水平擴容
  3. 支持自動化遷移,當出現某個Slave宕機了,那麼就只有Master了,這時候的高可用性就無法很好的保證了,萬一master也宕機了,咋辦呢? 針對這種情況,如果說其他Master有多餘的Slave ,集羣自動把多餘的Slave遷移到沒有Slave的Master 中。

缺點:

  1. 批量操作是個坑
  2. 資源隔離性較差,容易出現相互影響的情況。

 

煙哥彩蛋

在面試中如果碰到下列問題,如何應用上本篇的知識呢?先明確一點,我推薦的是Redis Cluster。
OK,開始舉例說明

問題1: 懂Redis事務麼?
正常版: Redis事務是一些列redis命令的集合,blabla…
高調版: 我們在生產上採用的是Redis Cluster集羣架構,不同的key是有可能分配在不同的Redis節點上的,在這種情況下Redis的事務機制是不生效的。其次,Redis事務不支持回滾操作,簡直是雞肋!所以基本不用!

問題2: Redis的多數據庫機制,瞭解多少?
正常版: Redis支持多個數據庫,並且每個數據庫的數據是隔離的不能共享,單機下的redis可以支持16個數據庫(db0 ~ db15)
高調版: 在Redis Cluster集羣架構下只有一個數據庫空間,即db0。因此,我們沒有使用Redis的多數據庫功能!

問題3: Redis集羣機制中,你覺得有什麼不足的地方嗎?
正常版: 不知道
高調版: 假設我有一個key,對應的value是Hash類型的。如果Hash對象非常大,是不支持映射到不同節點的!只能映射到集羣中的一個節點上!還有就是做批量操作比較麻煩!

問題4: 懂Redis的批量操作麼?
正常版: 懂一點。比如mset、mget操作等,blabla
高調版: 我們在生產上採用的是Redis Cluster集羣架構,不同的key會劃分到不同的slot中,因此直接使用mset或者mget等操作是行不通的。

問題5: 那在Redis集羣模式下,如何進行批量操作?
正常版: 不知道
高調版: 這個問題其實可以寫一篇文章了,改天寫。這裏說一種有一個很簡單的答法,足夠面試用。即:

如果執行的key數量比較少,就不用mget了,就用串行get操作。如果真的需要執行的key很多,就使用Hashtag保證這些key映射到同一臺redis節點上。簡單來說語法如下

對於key爲{foo}.student1、{foo}.student2,{foo}student3,這類key一定是在同一個redis節點上。因爲key中“{}”之間的字符串就是當前key的hash tags, 只有key中{ }中的部分才被用來做hash,因此計算出來的redis節點一定是同一個!

ps: 如果你用的是Proxy分片集羣架構,例如Codis這種,會將mget/mset的多個key拆分成多個命令發往不同得redis實例,這裏不多說。我推薦答的還是redis cluster。

問題6: 你們有對Redis做讀寫分離麼?
正常版: 沒有做,至於原因額。。。額。。。額。。沒辦法了,硬着頭皮扯~
高調版: 不做讀寫分離。我們用的是Redis Cluster的架構,是屬於分片集羣的架構。而redis本身在內存上操作,不會涉及IO吞吐,即使讀寫分離也不會提升太多性能,Redis在生產上的主要問題是考慮容量,單機最多10-20G,key太多降低redis性能.因此採用分片集羣結構,已經能保證了我們的性能。其次,用上了讀寫分離後,還要考慮主從一致性,主從延遲等問題,徒增業務複雜度。

 

總結

本文講了redis集羣架構的演進,以及面試注意事項,希望大家有所收穫!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章