天天看點

【2021最新版】Redis面試題總結(50道題含答案解析)總結

文章目錄

      • 1、什麼是Redis?
      • 2、Redis與其他key-value存儲有什麼不同?
      • 3、Redis的資料類型?
      • 4、使用Redis有哪些好處?
      • 5、Redis相比Memcached有哪些優勢?
      • 6、Memcache與Redis的差別都有哪些?
      • 7、Redis是單程序單線程的?
      • 8、一個字元串類型的值能存儲最大容量是多少?
      • 9、Redis持久化機制。
      • 10、緩存雪崩、緩存穿透、緩存預熱、緩存更新、緩存降級等問題
      • 11、熱點資料和冷資料是什麼?
      • 12、單線程的redis為什麼這麼快?
      • 13、redis的資料類型,以及每種資料類型的使用場景。
      • 14、redis的過期政策以及記憶體淘汰機制。
      • 15、Redis常見性能問題和解決方案?
      • 16、為什麼Redis的操作是原子性的,怎麼保證原子性的?
      • 17、Redis事務。
      • 18、Redis的持久化機制是什麼?各自的優缺點?
      • 19、Redis常見性能問題和解決方案:
      • 20、redis過期鍵的删除政策?
      • 21、Redis的回收政策(淘汰政策)?
      • 22、為什麼Redis需要把所有資料放到記憶體中?
      • 23、Redis的同步機制了解麼?
      • 24、Pipeline有什麼好處,為什麼要用pipeline?
      • 25、是否使用過Redis叢集,叢集的原理是什麼?
      • 26、Redis叢集方案什麼情況下會導緻整個叢集不可用?
      • 27、Redis支援的Java用戶端都有哪些?官方推薦用哪個?
      • 28、Jedis與Redisson對比有什麼優缺點?
      • 29、Redis如何設定密碼及驗證密碼?
      • 30、說說Redis哈希槽的概念?
      • 31、Redis叢集的主從複制模型是怎樣的?
      • 32、Redis叢集會有寫操作丢失嗎?為什麼?
      • 33、Redis叢集之間是如何複制的?
      • 34、Redis叢集最大節點個數是多少?
      • 35、Redis叢集如何選擇資料庫?
      • 36、怎麼測試Redis的連通性?
      • 37、怎麼了解Redis事務?
      • 38、Redis事務相關的指令有哪幾個?
      • 39、Redis key的過期時間和永久有效分别怎麼設定?
      • 40、Redis如何做記憶體優化?
      • 41、Redis回收程序如何工作的?
      • 42、都有哪些辦法可以降低Redis的記憶體使用情況呢?
      • 43、Redis的記憶體用完了會發生什麼?
      • 44、一個 Redis執行個體最多能存放多少的 keys?List、Set、Sorted Set他們最多能存放多少元素?
      • 45、MySQL裡有2000w資料,redis中隻存20w的資料,如何保證redis中的資料都是熱點資料?
      • 46、Redis最适合的場景?
      • 47、假如Redis裡面有1億個key,其中有10w個key是以某個固定的已知的字首開頭的,如果将它們全部找出來?
      • 48、如果有大量的key需要設定同一時間過期,一般需要注意什麼?
      • 49、使用過Redis做異步隊列麼,你是怎麼用的?
      • 50、使用過Redis分布式鎖麼,它是什麼回事?
  • 總結
最近面試的小夥伴很多,對此我整理了一份Java面試題手冊:基礎知識、JavaOOP、Java集合/泛型面試題、Java異常面試題、Java中的IO與NIO面試題、Java反射、Java序列化、Java注解、多線程&并發、JVM、Mysql、【2021最新版】Java面試真題彙總
序号 内容 位址連結
1 【2021最新版】JavaOOP面試題總結 https://blog.csdn.net/m0_48795607/article/details/115288673
2 【2021最新版】Java基礎面試題總結 https://blog.csdn.net/m0_48795607/article/details/115485109
3 【2021最新版】多線程&并發面試題總結 https://blog.csdn.net/m0_48795607/article/details/115489616
4 【2021最新版】JVM面試題總結 https://blog.csdn.net/m0_48795607/article/details/115555086
5 【2021最新版】Mysql面試題總結 https://blog.csdn.net/m0_48795607/article/details/115561030
6 【2021最新版】Memcached面試題總結 https://blog.csdn.net/m0_48795607/article/details/115664662
7 【2021最新版】MongoDB面試題總結 https://blog.csdn.net/m0_48795607/article/details/115672336
8 【2021最新版】Spring面試題總結 https://blog.csdn.net/m0_48795607/article/details/115738909
9 【2021最新版】Spring Boot面試題總結 https://blog.csdn.net/m0_48795607/article/details/115771307
10 【2021最新版】Spring Cloud面試題總結 https://blog.csdn.net/m0_48795607/article/details/115917190
11 【2021最新版】RabbitMQ面試題總結 https://blog.csdn.net/m0_48795607/article/details/116064045
12 【2021最新版】Dubbo面試題總結 https://blog.csdn.net/m0_48795607/article/details/116237861
13 【2021最新版】MyBatis面試題總結 https://blog.csdn.net/m0_48795607/article/details/116427170
14 【2021最新版】ZooKeeper面試題總結 https://blog.csdn.net/m0_48795607/article/details/116458096
15 【2021最新版】資料結構面試題總結 https://blog.csdn.net/m0_48795607/article/details/116461620
16 【2021最新版】算法面試題總結 https://blog.csdn.net/m0_48795607/article/details/116461620
17 【2021最新版】Elasticsearch面試題總結 https://blog.csdn.net/m0_48795607/article/details/116656094
18 【2021最新版】Kafka面試題總結 https://blog.csdn.net/m0_48795607/article/details/116659584
19 【2021最新版】微服務面試題總結 https://blog.csdn.net/m0_48795607/article/details/116662109
20 【2021最新版】Linux面試題總結 https://blog.csdn.net/m0_48795607/article/details/116798880

