Redis面試題
1、為什麽使用redis(高性能、高並發)
一、高性能,直接從內存中操作,性能遠大於操作db。因為db讀取的是磁盤上的文件,一般是機械運動,特別慢。
二、高並發,因為mysql有鏈接數量上限,超出了就會掛了。而redis不存在這個問題,為什麽呢?因為redis使用的是epoll,而mysql使用的是線程池。epoll抗高並發只要內存足夠,可以隨意抗。而一個進程創建的線程數是有限制的。
2、使用redis有什麽缺點
一、緩存和數據庫雙寫一致性問題
二、緩存雪崩問題
三、緩存擊穿問題
四、緩存的並發競爭問題
3、單線程的redis為什麽這麽快
一、純內存操作
二、單線程操作,避免了頻繁的上下文切換
三、采用了非阻塞I/O多路復用機制
4、redis的數據類型,以及每種數據類型的使用場景
回答:一共五種
一、String 計數功能,比如點贊數
二、哈希 結構化的對象
三、隊列 消息隊列
四、集合 不重復值的集合,比如保存話題裏的視頻id
五、有序集合 排行榜topN,比如話題下視頻排行。
5、redis的過期策略以及內存淘汰機制
問題一、設置了過期時間,但是時間到了,內存占用率還是比較高
問題二、你redis只能存5G數據,可是你寫了10G,那會刪5G的數據。怎麽刪的?
回答:redis采用的是定期刪除+惰性刪除策略。
為什麽不適用純定時刪除?因為這樣做,可能在某一個時間段內存在大量要刪除的key,這樣很可能影響到高並發業務。
那麽定期刪除+惰性刪除策略是怎麽執行的?
一、redis每100ms隨機檢查【一批key】,如果發現過期那麽就刪除。【定期刪除】
二、redis每次獲取一個key時候都會檢查它是否已經被刪除,如果是,那麽就刪除。【惰性刪除】
還是存在問題,在於可能某個key沒人獲取,但是定時刪除沒檢測出來。這時候需要自己配置刪除策略了。
redis.conf 中 maxmemory-policy volatile-lru
noeviction:當內存不足以容納新寫入數據時,新寫入操作會報錯。【推薦】
allkeys-lru:當內存不足以容納新寫入數據時,在鍵空間中,移除最近最少使用的key。【不推薦】
allkeys-random:在鍵空間中,隨機移除某個key 【不推薦】
6、redis和數據庫雙寫一致性問題
一致性問題包括:最終一致性問題、強一致性
強一致性:不能使用緩存。雙寫必然存在數據不一致問題。
最終一致性問題:先寫db,然後再刪緩存。如果刪除緩存失敗,那麽投遞消息隊列補償。
7、如何應對緩存穿透和緩存雪崩問題
緩存擊穿:故意請求緩存不存在的數據。
解決方案一:分布式鎖,緩存被擊穿,要讀數據庫時候,加個分布式鎖,保證用戶只能串行訪問db
解決方案二:異步更新策略,無論結果如何,緩存有沒有,都給返回,只是可能返回錯誤碼。同時,異步起一個線程去更新緩存。
解決方案三:提供一個能迅速判斷請求是否有效的攔截機制。。。。布隆過濾器。。
緩存雪崩:同一時間內大量面積緩存失效
解決方案一:隨機失效緩存
解決方案二:使用互斥鎖,使得請求串行化。策略不可行。
解決方案三:雙緩存,沒看懂。。。【】
8、如何解決redis的並發競爭問題
能不能用redis事務?不行,因為集群下redis事務基本無用。
如果要求請求排序:使用隊列串行化,或者設置鎖時候將時間戳帶上,如果某個系統發現自己的時間戳早於緩存鎖中的時間戳,那麽什麽也不操作即可。
系統A key 1 {valueA 3:00}
系統B key 1 {valueB 3:05}
系統C key 1 {valueC 3:10}
如果要求請求無序:直接分布式鎖即可。
9、redis丟失數據原因
一、程序bug或人為誤操作
二、因客戶端緩沖區內存使用過大,導致大量鍵被LRU淘汰
三、主庫故障後自動重啟,可能導致數據丟失
五、網絡分區的問題,可能導致短時間的寫入數據丟失
六、主從復制數據不一致,發生故障切換後,出現數據丟失
七、大量過期鍵,同時被淘汰清理
解決方案:https://blog.csdn.net/zhanglu1236789/article/details/56485213
Redis面試題