Redis面試內容梳理

(剛新建的羣1039047324,歡迎對技術感興趣的朋友加入,羣內只聊技術,分享工作中容易踩的坑,以及如何避免踩坑)

考點

面試的時候問你緩存,主要是考察緩存特性的理解,對 MCRedis 的特點和使用方式的掌握。

  1. 對 DB 熱點數據進行緩存減少 DB 壓力;對依賴的服務進行緩存,提高併發性能;
  2. 單純 K-V 緩存的場景可以使用 MC,而需要緩存 list、set 等特殊數據格式,可以使用 Redis
  3. 需要緩存一個用戶最近播放視頻的列表可以使用 Redis 的 list 來保存、需要計算排行榜數據時,可以使用 Redis 的 zset 結構來保存。
  4. 要了解 MC 和 Redis 的常用命令,例如原子增減、對不同數據結構進行操作的命令等。
  5. 瞭解 MC 和 Redis 在內存中的存儲結構,這對評估使用容量會很有幫助。
  6. 瞭解 MC 和 Redis 的數據失效方式和剔除策略,比如主動觸發的定期剔除和被動觸發延期剔除
  7. 要理解 Redis 的持久化、主從同步與 Cluster 部署的原理,比如 RDBAOF 的實現方式與區別。
  8. 要知道緩存穿透、擊穿、雪崩分別的異同點以及解決方案。
  9. 不管你有沒有電商經驗我覺得你都應該知道秒殺的具體實現,以及細節點。

加分項

如果想要在面試中獲得更好的表現,還應瞭解下面這些加分項。

  1. 是要結合實際應用場景來介紹緩存的使用。例如調用後端服務接口獲取信息時,可以使用本地+遠程的多級緩存;對於動態排行榜類的場景可以考慮通過 RedisSorted set 來實現等等。
  2. 最好你有過分佈式緩存設計和使用經驗,例如項目中在什麼場景使用過 Redis,使用了什麼數據結構,解決哪類的問題;使用 MC 時根據預估值大小調整 McSlab 分配參數等等。
  3. 最好可以瞭解緩存使用中可能產生的問題。比如 Redis 是單線程處理請求,應儘量避免耗時較高的單個請求任務,防止相互影響;Redis 服務應避免和其他 CPU 密集型的進程部署在同一機器;或者禁用 Swap 內存交換,防止 Redis 的緩存數據交換到硬盤上,影響性能。再比如前面提到的 MC 鈣化問題等等。
  4. 要了解 Redis 的典型應用場景,例如,使用 Redis 來實現分佈式鎖;使用 Bitmap 來實現 BloomFilter,使用 HyperLogLog 來進行 UV 統計等等。

 

1.Redis(Remote Dictionary Server),是一個開源用C語言編寫基於內存高性能的Key-Value數據庫。當前最新版本6.0。

 

2.Redis相比memcached有哪些優勢:

  • memcached所有的值均是簡單的字符串,redis作爲其替代者,支持更爲豐富的數據類型
  • redis的速度比memcached快很多
  • redis可以持久化其數據

 

3.Redis是單線程的,但Redis爲什麼這麼快?

  1. 完全基於內存,絕大部分請求是純粹的內存操作,非常快速。數據存在內存中,類似於HashMap,HashMap的優勢就是查找和操作的時間複雜度都是O(1);
  2. 數據結構簡單,對數據操作也簡單,Redis中的數據結構是專門進行設計的;
  3. 採用單線程,避免了不必要的上下文切換和競爭條件,也不存在多進程或者多線程導致的切換而消耗 CPU,不用去考慮各種鎖的問題,不存在加鎖釋放鎖操作,沒有因爲可能出現死鎖而導致的性能消耗;
  4. 使用多路I/O複用模型,非阻塞IO;這裏“多路”指的是多個網絡連接,“複用”指的是複用同一個線程
  5. 使用底層模型不同,它們之間底層實現方式以及與客戶端之間通信的應用協議不一樣,Redis直接自己構建了VM 機制 ,因爲一般的系統調用系統函數的話,會浪費一定的時間去移動和請求;

 

4.Reids主從複製

複製是高可用Redis的基礎,哨兵和集羣都是在複製基礎上實現高可用的。複製主要實現了數據的多機備份,以及對於讀操作的負載均衡和簡單的故障恢復。缺陷:故障恢復無法自動化;寫操作無法負載均衡;存儲能力受到單機的限制。

5.Redis哨兵

在複製的基礎上,哨兵實現了自動化的故障恢復。缺陷:寫操作無法負載均衡;存儲能力受到單機的限制。

6.RDB和AOF的優缺點

RDB持久化

優點:RDB文件緊湊,體積小,網絡傳輸快,適合全量複製;恢復速度比AOF快很多。當然,與AOF相比,RDB最重要的優點之一是對性能的影響相對較小。

缺點:RDB文件的致命缺點在於其數據快照的持久化方式決定了必然做不到實時持久化,而在數據越來越重要的今天,數據的大量丟失很多時候是無法接受的,因此AOF持久化成爲主流。此外,RDB文件需要滿足特定格式,兼容性差(如老版本的Redis不兼容新版本的RDB文件)。