1、什麼是Redis?

答:

Redis是完全開源免費的,遵守BSD協定,是一個高性能的key-value資料庫。

Redis與其他key-value緩存産品有以下三個特點:

Redis支援資料的持久化,可以将記憶體中的資料儲存在磁盤中,重新開機的時候可以再次加載進行使用。

Redis不僅僅支援簡單的key-value類型的資料,同時還提供list,set,zset,hash等資料結構的存儲。

Redis支援資料的備份,即master-slave模式的資料備份。

Redis優勢

性能極高–Redis能讀的速度是110000次/s,寫的速度是81000次/s 。豐富的資料類型–Redis支援二進制案例的Strings, Lists, Hashes,Sets及Ordered Sets資料類型操作。

原子–Redis的所有操作都是原子性的,意思就是要麼成功執行要麼失敗完全不執行。單個操作是原子性的。多個操作也支援事務,即原子性,通過MULTI和EXEC指令包起來。

豐富的特性–Redis還支援publish/subscribe, 通知,key過期等等特性。

2、Redis與其他key-value存儲有什麼不同?

答:

Redis有着更為複雜的資料結構并且提供對他們的原子性操作,這是一個不同于其他資料庫的進化路徑。

Redis的資料類型都是基于基本資料結構的同時對程式員透明,無需進行額外的抽象。

Redis 運作在記憶體中但是可以持久化到磁盤,是以在對不同資料集進行高速讀寫時需要權衡記憶體,因為資料量不能大于硬體記憶體。在記憶體資料庫方面的另一個優點是,相比在磁盤上相同的複雜的資料結構,在記憶體中操作起來非常簡單,這樣Redis可以做很多内部複雜性很強的事情。

同時,在磁盤格式方面他們是緊湊的以追加的方式産生的,因為他們并不需要進行随機通路。

3、Redis的資料類型?

答:

Redis支援五種資料類型: string(字元串)

1.hash(哈希)

2.list(清單)

3.set(集合)

4.及zsetsorted set:(有序集合)。

我們實際項目中比較常用的是string,hash如果你是Redis中進階使用者,還需要加上下面幾種資料結構HyperLogLog、Geo、Pub/Sub。

如果你說還玩過Redis Module,像 BloomFilter,RedisSearch,Redis-ML,面試官得眼睛就開始發亮了。

4、使用Redis有哪些好處?

答:

1、速度快,因為資料存在記憶體中,類似于HashMap,HashMap的優勢就是查找和操作的時間複雜度都是O1)

2、支援豐富資料類型,支援string,list,set,Zset,hash等

3、支援事務,操作都是原子性,所謂的原子性就是對資料的更改要麼全部執行,要麼全部不執行

4、豐富的特性:可用于緩存,消息,按key設定過期時間,過期後将會自動删除

5、Redis相比Memcached有哪些優勢?

答:

1、Memcached所有的值均是簡單的字元串,redis作為其替代者,支援更為豐富的資料類

2、Redis的速度比Memcached快很

3、Redis可以持久化其資料

6、Memcache與Redis的差別都有哪些?

答:

1、存儲方式Memecache把資料全部存在記憶體之中,斷電後會挂掉,資料不能超過記憶體大小。 Redis有部份存在硬碟上,這樣能保證資料的持久性。

2、資料支援類型Memcache對資料類型支援相對簡單。 Redis有複雜的資料類型。

3、使用底層模型不同 它們之間底層實作方式 以及與用戶端之間通信的應用協定不一樣。 Redis直接自己建構了VM機制 ,因為一般的系統調用系統函數的話,會浪費一定的時間去移動和請求。

7、Redis是單程序單線程的?

答:

Redis是單程序單線程的,redis利用隊列技術将并發通路變為串行通路,消除了傳統資料庫串行控制的開銷。

8、一個字元串類型的值能存儲最大容量是多少?

答:

512M。

9、Redis持久化機制。

答:

Redis是一個支援持久化的記憶體資料庫,通過持久化機制把記憶體中的資料同步到硬碟檔案來保證資料持久化。當Redis重新開機後通過把硬碟檔案重新加載到記憶體,就能達到恢複資料的目的。

實作:單獨建立fork()一個子程序,将目前父程序的資料庫資料複制到子程序的記憶體中,然後由子程序寫入到臨時檔案中,持久化的過程結束了,再用這個臨時檔案替換上次的快照檔案,然後子程序退出,記憶體釋放。

