熟悉這幾道 Redis 高頻面試題,面試不用愁

平頭哥的技術博文發表於2019-12-26

1、說說 Redis 都有哪些應用場景?

  • 快取:這應該是 Redis 最主要的功能了,也是大型網站必備機制,合理地使用快取不僅可以加 快資料的訪問速度,而且能夠有效地降低後端資料來源的壓力。
  • 共享Session:對於一些依賴 session 功能的服務來說,如果需要從單機變成叢集的話,可以選擇 redis 來統一管理 session。
  • 訊息佇列系統:訊息佇列系統可以說是一個大型網站的必備基礎元件,因為其具有業務 解耦、非實時業務削峰等特性。Redis提供了釋出訂閱功能和阻塞佇列的功 能,雖然和專業的訊息佇列比還不夠足夠強大,但是對於一般的訊息佇列功 能基本可以滿足。比如在分散式爬蟲系統中,使用 redis 來統一管理 url佇列。
  • 分散式鎖:在分散式服務中。可以利用Redis的setnx功能來編寫分散式的鎖,雖然這個可能不是太常用。

當然還有諸如排行榜、點贊功能都可以使用 Redis 來實現,但是 Redis 也不是什麼都可以做,比如資料量特別大時,不適合 Redis,我們知道 Redis 是基於記憶體的,雖然記憶體很便宜,但是如果你每天的資料量特別大,比如幾億條的使用者行為日誌資料,用 Redis 來儲存的話,成本相當的高。

2、單執行緒的 Redis 為什麼這麼快?

Redis 有多快?官方給出的答案是讀寫速度 10萬/秒,這個數字不讓人意外,但是 Redis 是單執行緒的。為什麼單執行緒的 Redis 速度這麼快?原因有以下三點:

  • 純記憶體操作:Redis 是完全基於記憶體的,所以讀寫效率非常的高,當然 Redis 存在持久化操作,在持久化操作是都是 fork 子程式和利用 Linux 系統的頁快取技術來完成,並不會影響 Redis 的效能。
  • 單執行緒操作:單執行緒並不是壞事,單執行緒可以避免了頻繁的上下文切換,頻繁的上下文切換也會影響效能的。
  • 合理高效的資料結構
  • 採用了非阻塞 I/O 多路複用機制:多路I/O複用模型是利用 select、poll、epoll 可以同時監察多個流的 I/O 事件的能力,在空閒的時候,會把當前執行緒阻塞掉,當有一個或多個流有 I/O 事件時,就從阻塞態中喚醒,於是程式就會輪詢一遍所有的流(epoll 是隻輪詢那些真正發出了事件的流),並且只依次順序的處理就緒的流,這種做法就避免了大量的無用操作。

3、說說 Redis 的資料結構及使用場景

Redis 提供了 5種資料結構,每一種資料結構有各種的使用場景。

1、String 字串

字串型別是 Redis 最基礎的資料結構,首先鍵都是字串型別,而且 其他幾種資料結構都是在字串型別基礎上構建的,我們常使用的 set key value 命令就是字串。常用在快取、計數、共享Session、限速等。

2、Hash 雜湊

在Redis中,雜湊型別是指鍵值本身又是一個鍵值對 結構,形如value={{field1,value1},...{fieldN,valueN}},新增命令:hset key field value。雜湊可以用來存放使用者資訊,比如實現購物車

3、List 列表

列表(list)型別是用來儲存多個有序的字串。可以做簡單的訊息佇列的功能。另外,可以利用 lrange 命令,做基於 Redis的分頁功能,效能極佳,使用者體驗好。

4、Set 集合

集合(set)型別也是用來儲存多個的字串元素,但和列表型別不一 樣的是,集合中不允許有重複元素,並且集合中的元素是無序的,不能通過 索引下標獲取元素。利用 Set 的交集、並集、差集等操作,可以計算共同喜好,全部的喜好,自己獨有的喜好等功能。

5、Sorted Set 有序集合

Sorted Set 多了一個權重引數 Score,集合中的元素能夠按 Score 進行排列。可以做排行榜應用,取 TOP N 操作

4、說一說 Redis 的資料過期策略

