微信搜索 【微觀技術】,關注這個不喜歡內卷的程式員,
精彩文章匯總 GitHub https://github.com/aalansehaiyang/technology-talk ,Star 12K ,匯總java生態圈常用技術框架、開源中間件,系統架構、資料庫、大公司架構案例、常用三方類別庫、專案管理、線上問題排查、個人成長、思考等知識
大家好,我是Tom哥~
阿里P7技術專家,一個不喜歡內卷的程式員~
為了便于大家查找問題,了解全貌,整理個目錄,我們可以快速全域了解關于Redis 快取,面試官一般喜歡問哪些問題?
接下來,我們逐條來看看每個問題及答案
Redis 有哪些特性?
答案:
-
性能高, 讀的速度是100000次/s,寫的速度是80000次/s
-
資料持久化,支持RDB 、AOF
-
支持事務,通過
MULTI和EXEC指令包起來, -
多種資料結構型別
-
主從復制
-
其他特性:發布/訂閱、通知、key過期等
Redis 為什么這么快?
答案:
-
完全基于記憶體,沒有磁盤IO上的開銷,異步持久化除外
-
單執行緒,避免多個執行緒切換的性能損耗
-
非阻塞的IO多路復用機制
-
底層的資料存盤結構優化,使用原生的資料結構提升性能,
整理了一份大廠常考面試題,這份pdf包括 Java基礎、Java并發、JVM、MySQL、Redis、Spring、MyBatis、Kafka、設計模式等面試題,分享給大家,
下載地址:百度云鏈接:https://pan.baidu.com/s/1XHT4ppXTp430MEMW2D0-Bg 提取碼: s3ab
Redis 底層的基礎資料結構有哪些?
答案:
-
字串,沒有采用C語言的傳統字串,而是自己實作的一個簡單動態字串SDS的抽象型別,并保存了長度資訊,
-
鏈表(linkedlist),雙向無環鏈表結構,每個鏈表的節點由一個listNode結構來表示,每個節點都有前置和后置節點的指標
-
字典(hashtable),保存鍵值對的抽象資料結構,底層使用hash表,每個字典帶有兩個hash表,供平時使用和rehash時使用,
-
跳躍表(skiplist),跳躍表是有序集合的底層實作之一,redis跳躍表由zskiplist和zskiplistNode組成,zskiplist用于保存跳躍表 資訊(表頭、表尾節點、?度等),zskiplistNode用于表示表跳躍節點,每個跳躍表的層高都是1- 32的亂數,在同一個跳躍表中,多個節點可以包含相同的分值,但是每個節點的成員物件必須是唯一的,節點按照分值大小排序,如果分值相同,則按照成員物件的大小排序,
-
整數集合(intset),用于保存整數值的集合抽象資料結構,不會出現重復元素,底層實作為陣列,
-
壓縮串列(ziplist),為節約記憶體而開發的順序性資料結構,可以包含多個節點,每個節點可以保存一個位元組陣列或者整數值,
Redis 支持哪些資料型別?
答案:五種常用資料型別:String、Hash、Set、List、SortedSet,三種特殊的資料型別:Bitmap、HyperLogLog、Geospatial,其中Bitmap 、HyperLogLog的底層都是 String 資料型別,Geospatial 底層是 Sorted Set 資料型別,
-
字串物件string:int整數、embstr編碼的簡單動態字串、raw簡單動態字串
-
串列物件list:ziplist、linkedlist
-
哈希物件hash:ziplist、hashtable
-
集合物件set:intset、hashtable
-
有序集合物件zset:ziplist、skiplist
Redis 常用的 5 種資料結構和應用場景?
答案:
-
String:快取、計數器、分布式鎖等
-
List:鏈表、佇列、微博關注人時間軸串列等
-
Hash:用戶資訊、Hash 表等
-
Set:去重、贊、踩、共同好友等
-
Zset:訪問量排行榜、點擊量排行榜等
為什么采用單執行緒?
答案:官方回復,CPU不會成為Redis的制約瓶頸,Redis主要受記憶體、網路限制,例如,在一個普通的 Linux 系統上,使用pipelining 可以每秒傳遞 100 萬個請求,所以如果您的應用程式主要使用 O(N) 或 O(log(N)) 命令,則幾乎不會使用太多 CPU,屬于IO密集型系統,
Redis 6.0 之后又改用多執行緒呢?
答案:Redis的多執行緒主要是處理資料的讀寫、協議決議,執行命令還是采用單執行緒順序執行,
主要是因為redis的性能瓶頸在于網路IO而非CPU,使用多執行緒進行一些周邊預處理,提升了IO的讀寫效率,從而提高了整體的吞吐量,antirez 在 RedisConf 2019 分享時提到,Redis 6 引入的多執行緒 IO 對性能提升至少一倍以上,
過期鍵Key 的洗掉策略有哪些?
答案:有3種過期洗掉策略,惰性洗掉、定期洗掉、定時洗掉
-
惰性洗掉,使用key時才進行檢查,如果已經過期,則洗掉,缺點:過期的key如果沒有被訪問到,一直無法洗掉,一直占用記憶體,造成空間浪費,
-
定期洗掉,每隔一段時間做一次檢查,洗掉過期的key,每次只是隨機取一些key去檢查,
-
定時洗掉,為每個key設定過期時間,同時創建一個定時器,一旦到期,立即執行洗掉,缺點:如果過期鍵比較多時,占用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、從系統可用性角度思考,Redis Cluster引入主備機制,當主節點掛了后,自動切換到備用節點,繼續提供服務,2、Client端引入本地快取,通過開關切換,避免Redis突然掛掉,高并發流量把資料庫打掛,
Redis 持久化有哪些方式?
答案:
1、快照RDB,將某個時間點上的資料庫狀態保存到RDB檔案中,RDB檔案是一個壓縮的二進制檔案,保存在磁盤上,當Redis崩潰時,可用于恢復資料,通過SAVE或BGSAVE來生成RDB檔案,
-
SAVE:會阻塞redis行程,直到RDB檔案創建完畢,在行程阻塞期間,redis不能處理任何命令請求,
-
BGSAVE:會fork出一個子行程,然后由子行程去負責生成RDB檔案,父行程還可以繼續處理命令請求,不會阻塞行程,
2、只追加檔案AOF,以日志的形式記錄每個寫操作(非讀操作),當不同節點同步資料時,讀取日志檔案的內容將寫指令從前到后執行一次,即可完成資料恢復,
Redis 常用場景
答案:
-
1、快取,有句話說的好,「性能不夠,快取來湊」
-
2、分布式鎖,利用Redis 的 setnx
-
3、分布式session
-
4、計數器,通過incr命令
-
5、排行榜,Redis 的 有序集合
-
6、其他
Redis 快取要注意的七大經典問題?
答案:列舉了億級系統,高訪問量情況下Redis快取可能會遇到哪些問題?以及對應的解決方案,
-
1、快取集中失效
-
2、快取穿透
-
3、快取雪崩
-
4、快取熱點
-
5、快取大Key
-
6、快取資料的一致性
-
7、資料并發競爭預熱
每個問題的詳細解決方案,請查看 億級系統的Redis快取如何設計???
Redis 集群方案有哪幾種?
答案:
-
主從復制模式
-
Sentinel(哨兵)模式
-
Redis Cluster模式
Redis 主從資料同步(主從復制)的程序?
答案:
-
1、slave啟動后,向master發送sync命令
-
2、master收到sync之后,執行bgsave保存快照,生成RDB全量檔案
-
3、master把slave的寫命令記錄到快取
-
4、bgsave執行完畢之后,發送RDB檔案到slave,slave執行
-
5、master發送緩沖區的寫命令給slave,slave接收命令并執行,完成復制初始化,
-
6、此后,master每次執行一個寫命令都會同步發送給slave,保持master與slave之間資料的一致性
主從復制的優缺點?
答案:
1、優點:
-
master能自動將資料同步到slave,可以進行讀寫分離,分擔master的讀壓力
-
master、slave之間的同步是以非阻塞的方式進行的,同步期間,客戶端仍然可以提交查詢或更新請求
缺點:
-
不具備自動容錯與恢復功能,master 節點宕機后,需要手動指定新的 master
-
master宕機,如果宕機前資料沒有同步完,則切換IP后會存在資料不一致的問題
-
難以支持在線擴容,Redis的容量受限于單機配置
Sentinel(哨兵)模式的優缺點?
答案:哨兵模式基于主從復制模式,增加了哨兵來監控與自動處理故障,
1、優點:
-
哨兵模式基于主從復制模式,所以主從復制模式有的優點,哨兵模式也有
-
master 掛掉可以自動進行切換,系統可用性更高
2、缺點:
-
Redis的容量受限于單機配置
-
需要額外的資源來啟動sentinel行程
Redis Cluster 模式的優缺點?
答案:實作了Redis的分布式存盤,即每臺節點存盤不同的內容,來解決在線擴容的問題,
1、優點:
-
無中心架構,資料按照slot分布在多個節點
-
集群中的每個節點都是平等的,每個節點都保存各自的資料和整個集群的狀態,每個節點都和其他所有節點連接,而且這些連接保持活躍,這樣就保證了我們只需要連接集群中的任意一個節點,就可以獲取到其他節點的資料,
-
可線性擴展到1000多個節點,節點可動態添加或洗掉
-
能夠實作自動故障轉移,節點之間通過
gossip協議交換狀態資訊,用投票機制完成slave到master的角色轉換
缺點:
-
資料通過異步復制,不保證資料的強一致性
-
slave充當 “冷備”,不對外提供讀、寫服務,只作為故障轉移使用,
-
批量操作限制,目前只支持具有相同slot值的key執行批量操作,對mset、mget、sunion等操作支持不友好
-
key事務操作支持有限,只支持多key在同一節點的事務操作,多key分布在不同節點時無法使用事務功能
-
不支持多資料庫空間,一臺redis可以支持16個db,集群模式下只能使用一個,即
db 0,Redis Cluster模式不建議使用pipeline和multi-keys操作,減少max redirect產生的場景,
Redis 如何做擴容?
答案:為了避免資料遷移失效,通常使用一致性哈希實作動態擴容縮容,有效減少需要遷移的Key數量,
但是Cluster 模式,采用固定Slot槽位方式(16384個),對每個key計算CRC16值,然后對16384取模,然后根據slot值找到目標機器,擴容時,我們只需要遷移一部分的slot到新節點即可,
Redis 的集群原理?
答案:一個redis集群由多個節點node組成,而多個node之間通過cluster meet命令來進行連接,組成一個集群,
資料存盤通過分片的形式,整個集群分成了16384個slot,每個節點負責一部分槽位,整個槽位的資訊會同步到所有節點中,
key與slot的映射關系:
-
健值對 key,進行
CRC16計算,計算出一個 16 bit 的值 -
將 16 bit 的值對 16384 取模,得到 0 ~ 16383 的數表示 key 對應的哈希槽
Redis 如何做到高可用?
答案:哨兵機制,具有自動故障轉移、集群監控、訊息通知等功能,
哨兵可以同時監視所有的主、從服務器,當某個master下線時,自動提升對應的slave為master,然后由新master對外提供服務,
什么是 Redis 事務?
答案:Redis事務是一組命令的集合,將多個命令打包,然后把這些命令按順序添加到佇列中,并且按順序執行這些命令,
Redis事務中沒有像Mysql關系型資料庫事務隔離級別的概念,不能保證原子性操作,也沒有像Mysql那樣執行事務失敗會進行回滾操作
Redis 事務執行流程?
答案:通過MULTI、EXEC、WATCH等命令來實作事務機制,事務執行程序將一系列多個命令按照順序一次性執行,在執行期間,事務不會被中斷,也不會去執行客戶端的其他請求,直到所有命令執行完畢,
具體程序:
-
服務端收到客戶端請求,事務以
MULTI開始 -
如果正處于事務狀態時,則會把后續命令放入佇列同時回傳給客戶端
QUEUED,反之則直接執行這 個命令 -
當收到客戶端的
EXEC命令時,才會將佇列里的命令取出、順序執行,執行完將當前狀態從事務狀態改為非事務狀態 -
如果收到
DISCARD命令,放棄執行佇列中的命令,可以理解為Mysql的回滾操作,并且將當前的狀態從事務狀態改為非事務狀態
WATCH 監視某個key,該命令只能在MULTI命令之前執行,如果監視的key被其他客戶端修改,EXEC將會放棄執行佇列中的所有命令,UNWATCH 取消監視之前通過WATCH 命令監視的key,通過執行EXEC 、DISCARD 兩個命令之前監視的key也會被取消監視,
Redis 與 Guava 、Caffeine 有什么區別?
答案:快取分為本地快取和分布式快取,
1、Caffeine、Guava,屬于本地快取,特點:
-
直接訪問記憶體,速度快,受記憶體限制,無法進行大資料存盤,
-
無網路通訊開銷,性能更高,
-
只支持本地應用行程訪問,同步更新所有節點的本地快取資料成本較高,
-
應用行程重啟,資料會丟失,
所以,本地快取適合存盤一些不易改變或者低頻改變的高熱點資料,
2、Redis屬于分布式快取,特點:
-
集群模式,支持大資料量存盤
-
資料集中存盤,保證資料的一致性
-
資料跨網路傳輸,性能低于本地快取,但同一個機房,兩臺服務器之間請求跑一個來回也就需要500微秒,比起其優勢,這點損耗完全可以忽略,這也是分布式快取受歡迎的原因,
-
支持副本機制,有效的保證了高可用性,
如何實作一個分布式鎖?
答案:
-
1、資料庫表,性能比較差
-
2、使用Lua腳本 (包含 SETNX + EXPIRE 兩條指令)
-
3、SET的擴展命令(SET key value [EX][PX] [NX|XX])
-
4、Redlock 框架
-
5、Zookeeper Curator框架提供了現成的分布式鎖
我是Tom哥~
校招進阿里,期間還拿了 百度、華為、中興、騰訊 等6家大廠offer,P7 技術專家,出過專利,CSDN博客專家,多次淘寶雙11活動方案,專注于微服務、高并發、分布式架構、高可用等領域,喜歡挖掘開源框架亮點設計,
1、Java高頻考點
2、計算機網路
3、LeetCode演算法
作為一線大廠的面試官,Tom哥收集很多大廠的高頻面試題,掃描下方的二維碼,關注公眾號【微觀技術】,后臺回復 “666”、“演算法”,免費領取相關學習資料,
已經幫助身邊很多小伙伴進入位元組、阿里等一線大廠,也歡迎小伙伴找Tom哥嘮嗑聊天, 技術交流,圍觀朋友圈,人生打怪不再寂寞
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/392110.html
標籤:java
上一篇:【歷史上的今天】12 月 24 日:姚期智出生;微軟在 Java 反壟斷案中敗訴;GIF 影像格式獲得專利保護
下一篇:學習筆記:中國大學排名定向爬蟲
