1. 程式人生 > >《【面試突擊】— Redis篇》--Redis Cluster及快取使用和架構設計的常見問題

《【面試突擊】— Redis篇》--Redis Cluster及快取使用和架構設計的常見問題

能堅持別人不能堅持的,才能擁有別人未曾擁有的。
關注程式設計大道公眾號,讓我們一同堅持心中所想,一起成長!!

《【面試突擊】— Redis篇》--Redis Cluster及快取使用和架構設計的常見問題

在這個系列裡,我會整理一些面試題與大家分享,幫助年後和我一樣想要在金三銀四準備跳槽的同學。
我們一起鞏固、突擊面試官常問的一些面試題,加油!!

《【面試突擊】— Redis篇》--Redis資料型別?適用於哪些場景?

《【面試突擊】— Redis篇》--Redis的執行緒模型瞭解嗎?為啥單執行緒效率還這麼高?

《【面試突擊】— Redis篇》-- Redis的主從複製?哨兵機制?

《【面試突擊】— Redis篇》-- Redis哨兵原理及持久化機制

說說Redis cluster

在redis cluster叢集架構中,可以由N個redis master node組成,每個master node都可以掛載多個slave node。
可以自動將資料進行分片,每個master上放一部分資料;
還提供內建的高可用支援,部分master不可用時,還是可以繼續工作的,因為每個master都有salve節點,那麼如果mater掛掉,redis cluster這套機制,就會自動將某個slave切換成master;
支援讀寫分離:對於每個master來說,都負責寫請求,寫就寫到master,然後讀就從mater對應的slave去讀;

總結:redis cluster(多master + 讀寫分離 + 高可用)

我們只要基於redis cluster去搭建redis叢集即可,不需要再手工去搭建replication複製+主從架構+讀寫分離+哨兵叢集+高可用,不需要這樣去搭了。

redis cluster 和 redis replication + sentinal的使用場景是什麼

redis replication + Sentinal:redis的一主多從,讀寫分離+哨兵機制

如果資料量很少,主要是承載高併發高效能的場景,比如快取一般就幾個G的話,單機足夠了。那就搭建主從複製的架構(redis replication),一個mater,多個slave,要幾個slave跟你要求的讀吞吐量有關係,然後自己搭建一個sentinal叢集,去保證redis主從架構的高可用性,就可以了。

而redis cluster 主要是針對海量資料+高併發+高可用的場景,如果是海量資料,如果你的資料量很大,那麼建議就用redis cluster,所有master的容量總和就是redis cluster可快取的資料容量。

redis cluster中是如何實現資料分佈的?這種方式有什麼優點?

redis cluster有固定的16384個hash slot(雜湊槽),對每個key計算CRC16值,然後對16384取模,可以獲取key對應的hash slot。

redis cluster中每個master都會持有部分slot(槽),比如有3個master,那麼可能每個master持有5000多個hash slot。

hash slot讓node的增加和移除很簡單,增加一個master,就將其他master的hash slot移動部分過去,減少一個master,就將它的hash slot移動到其他master上去。每次增加或減少master節點都是對16384取模,而不是根據master數量,這樣原本在老的master上的資料不會因master的新增或減少而找不到。並且增加或減少master時redis cluster移動hash slot的成本是非常低的。

redis cluster節點間通訊是什麼機制?

redis cluster節點間採取gossip協議進行通訊,所有節點都持有一份元資料,不同的節點如果出現了元資料的變更之後U不斷地i將元資料傳送給其他節點讓其他節點進行資料變更。

節點互相之間不斷通訊,保持整個叢集所有節點的資料是完整的。
主要交換故障資訊、節點的增加和移除、hash slot資訊等。

這種機制的好處在於,元資料的更新比較分散,不是集中在一個地方,更新請求會陸陸續續,打到所有節點上去更新,有一定的延時,降低了壓力;

缺點,元資料更新有延時,可能導致叢集的一些操作會有一些滯後。

如果現在有個讀超高併發的系統,用Redis來抗住大部分讀請求,你會怎麼設計?