RDB是Redis預設的持久化方式。按照一定的時間周期政策把記憶體的資料以快照的形式儲存到硬碟的二進制檔案。即Snapshot快照存儲,對應産生的資料檔案為dump.rdb,通過配置檔案中的save參數來定義快照的周期。( 快照可以是其所表示的資料的一個副本,也可以是資料的一個複制品。)

AOF:Redis會将每一個收到的寫指令都通過Write函數追加到檔案最後,類似于MySQL的binlog。當Redis重新開機是會通過重新執行檔案中儲存的寫指令來在記憶體中重建整個資料庫的内容。當兩種方式同時開啟時,資料恢複Redis會優先選擇AOF恢複。

10、緩存雪崩、緩存穿透、緩存預熱、緩存更新、緩存降級等問題

答:

一、緩存雪崩

我們可以簡單的了解為:由于原有緩存失效,新緩存未到期間(例如:我們設定緩存時采用了相同的過期時間,在同一時刻出現大面積的緩存過期),所有原本應該通路緩存的請求都去查詢資料庫了,而對資料庫CPU和記憶體造成巨大壓力,嚴重的會造成資料庫當機。進而形成一系列連鎖反應,造成整個系統崩潰。

解決辦法:

大多數系統設計者考慮用加鎖( 最多的解決方案)或者隊列的方式保證來保證不會有大量的線程對資料庫一次性進行讀寫,進而避免失效時大量的并發請求落到底層存儲系統上。還有一個簡單方案就時講緩存失效時間分散開。

二、緩存穿透

緩存穿透是指使用者查詢資料,在資料庫沒有,自然在緩存中也不會有。這樣就導緻使用者查詢的時候,在緩存中找不到,每次都要去資料庫再查詢一遍,然後傳回空(相當于進行了兩次無用的查詢)。這樣請求就繞過緩存直接查資料庫,這也是經常提的緩存命中率問題。

解決辦法:

最常見的則是采用布隆過濾器,将所有可能存在的資料哈希到一個足夠大的bitmap中,一個一定不存在的資料會被這個bitmap攔截掉,進而避免了對底層存儲系統的查詢壓力。另外也有一個更為簡單粗暴的方法,如果一個查詢傳回的資料為空(不管是資料不存在,還是系統故障),我們仍然把這個空結果進行緩存,但它的過期時間會很短,最長不超過五分鐘。通過這個直接設定的預設值存放到緩存,這樣第二次到緩沖中擷取就有值了,而不會繼續通路資料庫,這種辦法最簡單粗暴。

5TB的硬碟上放滿了資料,請寫一個算法将這些資料進行排重。如果這些資料是一些32bit大小的資料該如何解決?如果是64bit的呢?

對于空間的利用到達了一種極緻,那就是Bitmap和布隆過濾器(Bloom Filter)。

Bitmap: 典型的就是哈希表

缺點是,Bitmap對于每個元素隻能記錄1bit資訊,如果還想完成額外的功能,恐怕隻能靠犧牲更多的空間、時間來完成了布隆過濾器(推薦) 就是引入了k(k>1)k(k>1)個互相獨立的哈希函數,保證在給定的空間、誤判率下,完成元素判重的過程。

它的優點是空間效率和查詢時間都遠遠超過一般的算法,缺點是有一定的誤識别率和删除困難。

Bloom-Filter算法的核心思想就是利用多個不同的Hash函數來解決“沖突”。

Hash存在一個沖突(碰撞)的問題,用同一個Hash得到的兩個URL的值有可能相同。為了減少沖突,我們可以多引入幾個Hash,如果通過其中的一個Hash值我們得出某元素不在集合中,那麼該元素肯定不在集合中。隻有在所有的Hash函數告訴我們該元素在集合中時,才能确定該元素存在于集合中。這便是Bloom-Filter的基本思想。

Bloom-Filter一般用于在大資料量的集合中判定某元素是否存在。

三、緩存預熱

緩存預熱這個應該是一個比較常見的概念,相信很多小夥伴都應該可以很容易的了解,緩存預熱就是系統上線後,将相關的緩存資料直接加載到緩存系統。這樣就可以避免在使用者請求的時候,先查詢資料庫,然後再将資料緩存的問題!使用者直接查詢事先被預熱的緩存資料!

解決思路:

1、直接寫個緩存重新整理頁面,上線時手工操作下;

2、資料量不大,可以在項目啟動的時候自動進行加載;

3、定時重新整理緩存

四、緩存更新

除了緩存伺服器自帶的緩存失效政策之外(Redis預設的有6中政策可供選擇),我們還可以根據具體的業務需求進行自定義的緩存淘汰,常見的政策有兩種:

(1)定時去清理過期的緩存;

(2)當有使用者請求過來時,再判斷這個請求所用到的緩存是否過期,過期的話就去底層系統得到新資料并更新緩存。

兩者各有優劣,第一種的缺點是維護大量緩存的key是比較麻煩的,第二種的缺點就是每次使用者請求過來都要判斷緩存失效,邏輯相對比較複雜!具體用哪種方案,大家可以根據自己的應用場景來權衡。