AOF持久化

與RDB持久化相對應,AOF的優點在於支持秒級持久化、兼容性好,缺點是文件大、恢復速度慢、對性能影響大。

 

7.redis緩存被擊穿處理機制

使用mutex。簡單地來說,就是在緩存失效的時候(判斷拿出來的值爲空),不是立即去load db,而是先使用緩存工具的某些帶成功操作返回值的操作(比如Redis的SETNX或者Memcache的ADD)去set一個mutex key,當操作返回成功時,再進行load db的操作並回設緩存;否則,就重試整個get緩存的方法

 

8.緩存雪崩問題

存在同一時間內大量鍵過期(失效),接着來的一大波請求瞬間都落在了數據庫中導致連接異常。

解決方案:

  1. 也是像解決緩存穿透一樣加鎖排隊。
  2. 建立備份緩存,緩存A和緩存B,A設置超時時間,B不設值超時時間,先從A讀緩存,A沒有讀B,並且更新A緩存和B緩存;

9.緩存併發問題

這裏的併發指的是多個redis的client同時set key引起的併發問題。比較有效的解決方案就是把redis.set操作放在隊列中使其串行化,必須的一個一個執行,具體的代碼就不上了,當然加鎖也是可以的,至於爲什麼不用redis中的事務,留給各位看官自己思考探究。

 

10.緩存和數據庫間數據一致性問題

分佈式環境下(單機就不用說了)非常容易出現緩存和數據庫間的數據一致性問題,針對這一點的話,只能說,如果你的項目對緩存的要求是強一致性的,那麼請不要使用緩存。我們只能採取合適的策略來降低緩存和數據庫間數據不一致的概率,而無法保證兩者間的強一致性。合適的策略包括 合適的緩存更新策略,更新數據庫後要及時更新緩存、緩存失敗時增加重試機制,例如MQ模式的消息隊列。

 

11.Redis分佈式

redis支持主從的模式。原則:Master會將數據同步到slave,而slave不會將數據同步到master。Slave啓動時會連接master來同步數據。

這是一個典型的分佈式讀寫分離模型。我們可以利用master來插入數據,slave提供檢索服務。這樣可以有效減少單個機器的併發訪問數量

12.讀寫分離模型

通過增加Slave DB的數量,讀的性能可以線性增長。爲了避免Master DB的單點故障,集羣一般都會採用兩臺Master DB做雙機熱備,所以整個集羣的讀和寫的可用性都非常高。讀寫分離架構的缺陷在於,不管是Master還是Slave,每個節點都必須保存完整的數據,如果在數據量很大的情況下,集羣的擴展能力還是受限於單個節點的存儲能力,而且對於Write-intensive類型的應用,讀寫分離架構並不適合。

13.數據分片模型

爲了解決讀寫分離模型的缺陷,可以將數據分片模型應用進來。

可以將每個節點看成都是獨立的master,然後通過業務實現數據分片。

結合上面兩種模型,可以將每個master設計成由一個master和多個slave組成的模型。

14. redis常見性能問題和解決方案:

Master最好不要做任何持久化工作,如RDB內存快照和AOF日誌文件

如果數據比較重要,某個Slave開啓AOF備份數據,策略設置爲每秒同步一次

爲了主從複製的速度和連接的穩定性,Master和Slave最好在同一個局域網內

儘量避免在壓力很大的主庫上增加從庫

 

15.Redis分佈式鎖實現

先拿setnx來爭搶鎖,搶到之後,再用expire給鎖加一個過期時間防止鎖忘記了釋放。**如果在setnx之後執行expire之前進程意外crash或者要重啓維護了,那會怎麼樣?**set指令有非常複雜的參數,這個應該是可以同時把setnx和expire合成一條指令來用的!

 

16.Reids性能測試命令

#redis-benchmark:Redis 性能測試工具,測試 Redis 在你的系統及你的配置下的讀寫性能

$redis-benchmark -n 100000 –c 50

#模擬同時由 50 個客戶端發送 100000 個 SETs/GETs 查詢 

17 數據類型及適用場景:

String:

String 類型是 Redis 中最常使用的類型,內部的實現是通過 SDS(Simple Dynamic String )來存儲的。SDS 類似於 Java 中的 ArrayList,可以通過預分配冗餘空間的方式來減少內存的頻繁分配。

這是最簡單的類型,就是普通的 set 和 get,做簡單的 KV 緩存。

但是真實的開發環境中,很多仔可能會把很多比較複雜的結構也統一轉成String去存儲使用,比如有的仔他就喜歡把對象或者List轉換爲JSONString進行存儲,拿出來再反序列話啥的。

我在這裏就不討論這樣做的對錯了,但是我還是希望大家能在最合適的場景使用最合適的數據結構,對象找不到最合適的但是類型可以選最合適的嘛,之後別人接手你的代碼一看這麼規範,誒這小夥子有點東西呀,看到你啥都是用的String垃圾!

 

 

