大廠面試Redis高頻15問:資料結構+持久化+叢集全覆蓋
涵蓋Redis資料結構、持久化、叢集、快取問題等15道大廠高頻面試題,每題含考察點與答案方向,助你全面備戰Redis面試。
背景介紹
Redis這塊我是真的踩過坑。之前在一家創業公司做專案,快取方案全靠自己摸索,出了好幾次線上事故——快取雪崩那次直接導致服務不可用半小時。後來跳槽準備大廠面試的時候,我花了兩週時間把Redis從資料結構到叢集方案全部梳理了一遍,整理出這15道最常考的題目。說實話,Redis面試的套路性很強,準備到位了基本都能答上來。
一、資料結構(4題)
1. Redis的5種基本資料型別及底層實現?
考察點:資料結構底層原理
String底層是SDS(Simple Dynamic String),相比C字串多了len和free欄位,O(1)獲取長度,二進位安全,支援動態擴容。List底層3.2版本前是ziplist+linkedlist,之後統一用quicklist(ziplist+雙向鏈表)。Hash底層ziplist或hashtable,元素少時用ziplist省記憶體。Set底層intset或hashtable,全是整數且數量少時用intset。ZSet底層ziplist或skiplist+hashtable。面試官最愛追問的是:什麼時候從ziplist轉換成其他結構?答案是元素數量或單個元素大小超過閾值時。
2. 跳表是什麼?為什麼Redis用跳表不用紅黑樹?
考察點:有序集合底層實現
跳表是一種多層鏈表結構,通過隨機層數實現O(logN)的查詢、插入、刪除。Redis用跳表而不用紅黑樹的原因:實現更簡單,程式碼可讀性好;範圍查詢更方便,鏈表結構天然支援順序遍歷;並發場景下更容易修改(雖然Redis是單執行緒)。跳表每個節點隨機生成1-32層,層越高機率越低。面試的時候我把跳表的查詢過程畫出來,面試官直接說「理解得很清楚」。
3. 壓縮列表(ziplist)是什麼?
考察點:記憶體優化機制
ziplist是一塊連續記憶體儲存的列表結構,為了節省記憶體設計的。每個entry包含prevlen(前一個節點長度,用於反向遍歷)和encoding(編碼方式)。優點是記憶體緊湊,快取友好;缺點是連鎖更新問題——中間某個節點長度變化可能導致後續所有節點的prevlen欄位都需要擴展。Redis 7.0用listpack替代了ziplist,解決了連鎖更新問題。這個細節面試官很愛問。
4. Redis Stream是什麼?
考察點:新資料結構瞭解
Stream是Redis 5.0引入的資料型別,類似於Kafka的訊息佇列設計。支援消費組、訊息確認、持久化,比Pub/Sub更可靠。核心概念:訊息ID(時間戳+序號)、Consumer Group、Pending Entries List(PEL)。適合輕量級訊息佇列場景,不需要引入Kafka或RabbitMQ。但要注意:Stream的訊息堆積會影響記憶體,需要設定MAXLEN限制。
二、持久化(3題)
5. RDB和AOF的區別?
考察點:持久化方案對比
RDB是二進位快照檔案,fork子程序生成,恢復速度快,但可能丟失最後一次快照後的資料。AOF是追加寫入的操作日誌,預設每秒fsync,資料安全性更高,但檔案體積大、恢復慢。RDB適合做冷備份,AOF適合做熱備份。面試官經常問:如果同時開啟RDB和AOF,Redis重啟時載入哪個?答案是AOF,因為AOF的資料更完整。
6. 混合持久化是什麼?
考察點:持久化優化方案
Redis 4.0引入混合持久化:AOF重寫時把RDB格式的資料寫在AOF檔案前面,後面的增量資料用AOF格式。這樣既保證了恢復速度(RDB部分載入快),又保證了資料完整性(AOF部分記錄增量)。混合持久化通過aof-use-rdb-preamble yes開啟。面試官追問:AOF重寫的過程是什麼?主程序fork子程序→子程序重寫→主程序同時將新命令寫入AOF重寫緩衝區→子程序完成後主程序將緩衝區資料追加到新AOF檔案→替換舊檔案。
7. 生產環境如何選擇持久化方案?
考察點:實際運維經驗
純快取場景可以關閉持久化,獲得最佳效能;需要資料安全性的場景推薦混合持久化;如果對資料丟失極度敏感,用AOF+每秒fsync。關鍵配置建議:RDB的save策略根據業務調整;AOF的fsync策略選everysec(兼顧效能和安全);開啟混合持久化;定期備份RDB檔案到遠端儲存。我之前在生產環境就是因為AOF檔案太大導致重啟恢復慢,後來開啟了混合持久化,恢復時間從30分鐘降到了2分鐘。
三、叢集(3題)
8. Redis主從複製原理?
考察點:高可用基礎架構
全量複製:從庫首次連線或斷開太久,主庫生成RDB發送給從庫,發送期間的新命令寫入replication buffer,RDB發送完後發送buffer中的命令。部分複製:從庫短暫斷開,主庫維護repl_backlog環形緩衝區,從庫攜帶offset請求增量資料。關鍵引數:repl-backlog-size預設1MB,建議調大到256MB以上避免頻繁全量複製。面試官會追問:主從延遲怎麼處理?讀寫分離時從庫可能讀到舊資料,關鍵業務可以強制讀主庫。
9. 哨兵模式原理?
考察點:自動故障轉移
哨兵叢集監控Redis主從節點,通過心跳檢測判斷主庫是否下線。主觀下線:單個哨兵認為主庫不可用;客觀下線:超過半數哨兵認為主庫不可用。故障轉移流程:選舉領頭哨兵→選擇新主庫(優先級>複製偏移量>runid最小)→通知從庫複製新主庫→通知客戶端新主庫地址。面試官最愛問:哨兵之間如何發現彼此?通過主庫的pub/sub頻道__sentinel__:hello互相發現。
10. Redis Cluster分片原理?
考察點:分散式架構
Redis Cluster有16384個雜湊槽,每個主節點負責一部分槽。key通過CRC16(key) % 16384計算所屬槽位。客戶端訪問時如果key不在當前節點,會返回MOVED重定向。叢集至少需要6個節點(3主3從)保證高可用。常見問題:叢集不支援多key操作(除非key在同一槽位,可以用hash tag解決);擴縮容需要手動遷移槽位。面試官追問:為什麼是16384個槽?因為節點間心跳包需要攜帶槽位資訊,16384個槽用2KB就能表示,更大的槽數會增加網路開銷。
四、應用(3題)
11. 快取穿透、擊穿、雪崩分別是什麼?怎麼解決?
考察點:快取常見問題
穿透:查詢不存在的資料,快取和資料庫都沒有,請求直達資料庫。解決方案:布隆過濾器、快取空值。擊穿:熱點key過期瞬間,大量請求打到資料庫。解決方案:互斥鎖、熱點key永不過期。雪崩:大量key同時過期或Redis宕機,請求全部打到資料庫。解決方案:過期時間加隨機值、Redis叢集高可用、限流降級。我之前遇到的線上事故就是雪崩——大量key同一時間過期,後來給過期時間加了隨機偏移量就解決了。
12. Redis分散式鎖怎麼實現?
考察點:分散式鎖方案
基礎方案:SET key value NX EX seconds,NX保證互斥,EX設定過期時間防止死鎖。釋放鎖時用Lua指令碼保證原子性(判斷value是否是自己設定的再刪除)。Redlock演算法:在多個獨立Redis例項上同時加鎖,超過半數成功才算獲取鎖。生產環境建議用Redisson框架,它封裝了看門狗機制自動續期,解決了鎖過期但業務未完成的問題。面試官追問:Redlock一定安全嗎?Martin Kleppmann曾發文質疑,認為在時鐘跳變等場景下不安全。這個爭議點了解即可。
13. Redis做訊息佇列怎麼做?
考察點:訊息佇列方案
三種方案:List+LPUSH/BRPOP實現簡單佇列,支援阻塞等待但不支援消費組;Pub/Sub支援多消費者但不持久化,訊息丟失無法恢復;Stream支援消費組、訊息確認、持久化,是Redis 5.0+推薦方案。選擇建議:簡單場景用List,需要發布訂閱用Pub/Sub,需要可靠訊息用Stream。但Redis做訊息佇列只適合輕量場景,量大了還是上Kafka或RabbitMQ。
五、其他(2題)
14. 記憶體淘汰策略有哪些?
考察點:記憶體管理機制
8種策略:noeviction(預設,不淘汰直接報錯);allkeys-lru(所有key中淘汰最近最少使用的);volatile-lru(過期key中淘汰LRU);allkeys-lfu(所有key中淘汰使用頻率最低的,Redis 4.0+);volatile-lfu(過期key中淘汰LFU);allkeys-random(隨機淘汰);volatile-random(過期key中隨機淘汰);volatile-ttl(淘汰剩餘時間最短的)。生產環境推薦allkeys-lru或allkeys-lfu。LFU比LRU更優,因為它考慮了訪問頻率而不只是最近訪問時間。
15. 過期刪除機制是什麼?
考察點:key過期處理
Redis採用惰性刪除+定期刪除雙重策略。惰性刪除:訪問key時才檢查是否過期,過期則刪除。定期刪除:每100ms隨機抽取一批設定了過期時間的key檢查,過期則刪除,如果過期key超過25%則繼續檢查。這種組合方式在CPU和記憶體之間做了平衡——如果只用惰性刪除,過期key長期不訪問會浪費記憶體;如果只用定期刪除,全量掃描太耗CPU。面試官可能追問:如果大量key同時過期會怎樣?定期刪除會持續執行多輪,可能影響正常請求的回應時間。
心得建議
Redis面試準備的關鍵是:資料結構要理解底層實現,不能只停留在「5種型別」的表面;持久化和叢集方案要結合實際運維經驗來答,最好能說出自己踩過的坑;快取問題(穿透/擊穿/雪崩)是必考題,解決方案要能脫口而出。另外,Redis 7.0的新特性(Function替代Lua指令碼、listpack替代ziplist、多AOF檔案)也值得關注,能體現你的技術前沿性。
FAQ
Q:Redis面試需要了解原始碼嗎?
不需要深入原始碼,但了解關鍵資料結構的實現(如SDS、跳表、ziplist)會非常加分。
Q:Redis單執行緒為什麼這麼快?
純記憶體操作、IO多路複用、避免上下文切換和鎖競爭。注意:Redis 6.0引入多執行緒處理網路IO,但命令執行仍是單執行緒。
Q:生產環境Redis怎麼監控?
重點關注:記憶體使用率、命中率、連線數、慢查詢、主從延遲。可以用Redis Exporter+Prometheus+Grafana搭建監控。