五、緩存降級

當通路量劇增、服務出現問題(如響應時間慢或不響應)或非核心服務影響到核心流程的性能時,仍然需要保證服務還是可用的,即使是有損服務。系統可以根據一些關鍵資料進行自動降級,也可以配置開關實作人工降級。

降級的最終目的是保證核心服務可用,即使是有損的。而且有些服務是無法降級的(如加入購物車、結算)。

以參考日志級别設定預案:

(1)一般:比如有些服務偶爾因為網絡抖動或者服務正在上線而逾時,可以自動降級;

(2)警告:有些服務在一段時間内成功率有波動(如在95~100%之間),可以自動降級或人工降級,并發送告警;

(3)錯誤:比如可用率低于90%,或者資料庫連接配接池被打爆了,或者通路量突然猛增到系統能承受的最大閥值,此時可以根據情況自動降級或者人工降級;

(4)嚴重錯誤:比如因為特殊原因資料錯誤了,此時需要緊急人工降級。服務降級的目的,是為了防止Redis服務故障,導緻資料庫跟着一起發生雪崩問題。是以,對于不重要的緩存資料,可以采取服務降級政策,例如一個比較常見的做法就是Redis出現問題,不去資料庫查詢,而是直接傳回預設值給使用者。

11、熱點資料和冷資料是什麼?

答:

熱點資料,緩存才有價值對于冷資料而言,大部分資料可能還沒有再次通路到就已經被擠出記憶體,不僅占用記憶體,而且價值不大。頻繁修改的資料,看情況考慮使用緩存對于上面兩個例子,壽星清單、導航資訊都存在一個特點,就是資訊修改頻率不高,讀取通常非常高的場景。

對于熱點資料,比如我們的某IM産品,生日祝福子產品,當天的壽星清單,緩存以後可能讀取數十萬次。再舉個例子,某導航産品,我們将導航資訊,緩存以後可能讀取數百萬次。

資料更新前至少讀取兩次,緩存才有意義。這個是最基本的政策,如果緩存還沒有起作用就失效了,那就沒有太大價值了。

那存不存在,修改頻率很高,但是又不得不考慮緩存的場景呢?有!比如,這個讀取接口對資料庫的壓力很大,但是又是熱點資料,這個時候就需要考慮通過緩存手段,減少資料庫的壓力,比如我們的某助手産品的,點贊數,收藏數,分享數等是非常典型的熱點資料,但是又不斷變化,此時就需要将資料同步儲存到Redis緩存,減少資料庫壓力。

12、單線程的redis為什麼這麼快?

答:

(一)純記憶體操作

(二)單線程操作,避免了頻繁的上下文切換

(三)采用了非阻塞I/O多路複用機制

13、redis的資料類型,以及每種資料類型的使用場景。

答:

一共五種

(一)String

這個其實沒啥好說的,最正常的set/get操作,value可以是String也可以是數字。一般做一些複雜的計數功能的緩存。

(二)hash

這裡value存放的是結構化的對象,比較友善的就是操作其中的某個字段。部落客在做單點登入的時候,就是用這種資料結構存儲使用者資訊,以cookieId作為key,設定30分鐘為緩存過期時間,能很好的模拟出類似session的效果。

(三)list

使用List的資料結構,可以做簡單的消息隊列的功能。另外還有一個就是,可以利用lrange指令,做基于redis的分頁功能,性能極佳,使用者體驗好。本人還用一個場景,很合适—取行情資訊。就也是個生産者和消費者的場景。LIST可以很好的完成排隊,先進先出的原則。

(四)set

因為set堆放的是一堆不重複值的集合。是以可以做全局去重的功能。為什麼不用JVM自帶的Set進行去重?因為我們的系統一般都是叢集部署,使用JVM自帶的Set,比較麻煩,難道為了一個做一個全局去重,再起一個公共服務,太麻煩了。

另外,就是利用交集、并集、差集等操作,可以計算共同喜好,全部的喜好,自己獨有的喜好等功能。

(五)sorted set

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

14、redis的過期政策以及記憶體淘汰機制。

答:

redis采用的是定期删除+惰性删除政策。

為什麼不用定時删除政策?

定時删除,用一個定時器來負責監視key,過期則自動删除。雖然記憶體及時釋放,但是十分消耗CPU資源。在大并發請求下,CPU要将時間應用在處理請求,而不是删除key,是以沒有采用這一政策。

定期删除+惰性删除是如何工作的呢?

定期删除,redis預設每個100ms檢查,是否有過期的key,有過期key則删除。需要說明的是,redis不是每個100ms将所有的key檢查一次,而是随機抽取進行檢查(如果每隔100ms,全部key進行檢查,redis豈不是卡死)。是以,如果隻采用定期删除政策,會導緻很多key到時間沒有删除。于是,惰性删除派上用場。也就是說在你擷取某個key的時候,redis會檢查一下。

這個key如果設定了過期時間那麼是否過期了?

如果過期了此時就會删除。

采用定期删除+惰性删除就沒其他問題了麼?

不是的,如果定期删除沒删除key。然後你也沒即時去請求key,也就是說惰性删除也沒生效。這樣,redis的記憶體會越來越高。那麼就應該采用記憶體淘汰機制。在redis.conf中有一行配置。

