更新時間:2022-12-22 15:40:36 來源:動力節(jié)點 瀏覽1811次
redis有著出色的高性能與并發(fā),是在大流量的網(wǎng)站中,需要我們用到的緩存技術,如果大家想要在面試官面前有很好的表現(xiàn),那么redis的技術肯定是需要掌握的。今天小編就針對redis的面試題,整理出了比較常見的,希望可以幫助到大家:

一、Redis到底是單線程還是多線程
Redis 6.0版本之前的單線程指的是其網(wǎng)絡I/O和鍵值對讀寫是由一個線程完成。
也就是只有網(wǎng)絡請求模塊和數(shù)據(jù)操作模塊是單線程的,而其他的持久化、集群數(shù)據(jù)同步等,其實是由額外的線程執(zhí)行的。
Redis6.0引入的多線程指的是網(wǎng)絡請求過程采用了多線程,但鍵值對讀寫命令仍然是單線程處理的,所以Redis依然是并發(fā)安全的。

二、Redis單線程為什么還能這么快
命令執(zhí)行是基于內存操作的,一天命令在內存里操作的時間是幾十納秒
命令執(zhí)行是單線程操作,沒有線程切換開銷。
基于IO多路復用機制提升Redis的IO利用率。
高效的數(shù)據(jù)存儲結構:全局hash表以及多種高效的數(shù)據(jù)結構,比如:跳表、壓縮列表、鏈表等。
三、Redis底層數(shù)據(jù)是如何用跳表來存儲的

四、Redis key 過期了為什么內存沒釋放
如果原本這個key是有過期時間的,再給這個key使用SET命令并且不設置過期時間,那么Redis會自動擦除這個key的過期時間。
Redis對于過期的key的處理一般有惰性刪除和定時刪除兩種策略
惰性刪除:當讀/寫一個已經過期的key時,會觸發(fā)惰性刪除策略,判斷key是否過期,如果過期了直接刪除這個key。這也是key過期了為什么沒有立即釋放內存。
定時刪除:由于惰性刪除無法保證冷數(shù)據(jù)被及時刪掉,所以Redis會定期(默認每100ms)主動淘汰一批已過期的key,這里的一批只是部分過期的key,所以可能會出現(xiàn)key已經過期了但是還沒有被清理掉的情況,導致內存沒有釋放。
五、Redis key沒有設置過期時間為什么被Redis主動刪除了
當Redis已用內存超過maxmemory限定時,廚房主動清理策略
主動清理策略在Redis4.0之前,實現(xiàn)了6種內存淘汰策略,在4.0之后,又增加了兩種,總共8種:
| no-eviction | 當內存不足以容納新寫入數(shù)據(jù)時,新寫入操作會報錯,無法寫入新數(shù)據(jù),一般不采用。 |
| allkeys-Iru | 當內存不足以容納新寫入數(shù)據(jù)時,移除最近最少使用的key,這個是最常用的 |
| allkeys-random | 當內存不足以容納新寫入的數(shù)據(jù)時,隨機移除key |
| allkeys-Ifu | 當內存不足以容納新寫入數(shù)據(jù)時,移除最不經常(最少) 使用的key |
| volatile-lru | 當內存不足以容納新寫入數(shù)據(jù)時,在設置了過期時間的key中,移除最近最少使用的key。 |
| volatile- random |
內存不足以容納新寫入數(shù)據(jù)時,在設置了過期時間的key中,隨機移除某個key。 |
| volatile-lfu | 當內存不足以容納新寫入數(shù)據(jù)時,在設置了過期時間的key中,移除最不經常(最少)使用的key |
| volatile-tt! | 當內存不足以容納新寫入數(shù)據(jù)時,在設置了過期時間的key中,優(yōu)先移除過期時間最早(剩余存活時間最短)的key。 |
六、Redis 淘汰key的算法LRU與LFU的區(qū)別
LRU算法(Least Recently Used,最近最少使用):淘汰很久沒被訪問的數(shù)據(jù),以最近一次訪問時間作為參考。
LFU算法(Least Frequently Used,最不經常使用):淘汰最近一段時間被訪問次數(shù)最少的數(shù)據(jù),以次數(shù)作為參考。
絕大多數(shù)情況我們可以用LRU策略,當存在大量的熱點緩存數(shù)據(jù)時,LFU可能更好一點。
七、刪除Key命令會阻塞Redis嘛
會阻塞的。DEL key[key...] 命令會根據(jù)key類型來刪除,時間復雜度也是不一樣的,O(N),N為被刪除的key數(shù)量
刪除單個字符串類型的key,時間復雜度為O(1)
刪除單個列表、集合、有序集合或哈希類型的key,時間復雜度為O(M),M為以上數(shù)據(jù)結構內的元素數(shù)量。
八、談談Redis集群數(shù)據(jù)hash分片算法
Redis 集群將所有數(shù)據(jù)劃分16384個slots,每個節(jié)點負責其中一部分槽位。當Redis 集群的客戶端來連接集群時,它也會得到一份集群的槽位信息并將其緩存到客戶端本地,這樣當客戶端要查找某個key時,可以根據(jù)槽位定位算法定位到目標節(jié)點。
槽位定位算法
集群默認會對key值使用crc16算法進行hash,得到一個整數(shù)值,然后這個整數(shù)值對16384進行取模運算來得到具體的槽位。
Hash_slot = CRC16(key)mod13684
再根據(jù)槽位和節(jié)點的對應關系就可以定位到key具體是在那個Redis節(jié)點上。