好了這些都是題外話了,道理還是希望大家記在心裏,習慣成自然嘛,小習慣成就你。

String的實際應用場景比較廣泛的有:

  • 緩存功能:String字符串是最常用的數據類型,不僅僅是Redis,各個語言都是最基本類型,因此,利用Redis作爲緩存,配合其它數據庫作爲存儲層,利用Redis支持高併發的特點,可以大大加快系統的讀寫速度、以及降低後端數據庫的壓力。
  • 計數器:許多系統都會使用Redis作爲系統的實時計數器,可以快速實現計數和查詢的功能。而且最終的數據結果可以按照特定的時間落地到數據庫或者其它存儲介質當中進行永久保存。
  • 共享用戶Session:用戶重新刷新一次界面,可能需要訪問一下數據進行重新登錄,或者訪問頁面緩存Cookie,但是可以利用Redis將用戶的Session集中管理,在這種模式只需要保證Redis的高可用,每次用戶Session的更新和獲取都可以快速完成。大大提高效率。

Hash:

這個是類似 Map 的一種結構,這個一般就是可以將結構化的數據,比如一個對象(前提是這個對象沒嵌套其他的對象)給緩存在 Redis 裏,然後每次讀寫緩存的時候,可以就操作 Hash 裏的某個字段

但是這個的場景其實還是多少單一了一些,因爲現在很多對象都是比較複雜的,比如你的商品對象可能裏面就包含了很多屬性,其中也有對象。我自己使用的場景用得不是那麼多。

List:

List 是有序列表,這個還是可以玩兒出很多花樣的。

比如可以通過 List 存儲一些列表型的數據結構,類似粉絲列表、文章的評論列表之類的東西。

比如可以通過 lrange 命令,讀取某個閉區間內的元素,可以基於 List 實現分頁查詢,這個是很棒的一個功能,基於 Redis 實現簡單的高性能分頁,可以做類似微博那種下拉不斷分頁的東西,性能高,就一頁一頁走。

比如可以搞個簡單的消息隊列,從 List 頭懟進去,從 List 屁股那裏弄出來。

List本身就是我們在開發過程中比較常用的數據結構了,熱點數據更不用說了。

  • 消息隊列:Redis的鏈表結構,可以輕鬆實現阻塞隊列,可以使用左進右出的命令組成來完成隊列的設計。比如:數據的生產者可以通過Lpush命令從左邊插入數據,多個數據消費者,可以使用BRpop命令阻塞的“搶”列表尾部的數據。
  • 文章列表或者數據分頁展示的應用。

比如,我們常用的博客網站的文章列表,當用戶量越來越多時,而且每一個用戶都有自己的文章列表,而且當文章多時,都需要分頁展示,這時可以考慮使用Redis的列表,列表不但有序同時還支持按照範圍內獲取元素,可以完美解決分頁查詢功能。大大提高查詢效率。

Set:

Set 是無序集合,會自動去重的那種。

直接基於 Set 將系統裏需要去重的數據扔進去,自動就給去重了,如果你需要對一些數據進行快速的全局去重,你當然也可以基於 JVM 內存裏的 HashSet 進行去重,但是如果你的某個系統部署在多臺機器上呢?得基於Redis進行全局的 Set 去重。

可以基於 Set 玩兒交集、並集、差集的操作,比如交集吧,我們可以把兩個人的好友列表整一個交集,看看倆人的共同好友是誰?對吧。

反正這些場景比較多,因爲對比很快,操作也簡單,兩個查詢一個Set搞定。

Sorted Set:

Sorted set 是排序的 Set,去重但可以排序,寫進去的時候給一個分數,自動根據分數排序。

有序集合的使用場景與集合類似,但是set集合不是自動有序的,而Sorted set可以利用分數進行成員間的排序,而且是插入時就排序好。所以當你需要一個有序且不重複的集合列表時,就可以選擇Sorted set數據結構作爲選擇方案。

  • 排行榜:有序集合經典使用場景。例如視頻網站需要對用戶上傳的視頻做排行榜,榜單維護可能是多方面:按照時間、按照播放量、按照獲得的贊數等。
  • Sorted Sets來做帶權重的隊列,比如普通消息的score爲1,重要消息的score爲2,然後工作線程可以選擇按score的倒序來獲取工作任務。讓重要的任務優先執行。

微博熱搜榜,就是有個後面的熱度值,前面就是名稱

高級用法:

Bitmap :

位圖是支持按 bit 位來存儲信息,可以用來實現 布隆過濾器(BloomFilter)

HyperLogLog:

供不精確的去重計數功能,比較適合用來做大規模數據的去重統計,例如統計 UV;

Geospatial:

可以用來保存地理位置,並作位置距離計算或者根據半徑計算位置等。有沒有想過用Redis來實現附近的人?或者計算最優地圖路徑?

這三個其實也可以算作一種數據結構,你如果只知道五種基礎類型那隻能拿60分,如果你能講出高級用法,那就覺得你有點東西

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章