【2021最新版】Redis面試題總結(50道題含答案解析)總結

該配置就是配記憶體淘汰政策的(什麼,你沒配過?好好檢討一下自己)

volatile-lru:從已設定過期時間的資料集(server.db[i].expires)中挑選最近最少使用的資料淘汰

volatile-ttl:從已設定過期時間的資料集(server.db[i].expires)中挑選将要過期的資料淘汰

volatile-random:從已設定過期時間的資料集(server.db[i].expires)中任意選擇資料淘汰

allkeys-lru:從資料集(server.db[i].dict)中挑選最近最少使用的資料淘汰

allkeys-random:從資料集(server.db[i].dict)中任意選擇資料淘汰

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

ps:如果沒有設定expire的key, 不滿足先決條件(prerequisites); 那麼volatile-lru, volatile-random 和volatile-ttl政策的行為, 和

noeviction(不删除) 基本上一緻

15、Redis常見性能問題和解決方案?

答:

(1) Master 最好不要做任何持久化工作,如RDB記憶體快照和AOF日志檔案

(2) 如果資料比較重要,某個Slave開啟AOF備份資料,政策設定為每秒同步一次

(3) 為了主從複制的速度和連接配接的穩定性, Master和Slave最好在同一個區域網路内

(4) 盡量避免在壓力很大的主庫上增加從庫

(5) 主從複制不要用圖狀結構,用單向連結清單結構更為穩定,即: Master<- Slave1 <- Slave2 <-Slave3

16、為什麼Redis的操作是原子性的,怎麼保證原子性的?

答:

對于Redis而言,指令的原子性指的是:一個操作的不可以再分,操作要麼執行,要麼不執行。

Redis的操作之是以是原子性的,是因為Redis是單線程的。

Redis本身提供的所有API都是原子操作,Redis中的事務其實是要保證批量操作的原子性。

多個指令在并發中也是原子性的嗎?

不一定, 将get和set改成單指令操作,incr 。使用Redis的事務,或者使用Redis+Lua==的方式實作。

17、Redis事務。

答:

Redis事務功能是通過MULTI、EXEC、DISCARD和WATCH四個原語實作的

Redis會将一個事務中的所有指令序列化,然後按順序執行。

1.redis 不支援復原“Redis 在事務失敗時不進行復原,而是繼續執行餘下的指令”, 是以Redis的内部可以保持簡單且快速。

2.如果在一個事務中的指令出現錯誤,那麼所有的指令都不會執行;

3.如果在一個事務中出現運作錯誤,那麼正确的指令會被執行。

1)MULTI指令用于開啟一個事務,它總是傳回OK。 MULTI執行之後,用戶端可以繼續向伺服器發送任意多條指令,這些指令不會立即被執行,而是被放到一個隊列中,當EXEC指令被調用時,所有隊列中的指令才會被執行。

2)EXEC:執行所有事務塊内的指令。傳回事務塊内所有指令的傳回值,按指令執行的先後順序排列。當操作被打斷時,傳回空值 nil 。

3)通過調用DISCARD,用戶端可以清空事務隊列,并放棄執行事務, 并且用戶端會從事務狀态中退出。

4)WATCH指令可以為Redis 事務提供check-and-set(CAS)行為。 可以監控一個或多個鍵,一旦其中有一個鍵被修改(或删除),之後的事務就不會執行,監控一直持續到EXEC指令

18、Redis的持久化機制是什麼?各自的優缺點?

答:

Redis 提供兩種持久化機制 RDB 和 AOF 機制: 1、RDBRedis DataBase)持久化方式: 是指用資料集快照的方式半持久化模式)記錄 redis 資料庫的所有鍵值對,在某個時間點将資料寫入一個臨時檔案,持久化結束後,用這個臨時檔案替換上次持久化的檔案,達到資料恢複。

優點:

1、隻有一個檔案dump.rdb,友善持久化。

2、容災性好,一個檔案可以儲存到安全的磁盤。

3、性能最大化,fork子程序來完成寫操作,讓主程序繼續處理指令,是以是IO最大化。使用單獨子程序來進行持久化,主程序不會進行任何IO操作,保證了 redis的高性能)

4.相對于資料集大時,比AOF的啟動效率更高。

缺點:

1、資料安全性低。RDB是間隔一段時間進行持久化,如果持久化之間redis發生故障,會發生資料丢失。是以這種方式更适合資料要求不嚴謹的時候)

2、AOFAppend-only file)持久化方式: 是指所有的指令行記錄以redis指令請求協定的格式完全持久化存儲)儲存為aof檔案。

優點:

1、資料安全,aof持久化可以配置appendfsync屬性,有always,每進行一次指令操作就記錄到 aof 檔案中一次。

2、通過append模式寫檔案,即使中途伺服器當機,可以通過redis-check-aof工具解決資料一緻性問題。

3、AOF機制的rewrite模式。AOF檔案沒被rewrite之前(檔案過大時會對指令進行合并重寫),可以删除其中的某些指令(比如誤操作的flushall))

缺點:

1、AOF檔案比RDB檔案大,且恢複速度慢。

