今天是2019年2月12號,也就是大年初八,我接到了高中同窗劉有碼面試失利的消息。前端
他面試的時候,身份是某知名公司的小碼農一枚,卻由於不懂本身生產上Redis是如何部署的,致使面試失敗!面試
人間慘劇,莫過於此。redis
接到他面試失利的消息,我差點發出豬同樣的笑聲,顯然是平時太少關注孤獨煙這個公衆號!數據庫
我提筆6次,放筆6次,差點由於過於興奮而無法編下去。最後仍是硬着頭皮寫下了本文!後端
所以,今天咱們來談談Redis集羣這個話題,須要說明的是本文服務器
本文預計分兩個部分架構
ps
:煙哥彩蛋環節的內容,小白必背!必背!必背!運維
老規矩,我仍是以按部就班的方式來說,我一共經歷過三套集羣架構的演進!工具
這套架構使用的是社區版本推出的原生高可用解決方案,其架構圖以下!
性能
這裏Sentinel的做用有三個:
工做原理就是,當Master宕機的時候,Sentinel會選舉出新的Master,並根據Sentinel中client-reconfig-script
腳本配置的內容,去動態修改VIP(虛擬IP),將VIP(虛擬IP)指向新的Master。咱們的客戶端就連向指定的VIP便可!
故障發生後的轉移狀況,能夠理解爲下圖
缺陷:
(1)主從切換的過程當中會丟數據
(2)Redis只能單點寫,不能水平擴容
這裏的Proxy目前有兩種選擇:Codis和Twemproxy。我經歷這套架構的時間爲2015年,當時我好像諮詢過個人主管爲啥不用Codis和Redis官網的Redis Cluster。緣由有二:
因此我沒接觸過Codis,以前一直用的是Twemproxy做爲Proxy。
這裏以Twemproxy爲例說明,以下圖所示
工做原理以下
缺陷:
(1)部署結構超級複雜
(2)可擴展性差,進行擴縮容須要手動干預
(3)運維不方便
我經歷這套架構的時間爲2017年,在這個時間Redis Cluster已經很成熟了!大家在網上能查到的大部分缺點,在我接觸到的時候基本已經解決!
好比沒有完善的運維工具?能夠參照一下搜狐出的CacheCloud
。
好比沒有公司在生產用過?我接觸到的時候,百度貼吧,美團等大廠都用過了。
好比沒有Release版?我接觸到的時候距離Redis Cluster發佈Release版已經好久。
並且畢竟是官網出的,確定會一直維護、更新下去,將來一定會更加成熟、穩定。換句話說,Redis不倒,Redis Cluster就不會放棄維護。因此,我推薦仍是這套架構!
以下圖所示
工做原理以下
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}.student一、{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集羣架構的演進,以及面試注意事項,但願你們有所收穫!