首先,如果是讀高併發的話,先看讀併發的數量級是多少,因為redis單機的讀QPS在萬級,每秒幾萬沒問題,使用一主多從+哨兵叢集的快取架構來承載每秒10W+的讀併發,主從複製,讀寫分離。使用哨兵叢集主要是提高快取架構的可用性,解決單點故障問題。主庫負責寫,多個從庫負責讀,支援水平擴容,根據讀請求的QPS來決定加多少個redis從例項。如果讀併發繼續增加的話,只需要增加redis從例項就行了。

如果系統現在的業務量上升了,需要快取1T+的資料,你怎麼做?

因為Redis支撐海量資料的瓶頸在於單機容量,所以這個時候我會選擇redis cluster模式,每個主節點存一部分資料,假設一個master存32G,那隻需要n*32G>=1T,n個這樣的master節點就可以支援1T+的海量資料的儲存了。

Redis單主的瓶頸不在於讀寫的併發,而在於記憶體容量,即使是一主多從也是不能解決該問題,因為一主多從架構下,多個slave的資料和master的完全一樣。假如master是10G那slave也只能存10G資料。所以資料量受單主的影響。
而這個時候又需要快取海量資料,那就必須得有多主了,並且多個主儲存的資料還不能一樣。redis官方給出的 redis cluster 模式完美的解決了這個問題。

瞭解什麼是redis的雪崩和穿透嗎?如何應對?

其實這是問到快取必問的,因為快取雪崩和穿透,那是快取最大的兩個問題,要麼不出現,一旦出現就是致命性的問題。所以面試官一定會問你。

我先描述下如何出現的快取雪崩吧。

舉個例子,假設每天高峰期的時候系統每秒請求是5000次,快取在高峰期可以分擔每秒4000次請求,另外1000次請求落到資料庫(假設資料庫每秒可承擔2000次請求)。如果此時過來5000請求,但是redis因為某些原因掛掉了,快取整個就不能用了,那麼這5000個請求就全部落到資料庫。顯然資料庫扛不住,直接崩潰。此時,如果沒用什麼特別的方案來處理這個故障,只是很著急的重啟資料庫,結果因為快取還沒資料,立馬資料庫又被新的流量給打死了。這就是快取雪崩。

對於快取雪崩主要分為事前事中事後,
事前:如果快取不可用是因為快取中的大部分資料集中失效,我們可以對快取的失效時間加上一個隨機值,使失效時間分散一點,儘量避免集中失效。另外如果是因為別的原因redis宕機導致快取不可用,這時候我們就需要提前做好Redis高可用的架構,如主從+哨兵或redis cluster,來避免Redis出現故障時整個快取不可用,全盤崩潰。

事中:可以將一小部分資料同樣快取到本地ehcache(本地快取元件)快取,另外加上hystrix限流&降級元件,避免MySQL被打死。

事後:如果真的發生雪崩,我們還可以用redis的RDB或AOF重啟redis快速從磁碟載入快取資料。這就需要我們提前開啟Redis持久化機制,在雪崩發生的事後快速恢復快取資料,一旦重啟從磁碟中恢復資料到記憶體。

另外一個問題,快取穿透,一般是黑客惡意攻擊,或是自己系統出bug。例如黑客惡意偽造請求,這些請求都是資料庫根本查不到的,所以快取中也沒用,那這些大量的惡意請求都會落到資料庫去查詢,資料庫不就掛了嗎?

解決辦法就是
1、只要從資料庫沒查到,就寫入一個空值到快取裡去。
2、使用布隆過濾器對請求的key進行一層過濾,過濾掉系統認為不存在不合法的key。

說一說redis的過期策略吧

可以參考之前的這篇文章,什麼?我往Redis裡寫的資料怎麼沒了?

談談快取+資料庫雙寫不一致問題

可以參考之前的這篇文章,高併發場景下快取+資料庫雙寫不一致問題分析與解決方案設計


《【面試突擊】—Redis篇》就要結束了,暫時就整理這麼多,如果你還有更多的可以告訴我來補充哦

本系列文章在於面試突擊,不是教程,要是細挖能講好多,而面試你只需要把這個原理說出來就行了,如果邊講邊畫圖那就更好了。

該系列文章在於快速突擊,快速拾遺,溫習。