原文連接node
能堅持別人不能堅持的,才能擁有別人不曾擁有的。
關注 編程大道 公衆號,讓咱們一同堅持心中所想,一塊兒成長!!面試
《【面試突擊】— Redis篇》-- Redis的主從複製?哨兵機制?redis
在這個系列裏,我整理了一些面試題與你們分享,這是第三篇幫助想要在金三銀四準備跳槽的同窗。 咱們一塊兒鞏固、突擊面試官常問的一些面試題,加油!!算法
《【面試突擊】— Redis篇》--Redis數據類型?適用於哪些場景?編程
《【面試突擊】— Redis篇》--Redis的線程模型瞭解嗎?爲啥單線程效率還這麼高?緩存
面試官在問了上兩次提到的問題以後,可能就會開始更加猛烈的攻勢,一連串的Redis的知識點向你拋過來,你頂的住嗎?bash
高併發: redis的單機吞吐量能夠達到幾萬不是問題,若是想提升redis的讀寫能力,能夠用redis的主從架構,redis天熱支持一主多從的準備模式,單主負責寫請求多從負責讀請求,主從之間異步複製,把主的數據同步到從。網絡
高可用: 首先利用redis的主從架構解決redis的單點故障致使的不可用,而後若是使用的是主從架構,那麼只須要增長哨兵機制便可,就能夠實現,redis主實例宕機,自動會進行主備切換。以此來達到redis的高可用。架構
在redis主從架構中,master負責接收寫請求,寫操做成功後返回客戶端OK,而後後將數據異步的方式發送給多個slaver進行數據同步,不過從redis 2.8開始,slave node會週期性地確認本身每次複製的數據量。併發
當啓動一個slave node的時候,它會發送一個PSYNC
命令給master node
。若是slave node是從新鏈接master node,那麼master node僅僅會複製給slave部分缺乏的數據; 不然若是是slave node第一次鏈接master node,那麼會觸發一次full resynchronization
全量複製。
開始full resynchronization
的時候,master會啓動一個後臺線程,開始生成一份RDB快照文件,同時還會將從客戶端收到的全部寫命令緩存在內存(內存緩衝區)中。RDB文件生成完畢以後,master會將這個RDB發送給slave,slave會先寫入本地磁盤,而後再從本地磁盤加載到內存中。而後master會將內存中緩存的寫命令發送給slave,slave也會同步這些數據。
另外slave node作複製的時候,是不會block master node
的正常工做的,也不會block對本身的查詢操做,它會用舊的數據集來提供服務; 可是複製完成的時候,須要刪除舊數據集,加載新數據集,這個時候就會暫停對外服務了。slave node主要用來進行橫向擴容,作讀寫分離,擴容的slave node能夠提升讀的吞吐量。slave與高可用性有很大的關係。
若是出現網絡故障斷開鏈接了,會自動重連的,從redis 2.8開始,就支持主從複製的斷點續傳,能夠接着上次複製的地方,繼續複製下去,而不是從頭開始複製一份。
master若是發現有多個slave node都來從新鏈接,僅僅會啓動一個rdb save操做,用一份數據服務全部slave node。
master node會在內存中建立一個backlog,master和slave都會保存一個replica offset,還有一個master id,offset就是保存在backlog中的。若是master和slave網絡鏈接斷掉了,slave會讓master從上次的replica offset開始繼續複製。
可是若是沒有找到對應的offset,那麼就會執行一次resynchronization全量複製。
哨兵是redis集羣架構中很是重要的一個組件,主要功能以下:
(1)集羣監控,負責監控redis master和slave進程是否正常工做
(2)消息通知,若是某個redis實例有故障,那麼哨兵負責發送消息做爲報警通知給管理員
(3)故障轉移,若是master node掛掉了,會自動轉移到slave node上
(4)配置中心,若是故障轉移發生了,通知client客戶端新的master地址
哨兵自己也是分佈式的,做爲一個哨兵集羣去運行,互相協同工做 (1)故障轉移時,判斷一個master node是宕機了,須要大部分的哨兵都贊成才行,涉及到了分佈式選舉的問題 (2)即便部分哨兵節點掛掉了,哨兵集羣仍是能正常工做的,由於若是一個做爲高可用機制重要組成部分的故障轉移系統自己是單點的,那就很坑爹了。
目前採用的是sentinal 2版本,sentinal 2相對於sentinal 1來講,重寫了不少代碼,主要是讓故障轉移的機制和算法變得更加健壯和簡單。
若是兩個哨兵實例,即兩個redis實例,一主一從的模式。
則redis的配置quorum=1,表示一個哨兵認爲master宕機便可認爲master已宕機。
可是若是是機器1宕機了,那哨兵1和master都宕機了,雖然哨兵2知道master宕機了,可是這個時候,須要majority,也就是大多數哨兵都是運行的,2個哨兵的majority就是2(2的majority=2,3的majority=2,5的majority=3,4的majority=2),2個哨兵都運行着,就能夠容許執行故障轉移。
但此時哨兵1沒了就只有1個哨兵了了,此時就沒有majority來容許執行故障轉移,因此故障轉移不會執行。
會有,並且有兩種可能,一種是異步複製,一種是腦裂致使的數據丟失。
好的,第一種很好理解,由於master 到 slave的複製是異步的,因此可能有部分數據還沒複製到slave的時候,master就宕機了,此時這些部分數據就丟失了。雖然master會作持久化,可是哨兵將slave提高爲master後,若是舊的master這時候好了,會當作slave掛到新的master上,重新的master同步數據,原來的數據仍是會丟失。
第二種,也就是說,某個master所在機器忽然脫離了正常的網絡,跟其餘slave機器不能鏈接,可是實際上master還運行着,即集羣分區現象。此時哨兵可能就會認爲master宕機了,而後開啓選舉,將其餘slave切換成了master.
這個時候,集羣裏就會有兩個master,也就是所謂的腦裂。
此時雖然某個slave被切換成了master,可是可能client還沒來得及切換到新的master,還繼續向舊master寫數據,這部分數據可能就丟失了。所以舊master再次恢復的加入到主從結構中時,會被做爲一個slave掛到新的master上去,本身的數據會清空,從新重新的master複製數據,原來的寫到舊master的數據就丟失了。
數據丟失的問題是不可避免的,可是咱們能夠儘可能減小。 在redis的配置文件裏設置參數
min-slaves-to-write 1
min-slaves-max-lag 10
複製代碼
min-slaves-to-write
默認狀況下是0,min-slaves-max-lag
默認狀況下是10。
上面的配置的意思是要求至少有1個slave,數據複製和同步的延遲不能超過10秒。若是說一旦全部的slave,數據複製和同步的延遲都超過了10秒鐘,那麼這個時候,master就不會再接收任何請求了。
上面兩個配置能夠減小異步複製和腦裂致使的數據丟失。
以上面配置爲例,這兩個參數表示至少有1個salve的與master的同步複製延遲不能超過10s,一旦全部的slave複製和同步的延遲達到了10s,那麼此時master就不會接受任何請求。
咱們能夠減少min-slaves-max-lag
參數的值,這樣就能夠避免在發生故障時大量的數據丟失,一旦發現延遲超過了該值就不會往master中寫入數據。
那麼對於client,咱們能夠採起降級措施,將數據暫時寫入本地緩存和磁盤中,在一段時間後從新寫入master來保證數據不丟失;也能夠將數據寫入kafka消息隊列,隔一段時間去消費kafka中的數據。
經過上面兩個參數的設置咱們儘量的減小數據的丟失,具體的值還須要在特定的環境下進行測試設置。
好的,今天回答的還不錯,下一輪面試繼續努力哦~
本系列文章在於面試突擊,不是教程,要是細挖,能講好多,而面試你只須要把這個原理說出來就好了,若是邊講邊畫圖那就更好了。
該系列文章在於快速突擊,快速拾遺,溫習。
關注公衆號 編程大道 ,第一時間獲文章推送。
以爲好看,請 點贊、關注、轉發 哦~