Redis緩存那點破事 | 絕殺面試官 25 問!
時間:2021-10-21 14:37:34
手機看文章
掃描二維碼
隨時隨地手機看文章
[導讀]為了便于大家查找問題,了解全貌,整理個目錄,我們可以快速全局了解關于Redis緩存,面試官一般喜歡問哪些問題?接下來,我們逐條來看看每個問題及答案Redis有哪些特性?答案:性能高,讀的速度是100000次/s,寫的速度是80000次/s數據持久化,支持RDB、AOF支持事務。通...
為了便于大家查找問題,了解全貌,整理個目錄,我們可以快速全局了解關于Redis 緩存,面試官一般喜歡問哪些問題?
接下來,我們逐條來看看每個問題及答案
Redis 有哪些特性?答案:
Redis 為什么這么快?答案:
Redis 底層的基礎數據結構有哪些?答案:
Redis 支持哪些數據類型?答案:五種常用數據類型:
Redis 常用的 5 種數據結構和應用場景?答案:
為什么采用單線程?答案:官方回復,CPU不會成為Redis的制約瓶頸,Redis主要受內存、網絡限制。例如,在一個普通的 Linux 系統(tǒng)上,使用pipelining 可以每秒傳遞 100 萬個請求,所以如果您的應用程序主要使用 O(N) 或 O(log(N)) 命令,則幾乎不會使用太多 CPU,屬于IO密集型系統(tǒng)。
Redis 6.0 之后又改用多線程呢?答案:Redis的多線程主要是處理數據的讀寫、協(xié)議解析。執(zhí)行命令還是采用單線程順序執(zhí)行。主要是因為redis的性能瓶頸在于網絡IO而非CPU,使用多線程進行一些周邊預處理,提升了IO的讀寫效率,從而提高了整體的吞吐量。antirez 在 RedisConf 2019 分享時提到,Redis 6 引入的多線程 IO 對性能提升至少一倍以上。
過期鍵Key 的刪除策略有哪些?答案:有3種過期刪除策略。惰性刪除、定期刪除、定時刪除
如果Redis的內存空間不足,淘汰機制?答案:
Redis 突然掛了怎么解決?答案:1、從系統(tǒng)可用性角度思考,Redis Cluster引入主備機制,當主節(jié)點掛了后,自動切換到備用節(jié)點,繼續(xù)提供服務。2、Client端引入本地緩存,通過開關切換,避免Redis突然掛掉,高并發(fā)流量把數據庫打掛。
Redis 持久化有哪些方式?答案:1、快照RDB。將某個時間點上的數據庫狀態(tài)保存到
Redis 常用場景答案:
Redis 緩存要注意的七大經典問題?答案:列舉了億級系統(tǒng),高訪問量情況下Redis緩存可能會遇到哪些問題?以及對應的解決方案。
Redis 集群方案有哪幾種?答案:
Redis 主從數據同步(主從復制)的過程?答案:
主從復制的優(yōu)缺點?答案:1、優(yōu)點:
Sentinel(哨兵)模式的優(yōu)缺點?答案:哨兵模式基于主從復制模式,增加了哨兵來監(jiān)控與自動處理故障。1、優(yōu)點:
Redis Cluster 模式的優(yōu)缺點?答案:實現(xiàn)了Redis的分布式存儲,即每臺節(jié)點存儲不同的內容,來解決在線擴容的問題。1、優(yōu)點:
Redis 如何做擴容?答案:為了避免數據遷移失效,通常使用
Redis 的集群原理?答案:一個redis集群由多個節(jié)點node組成,而多個node之間通過
Redis 如何做到高可用?答案:哨兵機制。具有自動故障轉移、集群監(jiān)控、消息通知等功能。哨兵可以同時監(jiān)視所有的主、從服務器,當某個master下線時,自動提升對應的slave為master,然后由新master對外提供服務。
什么是 Redis 事務?答案:Redis事務是一組命令的集合,將多個命令打包,然后把這些命令按順序添加到隊列中,并且按順序執(zhí)行這些命令。Redis事務中沒有像Mysql關系型數據庫事務隔離級別的概念,不能保證原子性操作,也沒有像Mysql那樣執(zhí)行事務失敗會進行回滾操作
Redis 事務執(zhí)行流程?答案:通過
Redis 與 Guava 、Caffeine 有什么區(qū)別?答案:緩存分為本地緩存和分布式緩存。1、Caffeine、Guava,屬于本地緩存,特點:
如何實現(xiàn)一個分布式鎖?答案:
接下來,我們逐條來看看每個問題及答案
Redis 有哪些特性?答案:
- 性能高, 讀的速度是100000次/s,寫的速度是80000次/s
- 數據持久化,支持RDB 、AOF
- 支持事務。通過
MULTI和EXEC指令包起來。 - 多種數據結構類型
- 主從復制
- 其他特性:發(fā)布/訂閱、通知、key過期等
Redis 為什么這么快?答案:
- 完全基于內存,沒有磁盤IO上的開銷,異步持久化除外
- 單線程,避免多個線程切換的性能損耗
- 非阻塞的IO多路復用機制
- 底層的數據存儲結構優(yōu)化,使用原生的數據結構提升性能。
Redis 底層的基礎數據結構有哪些?答案:
- 字符串。沒有采用C語言的傳統(tǒng)字符串,而是自己實現(xiàn)的一個簡單動態(tài)字符串SDS的抽象類型,并保存了長度信息。
- 鏈表(linkedlist)。雙向無環(huán)鏈表結構,每個鏈表的節(jié)點由一個listNode結構來表示,每個節(jié)點都有前置和后置節(jié)點的指針
- 字典(hashtable)。保存鍵值對的抽象數據結構,底層使用hash表,每個字典帶有兩個hash表,供平時使用和rehash時使用。
- 跳躍表(skiplist)。跳躍表是有序集合的底層實現(xiàn)之一。redis跳躍表由zskiplist和zskiplistNode組成,zskiplist用于保存跳躍表 信息(表頭、表尾節(jié)點、?度等),zskiplistNode用于表示表跳躍節(jié)點,每個跳躍表的層高都是1- 32的隨機數,在同一個跳躍表中,多個節(jié)點可以包含相同的分值,但是每個節(jié)點的成員對象必須是唯一的,節(jié)點按照分值大小排序,如果分值相同,則按照成員對象的大小排序。
- 整數集合(intset)。用于保存整數值的集合抽象數據結構,不會出現(xiàn)重復元素,底層實現(xiàn)為數組。
- 壓縮列表(ziplist)。為節(jié)約內存而開發(fā)的順序性數據結構,可以包含多個節(jié)點,每個節(jié)點可以保存一個字節(jié)數組或者整數值。
Redis 支持哪些數據類型?答案:五種常用數據類型:
String、Hash、Set、List、SortedSet。三種特殊的數據類型:Bitmap、HyperLogLog、Geospatial,其中Bitmap 、HyperLogLog的底層都是 String 數據類型,Geospatial 底層是 Sorted Set 數據類型。- 字符串對象string:int整數、embstr編碼的簡單動態(tài)字符串、raw簡單動態(tài)字符串
- 列表對象list:ziplist、linkedlist
- 哈希對象hash:ziplist、hashtable
- 集合對象set:intset、hashtable
- 有序集合對象zset:ziplist、skiplist
Redis 常用的 5 種數據結構和應用場景?答案:
- String:緩存、計數器、分布式鎖等
- List:鏈表、隊列、微博關注人時間軸列表等
- Hash:用戶信息、Hash 表等
- Set:去重、贊、踩、共同好友等
- Zset:訪問量排行榜、點擊量排行榜等
為什么采用單線程?答案:官方回復,CPU不會成為Redis的制約瓶頸,Redis主要受內存、網絡限制。例如,在一個普通的 Linux 系統(tǒng)上,使用pipelining 可以每秒傳遞 100 萬個請求,所以如果您的應用程序主要使用 O(N) 或 O(log(N)) 命令,則幾乎不會使用太多 CPU,屬于IO密集型系統(tǒng)。
Redis 6.0 之后又改用多線程呢?答案:Redis的多線程主要是處理數據的讀寫、協(xié)議解析。執(zhí)行命令還是采用單線程順序執(zhí)行。主要是因為redis的性能瓶頸在于網絡IO而非CPU,使用多線程進行一些周邊預處理,提升了IO的讀寫效率,從而提高了整體的吞吐量。antirez 在 RedisConf 2019 分享時提到,Redis 6 引入的多線程 IO 對性能提升至少一倍以上。
過期鍵Key 的刪除策略有哪些?答案:有3種過期刪除策略。惰性刪除、定期刪除、定時刪除
- 惰性刪除。使用key時才進行檢查,如果已經過期,則刪除。缺點:過期的key如果沒有被訪問到,一直無法刪除,一直占用內存,造成空間浪費。
- 定期刪除。每隔一段時間做一次檢查,刪除過期的key,每次只是隨機取一些key去檢查。
- 定時刪除。為每個key設置過期時間,同時創(chuàng)建一個定時器。一旦到期,立即執(zhí)行刪除。缺點:如果過期鍵比較多時,占用CPU較多,對服務的性能有很大影響。
如果Redis的內存空間不足,淘汰機制?答案:
- volatile-lru:從已設置過期時間的key中,移出最近最少使用的key進行淘汰
- allkeys-lru:當內存不足以容納新寫入數據時,在鍵空間中,移除最近最少使用的key(這個是最常用的)
- volatile-ttl:從已設置過期時間的key中,移出將要過期的key
- volatile-random:從已設置過期時間的key中,隨機選擇key淘汰
- allkeys-random:從key中隨機選擇key進行淘汰
- no-eviction:禁止淘汰數據。當內存達到閾值的時候,新寫入操作報錯
- volatile-lfu:從已設置過期時間的數據集(server.db[i].expires)中挑選最不經常使用的數據淘汰(LFU(Least Frequently Used)算法,也就是最頻繁被訪問的數據將來最有可能被訪問到)
- allkeys-lfu:當內存不足以容納新寫入數據時,在鍵空間中,移除最不經常使用的key。
Redis 突然掛了怎么解決?答案:1、從系統(tǒng)可用性角度思考,Redis Cluster引入主備機制,當主節(jié)點掛了后,自動切換到備用節(jié)點,繼續(xù)提供服務。2、Client端引入本地緩存,通過開關切換,避免Redis突然掛掉,高并發(fā)流量把數據庫打掛。
Redis 持久化有哪些方式?答案:1、快照RDB。將某個時間點上的數據庫狀態(tài)保存到
RDB文件中,RDB文件是一個壓縮的二進制文件,保存在磁盤上。當Redis崩潰時,可用于恢復數據。通過SAVE或BGSAVE來生成RDB文件。- SAVE:會阻塞redis進程,直到RDB文件創(chuàng)建完畢,在進程阻塞期間,redis不能處理任何命令請求。
- BGSAVE:會fork出一個子進程,然后由子進程去負責生成RDB文件,父進程還可以繼續(xù)處理命令請求,不會阻塞進程。
Redis 常用場景答案:
- 1、緩存,有句話說的好,「性能不夠,緩存來湊」
- 2、分布式鎖,利用Redis 的 setnx
- 3、分布式session
- 4、計數器,通過incr命令
- 5、排行榜,Redis 的 有序集合
- 6、其他
Redis 緩存要注意的七大經典問題?答案:列舉了億級系統(tǒng),高訪問量情況下Redis緩存可能會遇到哪些問題?以及對應的解決方案。
- 1、緩存集中失效
- 2、緩存穿透
- 3、緩存雪崩
- 4、緩存熱點
- 5、緩存大Key
- 6、緩存數據的一致性
- 7、數據并發(fā)競爭預熱
Redis 集群方案有哪幾種?答案:
- 主從復制模式
- Sentinel(哨兵)模式
- Redis Cluster模式
Redis 主從數據同步(主從復制)的過程?答案:
- 1、slave啟動后,向master發(fā)送sync命令
- 2、master收到sync之后,執(zhí)行bgsave保存快照,生成RDB全量文件
- 3、master把slave的寫命令記錄到緩存
- 4、bgsave執(zhí)行完畢之后,發(fā)送RDB文件到slave,slave執(zhí)行
- 5、master發(fā)送緩沖區(qū)的寫命令給slave,slave接收命令并執(zhí)行,完成復制初始化。
- 6、此后,master每次執(zhí)行一個寫命令都會同步發(fā)送給slave,保持master與slave之間數據的一致性
主從復制的優(yōu)缺點?答案:1、優(yōu)點:
- master能自動將數據同步到slave,可以進行讀寫分離,分擔master的讀壓力
- master、slave之間的同步是以非阻塞的方式進行的,同步期間,客戶端仍然可以提交查詢或更新請求
- 不具備自動容錯與恢復功能,master 節(jié)點宕機后,需要手動指定新的 master
- master宕機,如果宕機前數據沒有同步完,則切換IP后會存在數據不一致的問題
- 難以支持在線擴容,Redis的容量受限于單機配置
Sentinel(哨兵)模式的優(yōu)缺點?答案:哨兵模式基于主從復制模式,增加了哨兵來監(jiān)控與自動處理故障。1、優(yōu)點:
- 哨兵模式基于主從復制模式,所以主從復制模式有的優(yōu)點,哨兵模式也有
- master 掛掉可以自動進行切換,系統(tǒng)可用性更高
- Redis的容量受限于單機配置
- 需要額外的資源來啟動sentinel進程
Redis Cluster 模式的優(yōu)缺點?答案:實現(xiàn)了Redis的分布式存儲,即每臺節(jié)點存儲不同的內容,來解決在線擴容的問題。1、優(yōu)點:
- 無中心架構,數據按照slot分布在多個節(jié)點
- 集群中的每個節(jié)點都是平等的,每個節(jié)點都保存各自的數據和整個集群的狀態(tài)。每個節(jié)點都和其他所有節(jié)點連接,而且這些連接保持活躍,這樣就保證了我們只需要連接集群中的任意一個節(jié)點,就可以獲取到其他節(jié)點的數據。
- 可線性擴展到1000多個節(jié)點,節(jié)點可動態(tài)添加或刪除
- 能夠實現(xiàn)自動故障轉移,節(jié)點之間通過
gossip協(xié)議交換狀態(tài)信息,用投票機制完成slave到master的角色轉換
- 數據通過異步復制,不保證數據的強一致性
- slave充當 “冷備”,不對外提供讀、寫服務,只作為故障轉移使用。
- 批量操作限制,目前只支持具有相同slot值的key執(zhí)行批量操作,對mset、mget、sunion等操作支持不友好
- key事務操作支持有限,只支持多key在同一節(jié)點的事務操作,多key分布在不同節(jié)點時無法使用事務功能
- 不支持多數據庫空間,一臺redis可以支持16個db,集群模式下只能使用一個,即
db 0。Redis Cluster模式不建議使用pipeline和multi-keys操作,減少max redirect產生的場景。
Redis 如何做擴容?答案:為了避免數據遷移失效,通常使用
一致性哈希實現(xiàn)動態(tài)擴容縮容,有效減少需要遷移的Key數量。但是Cluster 模式,采用固定Slot槽位方式(16384個),對每個key計算CRC16值,然后對16384取模,然后根據slot值找到目標機器,擴容時,我們只需要遷移一部分的slot到新節(jié)點即可。Redis 的集群原理?答案:一個redis集群由多個節(jié)點node組成,而多個node之間通過
cluster meet命令來進行連接,組成一個集群。數據存儲通過分片的形式,整個集群分成了16384個slot,每個節(jié)點負責一部分槽位。整個槽位的信息會同步到所有節(jié)點中。key與slot的映射關系:- 健值對 key,進行
CRC16計算,計算出一個 16 bit 的值 - 將 16 bit 的值對 16384 取模,得到 0 ~ 16383 的數表示 key 對應的哈希槽
Redis 如何做到高可用?答案:哨兵機制。具有自動故障轉移、集群監(jiān)控、消息通知等功能。哨兵可以同時監(jiān)視所有的主、從服務器,當某個master下線時,自動提升對應的slave為master,然后由新master對外提供服務。
什么是 Redis 事務?答案:Redis事務是一組命令的集合,將多個命令打包,然后把這些命令按順序添加到隊列中,并且按順序執(zhí)行這些命令。Redis事務中沒有像Mysql關系型數據庫事務隔離級別的概念,不能保證原子性操作,也沒有像Mysql那樣執(zhí)行事務失敗會進行回滾操作
Redis 事務執(zhí)行流程?答案:通過
MULTI、EXEC、WATCH等命令來實現(xiàn)事務機制,事務執(zhí)行過程將一系列多個命令按照順序一次性執(zhí)行,在執(zhí)行期間,事務不會被中斷,也不會去執(zhí)行客戶端的其他請求,直到所有命令執(zhí)行完畢。具體過程:- 服務端收到客戶端請求,事務以
MULTI開始 - 如果正處于事務狀態(tài)時,則會把后續(xù)命令放入隊列同時返回給客戶端
QUEUED,反之則直接執(zhí)行這 個命令 - 當收到客戶端的
EXEC命令時,才會將隊列里的命令取出、順序執(zhí)行,執(zhí)行完將當前狀態(tài)從事務狀態(tài)改為非事務狀態(tài) - 如果收到
DISCARD命令,放棄執(zhí)行隊列中的命令,可以理解為Mysql的回滾操作,并且將當前的狀態(tài)從事務狀態(tài)改為非事務狀態(tài)
WATCH 監(jiān)視某個key,該命令只能在MULTI命令之前執(zhí)行。如果監(jiān)視的key被其他客戶端修改,EXEC將會放棄執(zhí)行隊列中的所有命令。UNWATCH 取消監(jiān)視之前通過WATCH 命令監(jiān)視的key。通過執(zhí)行EXEC 、DISCARD 兩個命令之前監(jiān)視的key也會被取消監(jiān)視。
Redis 與 Guava 、Caffeine 有什么區(qū)別?答案:緩存分為本地緩存和分布式緩存。1、Caffeine、Guava,屬于本地緩存,特點:
- 直接訪問內存,速度快,受內存限制,無法進行大數據存儲。
- 無網絡通訊開銷,性能更高。
- 只支持本地應用進程訪問,同步更新所有節(jié)點的本地緩存數據成本較高。
- 應用進程重啟,數據會丟失。
- 集群模式,支持大數據量存儲
- 數據集中存儲,保證數據的一致性
- 數據跨網絡傳輸,性能低于本地緩存。但同一個機房,兩臺服務器之間請求跑一個來回也就需要500微秒,比起其優(yōu)勢,這點損耗完全可以忽略,這也是分布式緩存受歡迎的原因。
- 支持副本機制,有效的保證了高可用性。
如何實現(xiàn)一個分布式鎖?答案:
- 1、數據庫表,性能比較差
- 2、使用Lua腳本 (包含 SETNX EXPIRE 兩條指令)
- 3、SET的擴展命令(SET key value [EX][PX] [NX|XX])
- 4、Redlock 框架
- 5、Zookeeper Curator框架提供了現(xiàn)成的分布式鎖