2、資料集大的時候,比rdb啟動效率低。

19、Redis常見性能問題和解決方案:

答:

1、Master最好不要寫記憶體快照,如果Master寫記憶體快照,save指令排程rdbSave函數,會阻塞主線程的工作,當快照比較大時對性能影響是非常大的,會間斷性暫停服務

2、如果資料比較重要,某個Slave開啟AOF備份資料,政策設定為每秒同步一

3、為了主從複制的速度和連接配接的穩定性,Master和Slave最好在同一個區域網路

4、盡量避免在壓力很大的主庫上增加從

5、主從複制不要用圖狀結構,用單向連結清單結構更為穩定,即:Master<- Slave1<- Slave2 <- Slave3這樣的結構友善解決單點故障問題,實作Slave對Master的替換。如果Master挂了,可以立刻啟用Slave1做Master,其他不變。

20、redis過期鍵的删除政策?

答:

1、定時删除:在設定鍵的過期時間的同時,建立一個定時器timer). 讓定時器在鍵的過期時間來臨時,立即執行對鍵的删除操作。

2、惰性删除:放任鍵過期不管,但是每次從鍵空間中擷取鍵時,都檢查取得的鍵是否過期,如果過期的話,就删除該鍵;如果沒有過期,就傳回該鍵。

3、定期删除:每隔一段時間程式就對資料庫進行一次檢查,删除裡面的過期鍵。至于要删除多少過期鍵,以及要檢查多少個資料庫,則由算法決定。

21、Redis的回收政策(淘汰政策)?

答:

volatile-lru:從已設定過期時間的資料集(server.db[i].expires)中挑選最近最少使用的資料淘汰

volatile-ttl:從已設定過期時間的資料集(server.db[i].expires)中挑選将要過期的資料淘汰

volatile-random:從已設定過期時間的資料集(server.db[i].expires)中任意選擇資料淘汰

allkeys-lru:從資料集(server.db[i].dict)中挑選最近最少使用的資料淘汰

allkeys-random:從資料集(server.db[i].dict)中任意選擇資料淘汰

no-enviction(驅逐):禁止驅逐資料

注意這裡的 6 種機制,volatile 和 allkeys 規定了是對已設定過期時間的資料集淘汰資料還是從全部資料集淘汰資料,後面的

lru、ttl 以及 random 是三種不同的淘汰政策,再加上一種 no-enviction 永不回收的政策

使用政策規則:

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

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

22、為什麼Redis需要把所有資料放到記憶體中?

答:

Redis為了達到最快的讀寫速度将資料都讀到記憶體中,并通過異步的方式将資料寫入磁盤。是以redis具有快速和資料持久化的特征。如果不将資料放在記憶體中,磁盤I/O速度為嚴重影響redis的性能。在記憶體越來越便宜的今,redis将會越來越受歡迎。如果設定了最大使用的記憶體,則資料已有記錄數達到記憶體限值後不能繼續插入新值。

23、Redis的同步機制了解麼?

答:

Redis可以使用主從同步,從從同步。第一次同步時,主節點做一次bgsave,并同時将後續修改操作記錄到記憶體buffer,待完成後将rdb檔案全量同步到複制節點,複制節點接受完成後将rdb鏡像加載到記憶體。加載完成後,再通知主節點将期間修改的操作記錄同步到複制節點進行重放就完成了同步過程。

24、Pipeline有什麼好處,為什麼要用pipeline?

答:

可以将多次IO往返的時間縮減為一次,前提是pipeline執行的指令之間沒有因果相關性。使用redis-benchmark進行壓測的時候可以發現影響redis的QPS峰值的一個重要因素是pipeline批次指令的數目。

25、是否使用過Redis叢集,叢集的原理是什麼?

答:

1)、Redis Sentinal 着眼于高可用,在 master 當機時會自動将 slave 提升為master,繼續提供服務。

2)、Redis Cluster 着眼于擴充性,在單個 redis 記憶體不足時,使用 Cluster 進行分片存儲。

26、Redis叢集方案什麼情況下會導緻整個叢集不可用?

答:

有 A,B,C 三個節點的叢集,在沒有複制模型的情況下,如果節點B失敗了,那麼整個叢集就會以為缺少5501-11000這個範圍的槽而不可用。

27、Redis支援的Java用戶端都有哪些?官方推薦用哪個?

答:

Redisson、Jedis、lettuce等等,官方推薦使用Redisson。

28、Jedis與Redisson對比有什麼優缺點?

答:

Jedis是Redis的Java實作的用戶端,其API提供了比較全面的Redis 指令的支援;Redisson實作了分布式和可擴充的Java 資料結構,和Jedis相比,功能較為簡單,不支援字元串操作,不支援排序、事務、管道、分區等Redis特性。Redisson 的宗旨是促進使用者對Redis的關注分離,進而讓使用者能夠将精力更集中地放在處理業務邏輯上。

29、Redis如何設定密碼及驗證密碼?

答:

設定密碼:config set requirepass 123456

授權密碼:auth 123456

30、說說Redis哈希槽的概念?

答:

Redis叢集沒有使用一緻性hash,而是引入了哈希槽的概念,Redis叢集有16384個哈希槽,每個key通過CRC16校驗後對16384 取模來決定放置哪個槽,叢集的每個節點負責一部分hash槽。

31、Redis叢集的主從複制模型是怎樣的?

答:

為了使在部分節點失敗或者大部分節點無法通信的情況下叢集仍然可用,是以叢集使用了主從複制模型,每個節點都會有N-1 個複制品。

32、Redis叢集會有寫操作丢失嗎?為什麼?

答:

Redis并不能保證資料的強一緻性,這意味這在實際中叢集在特定的條件下可能會丢失寫操作。

33、Redis叢集之間是如何複制的?

答:

異步複制。

34、Redis叢集最大節點個數是多少?

答:

16384個。

35、Redis叢集如何選擇資料庫?

答:

Redis叢集目前無法做資料庫選擇,預設在0資料庫。

36、怎麼測試Redis的連通性?

答:

使用ping指令。

37、怎麼了解Redis事務?

答:

1)事務是一個單獨的隔離操作:事務中的所有指令都會序列化、按順序地執行。事務在執行的過程中,不會被其他用戶端發送來的指令請求所打斷。

2)事務是一個原子操作:事務中的指令要麼全部被執行,要麼全部都不執行。

38、Redis事務相關的指令有哪幾個?

答:

MULTI、EXEC、DISCARD、WATCH。

39、Redis key的過期時間和永久有效分别怎麼設定?

答:

EXPIRE和PERSIST指令。

40、Redis如何做記憶體優化?

答:

盡可能使用散清單(hashes),散清單(是說散清單裡面存儲的數少)使用的記憶體非常小,是以你應該盡可能的将你的資料模型抽象到一個散清單裡面。比如你的web系統中有一個使用者對象,不要為這個使用者的名稱,姓氏,郵箱,密碼設定單獨的key,而是應該把這個使用者的所有資訊存儲到一張散清單裡面。

41、Redis回收程序如何工作的?

答:

一個用戶端運作了新的指令,添加了新的資料。Redi檢查記憶體使用情況,如果大于maxmemory的限制, 則根據設定好的政策進行回收。

一個新的指令被執行,等等。是以我們不斷地穿越記憶體限制的邊界,通過不斷達到邊界然後不斷地回收回到邊界以下。如果一個指令的結果導緻大量記憶體被使用(例如很大的集合的交集儲存到一個新的鍵),不用多久記憶體限制就會被這個記憶體使用量超越。

42、都有哪些辦法可以降低Redis的記憶體使用情況呢?

答:

如果你使用的是32位的 Redis 執行個體,可以好好利用Hash,list,sorted set,set等集合類型資料,因為通常情況下很多小的Key-Value可以用更緊湊的方式存放到一起。

43、Redis的記憶體用完了會發生什麼?

答:

如果達到設定的上限,Redis的寫指令會傳回錯誤資訊(但是讀指令還可以正常傳回。)或者你可以将Redis當緩存來使用配置淘汰機制,當Redis達到記憶體上限時會沖刷掉舊的内容。

44、一個 Redis執行個體最多能存放多少的 keys?List、Set、Sorted Set他們最多能存放多少元素?

答:

理論上Redis可以處理多達232的keys,并且在實際中進行了測試,每個執行個體至少存放了2億5千萬的keys。我們正在測試一些較大的值。任何list、set、和sorted set都可以放232個元素。換句話說,Redis的存儲極限是系統中的可用記憶體值

45、MySQL裡有2000w資料,redis中隻存20w的資料,如何保證redis中的資料都是熱點資料?

答:

Redis記憶體資料集大小上升到一定大小的時候,就會施行資料淘汰政策。

相關知識:Redis提供6種資料淘汰政策:

volatile-lru:從已設定過期時間的資料集(server.db[i].expires)中挑選最近最少使用的資料淘汰

volatile-ttl:從已設定過期時間的資料集(server.db[i].expires)中挑選将要過期的資料淘汰

volatile-random:從已設定過期時間的資料集(server.db[i].expires)中任意選擇資料淘汰

allkeys-lru:從資料集(server.db[i].dict)中挑選最近最少使用的資料淘汰

allkeys-random:從資料集(server.db[i].dict)中任意選擇資料淘汰

no-enviction(驅逐):禁止驅逐資料

46、Redis最适合的場景?

答:

1、會話緩存(Session Cache)

最常用的一種使用 Redis 的情景是會話緩存(session cache)。用 Redis 緩存會話比其他存儲(如 Memcached)的優勢在于:Redis 提供持久化。當維護一個不是嚴格要求一緻性的緩存時,如果使用者的購物車資訊全部丢失,大部分人都會不高興的,現在,他們還會這樣嗎?

幸運的是,随着 Redis 這些年的改進,很容易找到怎麼恰當的使用 Redis 來緩存會話的文檔。甚至廣為人知的商業平台Magento 也提供 Redis 的插件。

2、全頁緩存(FPC)

