redis面試實錄
小張:
面試官,你好。我是來參加面試的。
面試官:
你好,小張。我看了你的簡歷,熟練掌握redis,那麼我就隨便問你幾個redis相關的問題吧。首先我的問題是,redis是單執行緒還是多執行緒呢?
小張:
redis不同版本之間採用的執行緒模型是不一樣的,在redis4.0版本之前使用的是單執行緒模型,在4.0版本之後增加了多執行緒的支援。
在4.0之前雖然我們說redis是單執行緒,也只是說它的網路i/o執行緒以及set 和 get操作是由乙個執行緒完成的。但是redis的持久化、集群同步還是使用其他執行緒來完成。
4.0之後新增了多執行緒的支援,主要是體現在大資料的非同步刪除功能上,例如 `unlink key`、`flushdb async`、`flushall async` 等
面試官:
回答的很好,那為什麼redis在4.0之前會選擇使用單執行緒?而且使用單執行緒還那麼快?
小張:
選擇單執行緒個人覺得主要是使用簡單,不存在鎖競爭,可以在無鎖的情況下完成所有操作,不存在死鎖和執行緒切換帶來的效能和時間上的開銷,但同時單執行緒也不能完全發揮出多核cpu的效能。
至於為什麼單執行緒那麼快我覺得主要有以下幾個原因:
1. redis 的大部分操作都在記憶體中完成,記憶體中的執行效率本身就很快,並且採用了高效的資料結構,比如雜湊表和跳表。
2. 使用單執行緒避免了多執行緒的競爭,省去了多執行緒切換帶來的時間和效能開銷,並且不會出現死鎖。
3. 採用 i/o 多路復用機制處理大量客戶端的socket請求,因為這是基於非阻塞的 i/o 模型,這就讓redis可以高效地進行網路通訊,i/o的讀寫流程也不再阻塞。
面試官:
不錯,那redis是如何實現資料不丟失的呢?
小張:
redis資料是儲存在記憶體中的,為了保證redis資料不丟失,那就要把資料從記憶體儲存到磁碟上,以便在伺服器重啟後還能夠從磁碟中恢復原有資料,這就是redis的資料持久化。redis資料持久化有三種方式。
>> rdb 快照(redis database):將某乙個時刻的記憶體資料,以二進位制的方式寫入磁碟。
>> 混合持久化方式:redis 4.0 新增了混合持久化的方式,整合了 rdb 和 aof 的優點。
面試官:
那你分別說說aof和 rdb的實現原理吧。
小張:
aof採用的是寫後日誌的方式,redis先執行命令把資料寫入記憶體,然後再記錄日誌到檔案中。aof日誌記錄的是操作命令,不是實際的資料,如果採用aof方法做故障恢復時需要將全量日誌都執行一遍。
rdb採用的是記憶體快照的方式,它記錄的是某一時刻的資料,而不是操作,所以採用rdb方法做故障恢復時只需要直接把rdb檔案讀入記憶體即可,實現快速恢復。
面試官:
你剛提到了aof採用的是 「寫後日誌」 的方式,我們平時用的mysql則採用的是 「寫前日誌」,那redis為什麼要先執行命令,再把資料寫入日誌呢?
小張:額頭開始冒汗,問的是些啥問題呀。。。
額,這個主要是由於redis在寫入日誌之前,不對命令進行語法檢查,所以只記錄執行成功的命令,避免出現記錄錯誤命令的情況,而且在命令執行後再寫日誌不會阻塞當前的寫操作。
面試官:
那後寫日誌又有什麼風險呢?
小張:
我... 這個我不會。
面試官:
好吧,後寫日誌主要有兩個風險可能會發生:
我還有個問題是rdb做快照時會阻塞執行緒嗎?
小張:
redis 提供了兩個命令來生成 rdb 快照檔案,分別是 `s**e` 和 `bgs**e`。`s**e` 命令在主線程中執行,會導致阻塞。而 `bgs**e` 命令則會建立乙個子程序,用於寫入 rdb 檔案的操作,避免了對主線程的阻塞,這也是 redis rdb 的預設配置。
面試官:
rdb 做快照的時候資料能修改嗎?
小張:
s**e是同步的會阻塞客戶端命令,bgs**e的時候是可以修改的。
面試官:
那redis是怎麼解決在bgs**e做快照的時候允許資料修改呢?
小張:(你咋還問。。。我™不會啊!)
額,這個我不太清楚...
面試官:
這裡主要是利用bgs**e
的子執行緒實現的,具體操作如下:
要注意,redis 對 rdb 的執行頻率非常重要,因為這會影響快照資料的完整性以及 redis 的穩定性,所以在 redis 4.0 後,增加了 aof 和 rdb 混合的資料持久化機制:把資料以 rdb 的方式寫入檔案,再將後續的操作命令以 aof 的格式存入檔案,既保證了 redis 重啟速度,又降低資料丟失風險。
小張:
學到了學到了。
面試官:
那你再跟我說說redis如何實現高可用吧?
小張:
redis實現高可用主要有三種方式:主從複製、哨兵模式,以及 redis 集群。
主從複製
將從前的一台 redis 伺服器,同步資料到多台從 redis 伺服器上,即一主多從的模式,這個跟mysql主從複製的原理一樣。
圖1 主從複製
哨兵模式
使用 redis 主從服務的時候,會有乙個問題,就是當 redis 的主從伺服器出現故障宕機時,需要手動進行恢復,為了解決這個問題,redis 增加了哨兵模式(因為哨兵模式做到了可以監控主從伺服器,並且提供自動容災恢復的功能)。
圖2 哨兵模式
redis cluster(集群)
redis cluster 是一種分布式去中心化的執行模式,是在 redis 3.0 版本中推出的 redis 集群方案,它將資料分布在不同的伺服器上,以此來降低系統對單主節點的依賴,從而提高 redis 服務的讀寫效能。
圖3 redis cluster(集群)
面試官:
使用哨兵模式在資料上有副本資料做保證,在可用性上又有哨兵監控,一旦master死機會選舉salve節點為master節點,這種已經滿足了我們的生產環境需要,那為什麼還需要使用集群模式呢?
小張:
額,哨兵模式歸根節點還是主從模式,在主從模式下我們可以通過增加salve節點來擴充套件讀併發能力,但是沒辦法擴充套件寫能力和儲存能力,儲存能力只能是master節點能夠承載的上限。所以為了擴充套件寫能力和儲存能力,我們就需要引入集群模式。
面試官:
集群中那麼多master節點,redis cluster在儲存的時候如何確定選擇哪個節點呢?
小張:
這應該是使用了某種hash演算法,但是我不太清楚。。。
面試官:
那好,今天的面試就到這裡吧,你先回去等我們的面試通知。
小張:
好的,謝謝面試官,你能告訴我redis cluster怎麼實現節點擊擇的嗎?
面試官:
redis cluster採用的是類一致性雜湊演算法實現節點擊擇的,至於什麼是一致性雜湊演算法你自己回去看看。
redis cluster將自己分成了16384個slot(槽位),雜湊槽類似於資料分割槽,每個鍵值對都會根據它的 key,被對映到乙個雜湊槽中,具體執行過程分為兩大步。
每個redis節點負責處理一部分槽位,加入你有三個master節點 abc,每個節點負責的槽位如下:
節點處理槽位
a0-5000
b5001 - 10000
c10001 - 16383
這樣就實現了cluster節點的選擇。
以上文章**於j**a日知錄 ,作者飄渺jam
redis面試 redis熱資料
mysql裡有2000w資料,redis中只存20w的資料,如何保證redis中的資料都是熱點資料?redis 記憶體資料集大小上公升到一定大小的時候,就會施行資料淘汰策略。redis 提供 6種資料淘汰策略 volatile lru 從已設定過期時間的資料集 server.db i expires...
redis面試總結
1.redis怎麼保證原子性 redis 是單執行緒的事件迴圈,乙個操作執行完了才執行下乙個操作 2.redis常用的資料結構 資料型別 高頻問點,熟!字串 string 列表 list 無序集合 zset 有序集合 set 雜湊表 hash 3.redis執行緒安全嗎 redis採用了執行緒封閉的...
Redis 面試準備
redis資料庫中的所有資料都儲存在記憶體中。由於記憶體的讀寫速度遠快於硬碟,因此redis的的的在效能上對比其他基於硬碟儲存的資料庫有非常明顯的優勢。資料雖在記憶體,但是提供了持久化的支援,即可以將記憶體中的資料非同步寫入到硬碟中,同時不影響繼續提供服務 為什麼快 一 純記憶體操作 二 單執行緒操...