先給大家一個結論,Redis 中資料過期策略採用定期刪除+惰性刪除策略

1、定期刪除、惰性刪除策略是什麼?

  • 定期刪除策略:Redis 啟用一個定時器定時監視所有的 key,判斷key是否過期,過期的話就刪除。這種策略可以保證過期的 key 最終都會被刪除,但是也存在嚴重的缺點:每次都遍歷記憶體中所有的資料,非常消耗 CPU 資源,並且當 key 已過期,但是定時器還處於未喚起狀態,這段時間內 key 仍然可以用。
  • 惰性刪除策略:在獲取 key 時,先判斷 key 是否過期,如果過期則刪除。這種方式存在一個缺點:如果這個 key 一直未被使用,那麼它一直在記憶體中,其實它已經過期了,會浪費大量的空間。

2、定期刪除+惰性刪除策略是如何工作的?

這兩種策略天然的互補,結合起來之後,定時刪除策略就發生了一些改變,不在是每次掃描全部的 key 了,而是隨機抽取一部分 key 進行檢查,這樣就降低了對 CPU 資源的損耗,惰性刪除策略互補了為檢查到的key,基本上滿足了所有要求。但是有時候就是那麼的巧,既沒有被定時器抽取到,又沒有被使用,這些資料又如何從記憶體中消失?沒關係,還有記憶體淘汰機制,當記憶體不夠用時,記憶體淘汰機制就會上場。Redis 記憶體淘汰機制有以下幾種策略:

  • noeviction:當記憶體不足以容納新寫入資料時,新寫入操作會報錯。(Redis 預設策略)
  • allkeys-lru:當記憶體不足以容納新寫入資料時,在鍵空間中,移除最近最少使用的 Key。(推薦使用)
  • allkeys-random:當記憶體不足以容納新寫入資料時,在鍵空間中,隨機移除某個 Key。
  • volatile-lru:當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,移除最近最少使用的 Key。這種情況一般是把 Redis 既當快取,又做持久化儲存的時候才用。
  • volatile-random:當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,隨機移除某個 Key。
  • volatile-ttl:當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,有更早過期時間的 Key 優先移除。

配置記憶體淘汰機制只需要在 redis.conf 配置檔案中配置 maxmemory-policy 引數即可。

5、如何解決 Redis 快取穿透和快取雪崩問題

快取雪崩: 由於快取層承載著大量請求,有效地 保護了儲存層,但是如果快取層由於某些原因不能提供服務,比如 Redis 節點掛掉了,熱點 key 全部失效了,在這些情況下,所有的請求都會直接請求到資料庫,可能會造成資料庫當機的情況。

預防和解決快取雪崩問題,可以從以下三個方面進行著手:

  • 1、使用 Redis 高可用架構:使用 Redis 叢集來保證 Redis 服務不會掛掉
  • 2、快取時間不一致: 給快取的失效時間,加上一個隨機值,避免集體失效
  • 3、限流降級策略:有一定的備案,比如個性推薦服務不可用了,換成熱點資料推薦服務

快取穿透: 快取穿透是指查詢一個根本不存在的資料,這樣的資料肯定不在快取中,這會導致請求全部落到資料庫上,有可能出現資料庫當機的情況。

預防和解決快取穿透問題,可以考慮以下兩種方法:

  • 1、快取空物件: 將空值快取起來,但是這樣就有一個問題,大量無效的空值將佔用空間,非常浪費。
  • 2、布隆過濾器攔截: 將所有可能的查詢key 先對映到布隆過濾器中,查詢時先判斷key是否存在布隆過濾器中,存在才繼續向下執行,如果不存在,則直接返回。布隆過濾器有一定的誤判,所以需要你的業務允許一定的容錯性。

最後

目前網際網路上很多大佬都有 Redis 高頻面試題相關文章,如有雷同,請多多包涵了。原創不易,碼字不易,還希望大家多多支援。若文中有所錯誤之處,還望提出,謝謝。

歡迎掃碼關注微信公眾號:「平頭哥的技術博文」,和平頭哥一起學習,一起進步。

平頭哥的技術博文

相關文章