除基本的會話token之外,Redis還提供很簡便的FPC平台。回到一緻性問題,即使重新開機了 Redis執行個體,因為有磁盤的持久化,使用者也不會看到頁面加載速度的下降,這是一個極大改進,類似PHP本地 FPC。 再次以agento為例,Magento提供一個插件來使用 Redis 作為全頁緩存後端。 此外,對WordPress的使用者來說,Pantheon有一個非常好的插件 wp-redis,這個插件能幫助你以最快速度加載你曾浏覽過的頁面。

3、隊列

Reids 在記憶體存儲引擎領域的一大優點是提供 list 和 set 操作,這使得 Redis能作為一個很好的消息隊列平台來使用。Redis 作為隊列使用的操作,就類似于本地程式語言(如 Python)對list的push/pop操作。 如果你快速的在Google中搜尋“Redisqueues”,你馬上就能找到大量的開源項目,這些項目的目的就是利用Redis建立非常好的後端工具,以滿足各種隊列需求。例如,Celery有一個背景就是使用Redis作為 broker,你可以從這裡去檢視。

4,排行榜/計數器

Redis 在記憶體中對數字進行遞增或遞減的操作實作的非常好。集合(Set)和有序集合(Sorted Set)也使得我們在執行這些操作的時候變的非常簡單,Redis 隻是正好提供了這兩種資料結構。是以,我們要從排序集合中擷取到排名最靠前的 10個使用者–我們稱之為“user_scores”,我們隻需要像下面一樣執行即可: 當然,這是假定你是根據你使用者的分數做遞增的排序。如果你想傳回使用者及使用者的分數,你需要這樣執行: ZRANGE user_scores 0 10 WITHSCORES Agora Games就是一個很好的例子,用 Ruby 實作的,它的排行榜就是使用 Redis 來存儲資料的,你可以在這裡看到

5、釋出/訂閱

最後(但肯定不是最不重要的)是Redis的釋出/訂閱功能。釋出/訂閱的使用場景确實非常多。我已看見人們在社交網絡連接配接中使用,還可作為基于釋出/訂閱的腳本觸發器,甚至用Redis的釋出/訂閱功能來建立聊天系統!

47、假如Redis裡面有1億個key,其中有10w個key是以某個固定的已知的字首開頭的,如果将它們全部找出來?

答:

使用 keys 指令可以掃出指定模式的 key 清單。 對方接着追問:如果這個 redis 正在給線上的業務提供服務,那使用 keys 指令會有什麼問題?

這個時候你要回答redis關鍵的一個特性:redis的單線程的。keys指令會導緻線程阻塞一段時間,線上服務會停頓,直到指令執行完畢,服務才能恢複。這個時候可以使用scan指令,scan指令可以無阻塞的提取出指定模式的key清單,但是會有一定的重複機率,在用戶端做一次去重就可以了,但是整體所花費的時間會比直接用keys指令長。

48、如果有大量的key需要設定同一時間過期,一般需要注意什麼?

答:

如果大量的key過期時間設定的過于集中,到過期的那個時間點,redis可能會出現短暫的卡頓現象。一般需要在時間上加一個随機值,使得過期時間分散一些。

49、使用過Redis做異步隊列麼,你是怎麼用的?

答:

一般使用 list 結構作為隊列,rpush生産消息,lpop消費消息。當lpop沒有消息的時候,要适當sleep一會再重試。

如果對方追問可不可以不用sleep呢?

list 還有個指令叫blpop,在沒有消息的時候,它會阻塞住直到消息到來。如果對方追問能不能生産一次消費多次呢?使用 pub/sub主題訂閱者模式,可以實作1:N的消息隊列。

如果對方追問pub/sub有什麼缺點?

在消費者下線的情況下,生産的消息會丢失,得使用專業的消息隊列如RabbitMQ等。

如果對方追問redis如何實作延時隊列?

我估計現在你很想把面試官一棒打死如果你手上有一根棒球棍的話,怎麼問的這麼詳細。但是你很克制,然後神态自若的回答道:使用sortedset,拿時間戳作為score,消息内容作為key調用zadd來生産消息,消費者用zrangebyscore指令擷取N秒之前的資料輪詢進行處理。到這裡,面試官暗地裡已經對你豎起了大拇指。但是他不知道的是此刻你卻豎起了中指,在椅子背後。

50、使用過Redis分布式鎖麼,它是什麼回事?

答:

先拿setnx來争搶鎖,搶到之後,再用expire給鎖加一個過期時間防止鎖忘記了釋放。

這時候對方會告訴你說你回答得不錯,然後接着問如果在setnx之後執行expire之前程序意外crash或者要重新開機維護了,那會怎麼樣?

這時候你要給予驚訝的回報:唉,是喔,這個鎖就永遠得不到釋放了。緊接着你需要抓一抓自己得腦袋,故作思考片刻,好像接下來的結果是你主動思考出來的。

然後回答:我記得set指令有非常複雜的參數,這個應該是可以同時把setnx 和expire合成一條指令來用的!對方這時會顯露笑容,心裡開始默念:摁,這小子還不錯。

總結

該面試題答案解析完整文檔擷取方式:

版權聲明:本文為CSDN部落客「m0_48795607」的原創文章,遵循CC 4.0 BY-SA版權協定,轉載請附上原文出處連結及本聲明。

原文連結:https://blog.csdn.net/m0_48795607/article/details/115642129