更新時間:2022-12-22 15:40:36 來源:動力節點 瀏覽1353次
redis有著出色的高性能與并發,是在大流量的網站中,需要我們用到的緩存技術,如果大家想要在面試官面前有很好的表現,那么redis的技術肯定是需要掌握的。今天小編就針對redis的面試題,整理出了比較常見的,希望可以幫助到大家:
一、Redis到底是單線程還是多線程
Redis 6.0版本之前的單線程指的是其網絡I/O和鍵值對讀寫是由一個線程完成。
也就是只有網絡請求模塊和數據操作模塊是單線程的,而其他的持久化、集群數據同步等,其實是由額外的線程執行的。
Redis6.0引入的多線程指的是網絡請求過程采用了多線程,但鍵值對讀寫命令仍然是單線程處理的,所以Redis依然是并發安全的。
二、Redis單線程為什么還能這么快
命令執行是基于內存操作的,一天命令在內存里操作的時間是幾十納秒
命令執行是單線程操作,沒有線程切換開銷。
基于IO多路復用機制提升Redis的IO利用率。
高效的數據存儲結構:全局hash表以及多種高效的數據結構,比如:跳表、壓縮列表、鏈表等。
三、Redis底層數據是如何用跳表來存儲的
四、Redis key 過期了為什么內存沒釋放
如果原本這個key是有過期時間的,再給這個key使用SET命令并且不設置過期時間,那么Redis會自動擦除這個key的過期時間。
Redis對于過期的key的處理一般有惰性刪除和定時刪除兩種策略
惰性刪除:當讀/寫一個已經過期的key時,會觸發惰性刪除策略,判斷key是否過期,如果過期了直接刪除這個key。這也是key過期了為什么沒有立即釋放內存。
定時刪除:由于惰性刪除無法保證冷數據被及時刪掉,所以Redis會定期(默認每100ms)主動淘汰一批已過期的key,這里的一批只是部分過期的key,所以可能會出現key已經過期了但是還沒有被清理掉的情況,導致內存沒有釋放。
五、Redis key沒有設置過期時間為什么被Redis主動刪除了
當Redis已用內存超過maxmemory限定時,廚房主動清理策略
主動清理策略在Redis4.0之前,實現了6種內存淘汰策略,在4.0之后,又增加了兩種,總共8種:
no-eviction | 當內存不足以容納新寫入數據時,新寫入操作會報錯,無法寫入新數據,一般不采用。 |
allkeys-Iru | 當內存不足以容納新寫入數據時,移除最近最少使用的key,這個是最常用的 |
allkeys-random | 當內存不足以容納新寫入的數據時,隨機移除key |
allkeys-Ifu | 當內存不足以容納新寫入數據時,移除最不經常(最少) 使用的key |
volatile-lru | 當內存不足以容納新寫入數據時,在設置了過期時間的key中,移除最近最少使用的key。 |
volatile- random |
內存不足以容納新寫入數據時,在設置了過期時間的key中,隨機移除某個key。 |
volatile-lfu | 當內存不足以容納新寫入數據時,在設置了過期時間的key中,移除最不經常(最少)使用的key |
volatile-tt! | 當內存不足以容納新寫入數據時,在設置了過期時間的key中,優先移除過期時間最早(剩余存活時間最短)的key。 |
六、Redis 淘汰key的算法LRU與LFU的區別
LRU算法(Least Recently Used,最近最少使用):淘汰很久沒被訪問的數據,以最近一次訪問時間作為參考。
LFU算法(Least Frequently Used,最不經常使用):淘汰最近一段時間被訪問次數最少的數據,以次數作為參考。
絕大多數情況我們可以用LRU策略,當存在大量的熱點緩存數據時,LFU可能更好一點。
七、刪除Key命令會阻塞Redis嘛
會阻塞的。DEL key[key...] 命令會根據key類型來刪除,時間復雜度也是不一樣的,O(N),N為被刪除的key數量
刪除單個字符串類型的key,時間復雜度為O(1)
刪除單個列表、集合、有序集合或哈希類型的key,時間復雜度為O(M),M為以上數據結構內的元素數量。
八、談談Redis集群數據hash分片算法
Redis 集群將所有數據劃分16384個slots,每個節點負責其中一部分槽位。當Redis 集群的客戶端來連接集群時,它也會得到一份集群的槽位信息并將其緩存到客戶端本地,這樣當客戶端要查找某個key時,可以根據槽位定位算法定位到目標節點。
槽位定位算法
集群默認會對key值使用crc16算法進行hash,得到一個整數值,然后這個整數值對16384進行取模運算來得到具體的槽位。
Hash_slot = CRC16(key)mod13684
再根據槽位和節點的對應關系就可以定位到key具體是在那個Redis節點上。
九、Redis執行命令竟然有死循環阻塞Bug
Redis有個RANDOMKEY命令可以從Redis中隨機取出一個key,這個命令可能導致Redis死循環阻塞。
RANDOMKEY在隨機拿出一個key之后,首先會檢驗這個key是否過期,如果該key過期,那么Redis會刪除它,這個過程就是惰性刪除,但是清理完了之后還不能結束,Redis會再找出一個沒過期的key返回給客戶端。
此時,Redis則會繼續隨機拿出一個key,然后再判斷它是否過期,直到找到一個沒過期的key返回給客戶端。
這里就有一個問題,如果此時Redis中有大量的key過期,但還未來得及被清理掉,這個循環就會持續很久才能結束,這樣就會導致RANDOMKEY命令執行耗時變長,影響Redis性能。
以上流程,其實是master上執行的。如果在slave上執行RANDOMKEY,那么問題更嚴重。
slave是不會自己清理過期的key,當一個key要過期時,master會先清理刪除它,之后master向slave發送一個DEL命令,告知slave也刪除這個key,以此達到主從一致。
假設Redis中存在大量已過期還未來得及清理的key,那么在slave上執行RANDOMKEY時,就會發生一下問題:
1、slave隨機取出一個key,判斷是否已經過期。
2、key已經過期,但是slave不會刪除它,而是繼續隨機尋找不過期的key
3、由于大量key都已過期,那slave就會找不到符合條件的key,就會進入死循環。
這個Bug直到5.0才被修復,修復方法就是在slave中設置一個最大查找次數,無論找到與否,到了這個最大次數就退出循環。
十、一次線上事故,Redis主從切換導致了緩存雪崩
我們假設,slave的機器時鐘比master走的快很多。
此時,Redis master 里設置了過期時間的key,從slave角度來看,可能會有很多在master里沒過期,在slave里面已經過期了的數據。
如果此時操作主從切換,把slave提升為新的master,新的master就會開始大量清理過期的key,此時就會導致以下結果:
1、master大量清理過期key,主線程可能會發生阻塞,無法及時處理客戶端請求。
2、Redis中數據大量過期,引發緩存雪崩。
所以,我們一定要保證主從庫的機器時鐘一致,避免發生這些問題。
以上就是“高頻出現的redis緩存面試題”,你能回答上來嗎?如果想要了解更多的Java面試題相關內容,可以關注動力節點Java官網。
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習