天天看點

12道redis面試題,面試官能問的都在這裡了

1.redis是什麼

redis是基于記憶體存儲Key-Value鍵值對的高性能緩存資料庫,它是一個Nosql類型非關系型資料庫,它的資料完全在記憶體當中,是以存取非常快,被後端人才經常用做緩存資料庫這塊,而且他是單線程的,采用的隊列模式将并發通路變為串行通路,消除了關系型資料庫串行控制的開銷。

2.redis的特點

由于它是一個基于記憶體存儲的緩存資料庫,是以速度超級快,他的查找和操作的時間複雜度都是O(1),并且支援多種資料類型的存儲,能存儲String、list、set,、hash、sorted set。但是缺點是它受到實體記憶體的限制,不能用來存儲海量的資料進行讀寫。

3.redis存儲的資料類型

1.String:以下是操作它的常用指令:

set/get/decr/incr/mget等。

2.List:以下是操作它的常用指令:

lpush/rpush/lpop/lrange等。

這個類型讓redis可以有很多的應用場景,如關注清單,微網誌的粉絲清單,消息隊列等,都可以用list來實作。

3.Set,操作它常用的指令有sadd/spop/smembers等。這個資料類型和List類似,都可以做清單功能,但是set是可以自動去重的,當需要有去重的時候,我們可以選擇它來存儲。

4.Hash,操作它常用指令有hget/hset/hgetall等。hash适合我們存儲一些對象的時候使用,比如我們可以存儲一些商品的資訊,格式:key=productId ,value={“id”:1,“name”:“蘋果”,“price”:10}

5.Sorted set ,操作它常用指令有zadd/zrange/zrem等。使用場景跟set類似,但它是自動有序的,它提供了一個額外的優先級score參數來提供排序,并且可以自動排序,可以用來做排行榜。

他的内部實作:sorted set的底層使用HashMap和跳躍表來保證資料的存儲和有序,HashMap裡放的是成員到score的映射,而跳躍表放的是所有成員,排序是根據HashMap裡的score,使用跳躍表可以讓查詢更加高效。

4.Redis 挂掉之後,如何再重新開機伺服器資料可以恢複

redis有自己的持久化機制,可以将記憶體中的資料持久化到硬碟裡面去來保證資料持久化,當redis伺服器重新開機時候可以讀取硬碟裡面的檔案來重新加載的記憶體中,就可以恢複原來的資料。

RDB是redis預設的持久化機制,它是以快照的形式将資料儲存到硬碟的二進制檔案裡的,産生一個dump.rdb檔案,可以通過配置檔案中的save來定義快照的周期。這種方式性能好,但是資料不是很完整,容易丢失一部分。

AOF也是redis的一種持久化機制,它是通過Write函數來将操作過redis資料庫的指令追加到檔案的最後,當重新開機伺服器時候會重新執行檔案中的寫的指令來重建資料庫的資料。這個方式資料完整,但是執行的檔案比較大時,會很慢,可能導緻服務卡頓。

如果這兩種都開啟了,重新開機時候會優先選擇AOF這種方式。

5.緩存雪崩

定義:在同一時間出現了大面積緩存過期,本應該通路緩存的的資料請求都去通路資料庫了,造成資料庫壓力太大而使資料庫當機,系統崩潰。

解決方案:可以考慮用加鎖的方式或隊列的方式來保證大量的線程不會對資料庫一次性進行讀寫操作,進而避免失效時大量的請求落到資料庫上。

6.緩存穿透

定義:是指使用者先在緩存中查詢不到資料,然後又在資料庫查不到資料,兩次都沒有命中,如果是很多使用者,這樣會給資料庫壓力造成很大,這個就屬于緩存穿透。

解決方案:最常用的辦法布隆過濾器,将所有可能存在的資料哈希到一個超級大的bitmap中,一個不存在的資料會被這個bitmap攔截,進而避免了對資料庫的查詢壓力。

7.緩存擊穿

定義:指一個很熱點的key,大量的并發請求同時對這個key進行通路,當這個key在失效的瞬間,仍然有大量的請求通路就會穿破緩存,進而直接請求資料庫。

解決方案:在通路key之前,采用setnx(set if not exists)來設定另一個短期key來鎖住目前key的通路,通路結束再删除該短期key。

8.業務需要将大量的key設定相同過期時間,應當注意什麼

大量的key過期時間設定相同,剛好到時間時候,redis可能會出現短暫的卡頓,我們可以在時間上加一個随機值,讓過期時間分散一些。

9.Redis分布式鎖

先用setnx來争搶鎖,搶到之後,再用expire給鎖加一個過期時間防止鎖忘記了釋放,我們也可以使用del key 來釋放鎖。

10.Redis如何做消息隊列

正常情況使用list資料類型作為隊列,rpush用來生産消息,lpop用來消費消息。當lpop沒有消息的時候,可以讓他sleep,當然List中還有個指令叫blpop,在沒有消息的時候,也可以使用它來阻塞,一直到消息過來。

如果是做延時隊列的話,我們可以使用它的Sorted set資料類型,用時間戳來作為score,消息内容作為key調用zadd指令來生産消息,消費者用zrangebyscore指令擷取N秒之前的資料輪詢進行處理。

11.如何解決 Redis 的并發競争問題

Redis的并發競争問題是指多個系統同時對一個key進行的操作,但是最後執行的順序和我們期望的順序不同,這樣也就導緻了結果的不同。

解決方案:

1.用戶端角度,為保證每個用戶端間正常有序與Redis進行通信,對用戶端讀寫Redis操作采用内部鎖synchronized。

2.伺服器角度,利用setnx實作鎖(分布式鎖)

12.redis的過期政策以及記憶體淘汰機制

過期政策采用的是定期删除和惰性删除政策,定期删除是redis預設每過100ms檢查是否有過期的key,如果有就删除,它是随機抽取進行檢查,并不是對所有的key都進行檢查,如果隻用定期删除政策,會造成很多key到時間沒有被删除。這個時候惰性删除就閃亮登場了,當你擷取某個key時,redis會檢查這個key是否已經過期,如果過期就會删除。當然也有一種情況就是定期删除沒有删除key(定期删除失效),你也沒有請求key(惰性删除也失效)這樣就會導緻redis的記憶體會越來越高,這個時候就應該采用記憶體淘汰機制。

記憶體淘汰政策有6種:

volatile-lru:從已設定過期時間的資料集中挑選最近最少使用的資料淘汰

volatile-ttl:從已設定過期時間的資料集中挑選将要過期的資料淘汰

volatile-random:從已設定過期時間的資料集中随機選擇資料淘汰

allkeys-lru:從資料集中挑選最近最少使用的資料淘汰

allkeys-random:從資料集中随機選擇資料淘汰

no-enviction:禁止驅逐資料,新寫入操作會報錯

使用政策規則:

1、如果資料呈現幂律分布,也就是一部分資料通路頻率高,一部分資料通路頻率低,則使用allkeys-lru

2、如果資料呈現平等分布,也就是所有的資料通路頻率都相同,則使用allkeys-random

以上是我總結面試過程中,經常被問到Redis的相關問題,大家可以參考一下,希望能夠幫助到你們,讓你們在這塊準備的充分一點,因為這塊問題是個難點加重點,基本上履歷中出現Redis,面試官就會問關于它的相關問題。大家找工作,可以關注下面的公衆号,免費分享面試總結。

12道redis面試題,面試官能問的都在這裡了