原文連接(有修改)面試
能堅持別人不能堅持的,才能擁有別人不曾擁有的。
關注 編程大道 公衆號,讓咱們一同堅持心中所想,一塊兒成長!!redis
《「面試突擊」— Redis篇》- Redis哨兵原理及持久化機制數據庫
在這個系列裏,我會整理一些面試題與你們分享,幫助想要在金三銀四準備跳槽的同窗鞏固、突擊面試官常問的一些面試題,加油!!編程
《【面試突擊】— Redis篇》--Redis數據類型?適用於哪些場景?緩存
《【面試突擊】— Redis篇》--Redis的線程模型瞭解嗎?爲啥單線程效率還這麼高?安全
《【面試突擊】— Redis篇》-- Redis的主從複製?哨兵機制?併發
前兩次由於時間緣由面試官暫時停止了面試,面試官以爲你對redis的主從複製,哨兵機制的知識掌握的還能夠,因而今天面試官想看看你到底對Redis瞭解有多深,又加大了攻勢,你準備好了嗎?app
上次由於時間問題面試草草收場今天我還有幾個哨兵的問題要問。首先說一下Redis Sentinel是怎麼工做的?重點描述一下故障轉移的過程
好的。分佈式
1)每一個Sentinel以每秒鐘一次的頻率向它所知的Master,Slave以及其餘 Sentinel 實例發送一個 PING 命令。高併發
2)若是一個實例(instance)距離最後一次有效回覆 PING 命令的時間超過 down-after-milliseconds 選項所指定的值, 則這個實例會被當前 Sentinel 標記爲主觀下線。
3)若是一個Master被標記爲主觀下線,則正在監視這個Master的全部 Sentinel 要以每秒一次的頻率確認Master的確進入了主觀下線狀態。
4)當有足夠數量的 Sentinel(大於等於配置文件指定的值)在指定的時間範圍內確認Master的確進入了主觀下線狀態, 則Master會被標記爲客觀下線 。
5)當Master被 Sentinel 標記爲客觀下線時,Sentinel 向下線的 Master 的全部 Slave 發送 INFO 命令的頻率會從 10 秒一次改成每秒一次 (在通常狀況下, 每一個 Sentinel 會以每 10 秒一次的頻率向它已知的全部Master,Slave發送 INFO 命令 )。
6)若沒有足夠數量的 Sentinel 贊成 Master 已經下線, Master 的客觀下線狀態就會變成主觀下線。若 Master 從新向 Sentinel 的 PING 命令返回有效回覆, Master 的主觀下線狀態就會被移除。
7)sentinel節點會與其餘sentinel節點進行「溝通」,投票選舉一個sentinel節點進行故障處理,在從節點中選取一個主節點,其餘從節點掛載到新的主節點上自動複製新主節點的數據。
故障轉移時會從剩下的slave選舉一個新的master,被選舉爲master的標準是什麼?
若是一個master被認爲odown了,並且majority哨兵都容許了主備切換,那麼某個哨兵就會執行主備切換操做,此時首先要選舉一個slave來,會考慮slave的一些信息。
(1)跟master斷開鏈接的時長。
若是一個slave跟master斷開鏈接已經超過了down-after-milliseconds的10倍,外加master宕機的時長,那麼slave就被認爲不適合選舉爲master.( down-after-milliseconds * 10) + milliseconds_since_master_is_in_SDOWN_state
(2)slave優先級。
按照slave優先級進行排序,slave priority越低,優先級就越高
(3)複製offset。
若是slave priority相同,那麼看replica offset,哪一個slave複製了越多的數據,offset越靠後,優先級就越高
(4)run id
若是上面兩個條件都相同,那麼選擇一個run id比較小的那個slave
執行切換的那個哨兵在完成故障轉移後會作什麼?
會進行configuraiton配置信息傳播。
哨兵完成切換以後,會在本身本地更新生成最新的master配置,而後經過pub/sub消息機制同步給其餘的哨兵。
同步配置的時候其餘哨兵根據什麼更新本身的配置呢?
執行切換的那個哨兵,會從要切換到的新master(salve->master)那裏獲得一個configuration epoch,這就是一個version號,每次切換的version號都必須是惟一的。
若是第一個選舉出的哨兵切換失敗了,那麼其餘哨兵,會等待failover-timeout時間,而後接替繼續執行切換,此時會從新獲取一個新的configuration epoch 做爲新的version號。
這個version號就很重要了,由於各類消息都是經過一個channel去發佈和監聽的,因此一個哨兵完成一次新的切換以後,新的master配置是跟着新的version號的,其餘的哨兵都是根據版本號的大小來更新本身的master配置的。
好,上次哨兵的問題暫時就到這吧,接下來講說redis的持久化方面的問題吧。首先,生產上Redis要不要持久化?若是要,說說爲何須要,或者說持久化對生產系統的意義何在?
要。
redis持久化主要是作災難恢復,數據恢復,也能夠歸類到高可用的範疇。
好比Redis整個掛了,致使Redis不可用了,這時候首先要作的事情是讓Redis儘快變得可用。那麼就會去重啓Redis,儘快讓它對外提供服務。可是若是沒作持久化沒有數據備份,這個時候Redis啓動了,也不可用啊,數據都沒了!
這時候極可能,大量的請求過來,在緩存所有沒法命中,這個時候就死定了,可能會致使緩存雪崩問題,全部的請求,沒有在Redis命中,就會去數據庫中去找,數據庫一會兒承接高併發,而後就掛了。數據庫掛掉,你都無法去找數據恢復到redis裏面去。
Redis持久化機制有哪些?
Redis有兩種持久化機制,AOF和RDB。
AOF
,記錄每次寫請求的命令,以追加的方式在文件尾部追加,直接在尾部追加,效率比較高。
對於操做系統來講,不是每次寫都直接寫到磁盤,操做系統本身會有一層cache,redis寫磁盤的數據會先緩存在os cache裏,redis每隔1秒調用一次操做系統的fsync操做,強制將os cache中的數據刷入AOF文件中。
當redis重啓的時候,就把AOF中記錄的命令從新執行一遍就能夠了,可是若是文件很大的話,執行會耗費較多的時間,對於數據恢復來講耗時會多一點。
RDB
,是快照文件,每隔必定時間將redis內存中的數據生成一份完整的RDB快照文件,當redis重啓的時候直接加載數據便可,一樣的數據比AOF恢復的要快。
說說這兩種持久化機制各自的特色、優缺點吧
好的。
RDB的優勢
第一點就是他會生成多個數據文件,每一個數據文件都表明了某一時刻redis中的數據,很是適合作冷備。
第二點,RDB持久化機制對redis對外提供的讀寫服務影響很是小,可讓redis保持高性能,由於redis主進程只須要fork一個子進程,讓子進程執行磁盤IO操做來進行RDB持久化便可。
第三點,相對於AOF持久化機制來講,直接基於RDB數據文件來重啓和恢復redis進程,更加快速。
AOF,存放的指令日誌,作數據恢復的時候,實際上是要回放和執行全部的指令日誌,來恢復出來內存中的全部數據的。
RDB,就是一份數據文件,恢復的時候,直接加載到內存中便可。
RBD的缺點
1)故障時可能數據丟失的比AOF要多。通常來講,RDB數據快照文件,都是每隔5分鐘或者更長時間生成一次,這個時候一旦redis進程宕機,那麼會丟失最近5分鐘的數據。
這個問題,也是rdb最大的缺點,就是不適合作第一優先的恢復方案,若是你依賴RDB作第一優先恢復方案,會致使數據丟失的比較多
2)RDB每次在fork子進程來執行RDB快照數據文件生成的時候,若是數據文件特別大,可能會致使對客戶端提供的服務暫停數毫秒,或者甚至數秒。
因此通常不要讓RDB的間隔太長,不然每次生成的RDB文件太大了,對redis自己的性能可能會有影響的。
AOF的優勢
1)AOF能夠更好的保護數據不丟失
通常AOF會每隔1秒,經過一個後臺線程執行一次fsync操做,最多丟失1秒鐘的數據。
每隔1秒,就執行一次fsync操做,保證os cache中的數據寫入磁盤中。
redis進程掛了,最多丟掉1秒鐘的數據.
2)AOF持久化性能高
AOF日誌文件以append-only模式寫入,因此沒有任何磁盤尋址的開銷,寫入性能很是高,並且文件不容易破損,即便文件尾部破損,也很容易修復。
3)AOF日誌文件即便過大的時候,出現後臺重寫操做,也不會影響客戶端的讀寫。
由於在rewrite log的時候,會對其中的指令進行壓縮,建立出一份須要恢復數據的最小日誌出來。在建立新日誌文件的時候,老的日誌文件仍是照常寫入。當新的merge後的日誌文件ready的時候,再交換新老日誌文件便可。
4)AOF日誌文件的命令經過很是可讀的方式進行記錄,這個特性很是適合作災難性的誤刪除的緊急恢復。
好比某人不當心用flushall命令清空了全部數據,只要這個時候後臺rewrite尚未發生,那麼就能夠當即拷貝AOF文件,將最後一條flushall命令給刪了,而後再將該AOF文件放回去,就能夠經過恢復機制,自動恢復全部數據。
AOF的缺點
(1)對於同一份數據來講,AOF日誌文件一般比RDB數據快照文件更大
(2)AOF開啓後,支持的寫QPS會比RDB支持的寫QPS低,由於AOF通常會配置成每秒fsync一第二天志文件,固然,每秒一次fsync,性能也仍是很高的。
若是你要保證一條數據都不丟,也是能夠的,AOF的fsync設置成沒寫入一條數據,fsync一次,可是那樣致使redis的QPS大幅度降低。
(3)之前AOF發生過bug,就是經過AOF記錄的日誌,進行數據恢復的時候,沒有恢復如出一轍的數據出來。
因此說,相似AOF這種較爲複雜的基於命令日誌/merge/回放的方式,比基於RDB每次持久化一份完整的數據快照文件的方式,更加脆弱一些,容易有bug。不過AOF就是爲了不rewrite過程致使的bug,所以每次rewrite並非基於舊的指令日誌進行merge的,而是基於當時內存中的數據進行指令的從新構建,這樣健壯性會好不少。
(4)惟一的比較大的缺點,其實就是作數據恢復的時候,會比較慢,作冷備不太合適。
你剛纔提到冷備,那你具體說說爲啥AOF不適合RDB適合?
其實兩個均可以作,只不過RDB更適合。
RDB能夠作冷備,是由於它會生成多個文件,每一個文件都表明了某一個時刻的完整的數據快照,咱們能夠將這種完整的數據文件發送到一些遠程的安全存儲上去,好比能夠是阿里雲的ODPS分佈式存儲上,以預約好的備份策略來按期備份redis中的數據。
AOF也能夠作冷備,只不過它只有一個文件,可是咱們能夠去本身寫程序,每隔必定時間,去copy一份這個文件出來。
RDB作冷備,優點在於由redis去控制固定時長生成快照文件的事情,比較方便,而 AOF,還須要咱們本身寫一些腳本去作這個事情,各類定時,比較麻煩。
RDB數據作冷備,在最壞的狀況下,提供數據恢復的時候,速度比AOF快。
說了那麼多AOF和RDB,那麼生產系統對於這倆持久化機制到底該如何選擇呢?
至於,RDB和AOF到底該如何選擇,我以爲兩種都選擇,
1)不要僅僅使用RDB,由於那樣會致使你丟失不少數據。
2)也不要僅僅使用AOF,由於那樣有兩個問題,
第一,你經過AOF作冷備,沒有RDB作冷備,來的恢復速度更快;
第二,RDB每次簡單粗暴生成數據快照,更加健壯,能夠避免AOF這種複雜的備份和恢復機制的bug。
3)綜合使用AOF和RDB兩種持久化機制,用AOF來保證數據不丟失,做爲數據恢復的第一選擇; 用RDB來作不一樣程度的冷備,在AOF文件都丟失或損壞不可用的時候,還可使用RDB來進行快速的數據恢復,做爲數據恢復的最後一道防線。
好,今天就到這裏,下次咱們繼續聊
終於結束了。
其實若是你的簡歷上寫了掌握Redis,那麼若是面試官也比較精通Redis的話,他就會抓住你這一個Redis從淺入深的一直追着問,看看你到底對Redis瞭解多少,是否是平時本身真的積累過這些知識,是否是比別人要懂得多一點,通過一層一層的深挖,看看你能過幾關。相對於其餘競爭者可能幾個回合就招架不住了,你要是能多戰幾個回合,面試官對你的印象也會越深,你的機會也就越大。
若是說就redis問你幾個基礎的問題,那面試官要麼對redis瞭解很少,要麼就看中了你簡歷中的其餘亮點。
小建議: 還有一點要說,面試不要只是技術名詞的羅列,能夠具體到某個技術的技術點,如:熟悉redis線程模型、持久化機制
(固然你要真的瞭解再這樣寫)。比你只寫熟悉redis
要強,這樣面試官也能知道要問你啥,有方向。否則就只是羅列技術名詞,太普遍了,面試官都不知道問你啥,隨便問的話你不會不就尷尬了。你寫上你熟悉具體的某個知識點,就不那麼被動了。固然免不了會有面試官專門問你簡歷上沒寫的。。。
本系列文章在於面試突擊,不是教程,要是細挖能講好多,而面試你只須要把這個原理說出來就好了,若是邊講邊畫圖那就更好了。該系列文章在於快速突擊,快速拾遺,溫習。
以爲好看,請點贊哦~
關注公衆號 編程大道 ,第一時間獲文章推送。
以爲好看,請 點贊、關注、轉發 哦~