九、Redis執(zhí)行命令竟然有死循環(huán)阻塞Bug
Redis有個RANDOMKEY命令可以從Redis中隨機取出一個key,這個命令可能導致Redis死循環(huán)阻塞。
RANDOMKEY在隨機拿出一個key之后,首先會檢驗這個key是否過期,如果該key過期,那么Redis會刪除它,這個過程就是惰性刪除,但是清理完了之后還不能結束,Redis會再找出一個沒過期的key返回給客戶端。
此時,Redis則會繼續(xù)隨機拿出一個key,然后再判斷它是否過期,直到找到一個沒過期的key返回給客戶端。
這里就有一個問題,如果此時Redis中有大量的key過期,但還未來得及被清理掉,這個循環(huán)就會持續(xù)很久才能結束,這樣就會導致RANDOMKEY命令執(zhí)行耗時變長,影響Redis性能。
以上流程,其實是master上執(zhí)行的。如果在slave上執(zhí)行RANDOMKEY,那么問題更嚴重。
slave是不會自己清理過期的key,當一個key要過期時,master會先清理刪除它,之后master向slave發(fā)送一個DEL命令,告知slave也刪除這個key,以此達到主從一致。
假設Redis中存在大量已過期還未來得及清理的key,那么在slave上執(zhí)行RANDOMKEY時,就會發(fā)生一下問題:
1、slave隨機取出一個key,判斷是否已經過期。
2、key已經過期,但是slave不會刪除它,而是繼續(xù)隨機尋找不過期的key
3、由于大量key都已過期,那slave就會找不到符合條件的key,就會進入死循環(huán)。
這個Bug直到5.0才被修復,修復方法就是在slave中設置一個最大查找次數(shù),無論找到與否,到了這個最大次數(shù)就退出循環(huán)。
十、一次線上事故,Redis主從切換導致了緩存雪崩
我們假設,slave的機器時鐘比master走的快很多。
此時,Redis master 里設置了過期時間的key,從slave角度來看,可能會有很多在master里沒過期,在slave里面已經過期了的數(shù)據(jù)。
如果此時操作主從切換,把slave提升為新的master,新的master就會開始大量清理過期的key,此時就會導致以下結果:
1、master大量清理過期key,主線程可能會發(fā)生阻塞,無法及時處理客戶端請求。
2、Redis中數(shù)據(jù)大量過期,引發(fā)緩存雪崩。
所以,我們一定要保證主從庫的機器時鐘一致,避免發(fā)生這些問題。
以上就是“高頻出現(xiàn)的redis緩存面試題”,你能回答上來嗎?如果想要了解更多的Java面試題相關內容,可以關注動力節(jié)點Java官網(wǎng)。
Java實驗班
0基礎 0學費 15天面授
Java就業(yè)班
有基礎 直達就業(yè)
Java夜校直播班
業(yè)余時間 高薪轉行
Java在職加薪班
工作1~3年,加薪神器
Java架構師班
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習