1. 程式人生 > >轉載 redis面試題

轉載 redis面試題


   

   
1、什麼是Redis?
答:Redis全稱為:Remote Dictionary Server(遠端資料服務),是一個基於記憶體的高效能key-value資料庫。
2、Redis的資料型別?

答:Redis支援五種資料型別:string(字串),hash(雜湊),list(列表),set(集合)及zset(sorted set:有序集合)。

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

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

3、使用Redis有哪些好處?

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

(2) 支援豐富資料型別,支援string,list,set,Zset,hash等

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

(4) 豐富的特性:可用於快取,訊息,按key設定過期時間,過期後將會自動刪除

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

(1) Memcached所有的值均是簡單的字串,redis作為其替代者,支援更為豐富的資料型別

(2) Redis的速度比Memcached快很多

(3) Redis可以持久化其資料

5、Memcache與Redis的區別都有哪些?

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

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

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

6、Redis是單程序單執行緒的?
答:Redis是單程序單執行緒的,redis利用佇列技術將併發訪問變為序列訪問,消除了傳統資料庫序列控制的開銷。
7、一個字串型別的值能儲存最大容量是多少?
答:512M
8、Redis的持久化機制是什麼?各自的優缺點?

Redis提供兩種持久化機制RDB和AOF機制:

1)RDB(Redis DataBase)持久化方式: 是指用資料集快照的方式(半持久化模式)記錄redis資料庫的所有鍵值對,在某個時間點將資料寫入一個臨時檔案,持久化結束後,用這個臨時檔案替換上次持久化的檔案,達到資料恢復。 

 優點:   

1.只有一個檔案dump.rdb,方便持久化。   

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

3.效能最大化,fork子程序來完成寫操作,讓主程序繼續處理命令,所以是IO最大化。(使用單獨子程序來進行持久化,主程序不會進行任何IO操作,保證了redis的高效能) 4.相對於資料集大時,比AOF的啟動效率更高。 

 缺點:   

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

2)AOF(Append-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啟動效率低。

9、Redis常見效能問題和解決方案:

(1) Master最好不要寫記憶體快照,如果Master寫記憶體快照,save命令排程rdbSave函式,會阻塞主執行緒的工作,當快照比較大時對效能影響是非常大的,會間斷性暫停服務。

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

(3) 為了主從複製的速度和連線的穩定性,Master和Slave最好在同一個區域網內

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

(5) 主從複製不要用圖狀結構,用單向連結串列結構更為穩定,即:Master <- Slave1 <- Slave2 <- Slave3...這樣的結構方便解決單點故障問題,實現Slave對Master的替換。如果Master掛了,可以立刻啟用Slave1做Master,其他不變。

10、redis過期鍵的刪除策略?

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

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

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

11、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、如果資料呈現平等分佈,也就是所有的資料訪問頻率都相同,則使用allkeys-random

12、為什麼edis需要把所有資料放到記憶體中?
答:Redis為了達到最快的讀寫速度將資料都讀到記憶體中,並通過非同步的方式將資料寫入磁碟。所以redis具有快速和資料持久化的特徵。如果不將資料放在記憶體中,磁碟I/O速度為嚴重影響redis的效能。在記憶體越來越便宜的今天,redis將會越來越受歡迎。如果設定了最大使用的記憶體,則資料已有記錄數達到記憶體限值後不能繼續插入新值。
13、Redis的同步機制瞭解麼?
答:Redis可以使用主從同步,從從同步。第一次同步時,主節點做一次bgsave,並同時將後續修改操作記錄到記憶體buffer,待完成後將rdb檔案全量同步到複製節點,複製節點接受完成後將rdb映象載入到記憶體。載入完成後,再通知主節點將期間修改的操作記錄同步到複製節點進行重放就完成了同步過程。
14、Pipeline有什麼好處,為什麼要用pipeline?
答:可以將多次IO往返的時間縮減為一次,前提是pipeline執行的指令之間沒有因果相關性。使用redis-benchmark進行壓測的時候可以發現影響redis的QPS峰值的一個重要因素是pipeline批次指令的數目。
15、是否使用過Redis叢集,叢集的原理是什麼?

(1)、Redis Sentinal著眼於高可用,在master宕機時會自動將slave提升為master,繼續提供服務。

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

16、Redis叢集方案什麼情況下會導致整個叢集不可用?
答:有A,B,C三個節點的叢集,在沒有複製模型的情況下,如果節點B失敗了,那麼整個叢集就會以為缺少5501-11000這個範圍的槽而不可用。
17、Redis支援的Java客戶端都有哪些?官方推薦用哪個?
答:Redisson、Jedis、lettuce等等,官方推薦使用Redisson。
18、Jedis與Redisson對比有什麼優缺點?
答:Jedis是Redis的Java實現的客戶端,其API提供了比較全面的Redis命令的支援;Redisson實現了分散式和可擴充套件的Java資料結構,和Jedis相比,功能較為簡單,不支援字串操作,不支援排序、事務、管道、分割槽等Redis特性。Redisson的宗旨是促進使用者對Redis的關注分離,從而讓使用者能夠將精力更集中地放在處理業務邏輯上。
19、Redis如何設定密碼及驗證密碼?

設定密碼:config set requirepass 123456

授權密碼:auth 123456

20、說說Redis雜湊槽的概念?
答:Redis叢集沒有使用一致性hash,而是引入了雜湊槽的概念,Redis叢集有16384個雜湊槽,每個key通過CRC16校驗後對16384取模來決定放置哪個槽,叢集的每個節點負責一部分hash槽。
21、Redis叢集的主從複製模型是怎樣的?
答:為了使在部分節點失敗或者大部分節點無法通訊的情況下叢集仍然可用,所以叢集使用了主從複製模型,每個節點都會有N-1個複製品.
22、Redis叢集會有寫操作丟失嗎?為什麼?
答:Redis並不能保證資料的強一致性,這意味這在實際中叢集在特定的條件下可能會丟失寫操作。
23、Redis叢集之間是如何複製的?
答:非同步複製
24、Redis叢集最大節點個數是多少?
答:16384個。
25、Redis叢集如何選擇資料庫?
答:Redis叢集目前無法做資料庫選擇,預設在0資料庫。
26、怎麼測試Redis的連通性?
答:使用ping命令。
27、怎麼理解Redis事務?

答: 

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

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

28、Redis事務相關的命令有哪幾個?
答:MULTI、EXEC、DISCARD、WATCH
29、Redis key的過期時間和永久有效分別怎麼設定?
答:EXPIRE和PERSIST命令。
30、Redis如何做記憶體優化?
答:儘可能使用散列表(hashes),散列表(是說散列表裡面儲存的數少)使用的記憶體非常小,所以你應該儘可能的將你的資料模型抽象到一個散列表裡面。比如你的web系統中有一個使用者物件,不要為這個使用者的名稱,姓氏,郵箱,密碼設定單獨的key,而是應該把這個使用者的所有資訊儲存到一張散列表裡面.
31、Redis回收程序如何工作的?
答:一個客戶端運行了新的命令,添加了新的資料。Redi檢查記憶體使用情況,如果大於maxmemory的限制, 則根據設定好的策略進行回收。一個新的命令被執行,等等。所以我們不斷地穿越記憶體限制的邊界,通過不斷達到邊界然後不斷地回收回到邊界以下。如果一個命令的結果導致大量記憶體被使用(例如很大的集合的交集儲存到一個新的鍵),不用多久記憶體限制就會被這個記憶體使用量超越。
32、都有哪些辦法可以降低Redis的記憶體使用情況呢?
答:如果你使用的是32位的Redis例項,可以好好利用Hash,list,sorted set,set等集合型別資料,因為通常情況下很多小的Key-Value可以用更緊湊的方式存放到一起。
33、Redis的記憶體用完了會發生什麼?
答:如果達到設定的上限,Redis的寫命令會返回錯誤資訊(但是讀命令還可以正常返回。)或者你可以將Redis當快取來使用配置淘汰機制,當Redis達到記憶體上限時會沖刷掉舊的內容。
34、一個Redis例項最多能存放多少的keys?List、Set、Sorted Set他們最多能存放多少元素?
答:理論上Redis可以處理多達232的keys,並且在實際中進行了測試,每個例項至少存放了2億5千萬的keys。我們正在測試一些較大的值。任何list、set、和sorted set都可以放232個元素。換句話說,Redis的儲存極限是系統中的可用記憶體值。
35、MySQL裡有2000w資料,redis中只存20w的資料,如何保證redis中的資料都是熱點資料?

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

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

 voltile-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(驅逐):禁止驅逐資料

36、Redis最適合的場景?

(1)、會話快取(Session Cache) 

 最常用的一種使用Redis的情景是會話快取(session cache)。用Redis快取會話比其他儲存(如Memcached)的優勢在於:Redis提供持久化。當維護一個不是嚴格要求一致性的快取時,如果使用者的購物車資訊全部丟失,大部分人都會不高興的,現在,他們還會這樣嗎? 幸運的是,隨著 Redis 這些年的改進,很容易找到怎麼恰當的使用Redis來快取會話的文件。甚至廣為人知的商業平臺Magento也提供Redis的外掛。

(2)、全頁快取(FPC)

 除基本的會話token之外,Redis還提供很簡便的FPC平臺。回到一致性問題,即使重啟了Redis例項,因為有磁碟的持久化,使用者也不會看到頁面載入速度的下降,這是一個極大改進,類似PHP本地FPC。 再次以Magento為例,Magento提供一個外掛來使用Redis作為全頁快取後端。 此外,對WordPress的使用者來說,Pantheon有一個非常好的外掛 wp-redis,這個外掛能幫助你以最快速度載入你曾瀏覽過的頁面。

(3)、佇列 

 Reids在記憶體儲存引擎領域的一大優點是提供 list 和 set 操作,這使得Redis能作為一個很好的訊息佇列平臺來使用。Redis作為佇列使用的操作,就類似於本地程式語言(如Python)對 list 的 push/pop 操作。 如果你快速的在Google中搜索“Redis queues”,你馬上就能找到大量的開源專案,這些專案的目的就是利用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的釋出/訂閱功能來建立聊天系統!

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

答:使用keys指令可以掃出指定模式的key列表。

對方接著追問:如果這個redis正在給線上的業務提供服務,那使用keys指令會有什麼問題?

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

38、如果有大量的key需要設定同一時間過期,一般需要注意什麼?
答:如果大量的key過期時間設定的過於集中,到過期的那個時間點,redis可能會出現短暫的卡頓現象。一般需要在時間上加一個隨機值,使得過期時間分散一些。
39、使用過Redis做非同步佇列麼,你是怎麼用的?

答:一般使用list結構作為佇列,rpush生產訊息,lpop消費訊息。當lpop沒有訊息的時候,要適當sleep一會再重試。

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

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

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

在消費者下線的情況下,生產的訊息會丟失,得使用專業的訊息佇列如RabbitMQ等。

如果對方追問redis如何實現延時佇列?

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

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

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

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

這時候你要給予驚訝的反饋:唉,是喔,這個鎖就永遠得不到釋放了。緊接著你需要抓一抓自己得腦袋,故作思考片刻,好像接下來的結果是你主動思考出來的,然後回答:我記得set指令有非常複雜的引數,這個應該是可以同時把setnx和expire合成一條指令來用的!對方這時會顯露笑容,心裡開始默唸:摁,這小子還不錯。

注:另有需要JAVA、Android、IOS、Python、C++、HTML5等全套程式設計視訊教程的朋友,請關注微信公眾號trteach圖靈技術社群”獲取資源~~~


 

 
1、什麼是Redis?
答:Redis全稱為:Remote Dictionary Server(遠端資料服務),是一個基於記憶體的高效能key-value資料庫。
2、Redis的資料型別?

答:Redis支援五種資料型別:string(字串),hash(雜湊),list(列表),set(集合)及zset(sorted set:有序集合)。

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

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

3、使用Redis有哪些好處?

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

(2) 支援豐富資料型別,支援string,list,set,Zset,hash等

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

(4) 豐富的特性:可用於快取,訊息,按key設定過期時間,過期後將會自動刪除

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

(1) Memcached所有的值均是簡單的字串,redis作為其替代者,支援更為豐富的資料型別

(2) Redis的速度比Memcached快很多

(3) Redis可以持久化其資料

5、Memcache與Redis的區別都有哪些?

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

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

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

6、Redis是單程序單執行緒的?
答:Redis是單程序單執行緒的,redis利用佇列技術將併發訪問變為序列訪問,消除了傳統資料庫序列控制的開銷。
7、一個字串型別的值能儲存最大容量是多少?
答:512M
8、Redis的持久化機制是什麼?各自的優缺點?

Redis提供兩種持久化機制RDB和AOF機制:

1)RDB(Redis DataBase)持久化方式: 是指用資料集快照的方式(半持久化模式)記錄redis資料庫的所有鍵值對,在某個時間點將資料寫入一個臨時檔案,持久化結束後,用這個臨時檔案替換上次持久化的檔案,達到資料恢復。 

 優點:   

1.只有一個檔案dump.rdb,方便持久化。   

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

3.效能最大化,fork子程序來完成寫操作,讓主程序繼續處理命令,所以是IO最大化。(使用單獨子程序來進行持久化,主程序不會進行任何IO操作,保證了redis的高效能) 4.相對於資料集大時,比AOF的啟動效率更高。 

 缺點:   

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

2)AOF(Append-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啟動效率低。

9、Redis常見效能問題和解決方案:

(1) Master最好不要寫記憶體快照,如果Master寫記憶體快照,save命令排程rdbSave函式,會阻塞主執行緒的工作,當快照比較大時對效能影響是非常大的,會間斷性暫停服務。

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

(3) 為了主從複製的速度和連線的穩定性,Master和Slave最好在同一個區域網內

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

(5) 主從複製不要用圖狀結構,用單向連結串列結構更為穩定,即:Master <- Slave1 <- Slave2 <- Slave3...這樣的結構方便解決單點故障問題,實現Slave對Master的替換。如果Master掛了,可以立刻啟用Slave1做Master,其他不變。

10、redis過期鍵的刪除策略?

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

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

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

11、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、如果資料呈現平等分佈,也就是所有的資料訪問頻率都相同,則使用allkeys-random

12、為什麼edis需要把所有資料放到記憶體中?
答:Redis為了達到最快的讀寫速度將資料都讀到記憶體中,並通過非同步的方式將資料寫入磁碟。所以redis具有快速和資料持久化的特徵。如果不將資料放在記憶體中,磁碟I/O速度為嚴重影響redis的效能。在記憶體越來越便宜的今天,redis將會越來越受歡迎。如果設定了最大使用的記憶體,則資料已有記錄數達到記憶體限值後不能繼續插入新值。
13、Redis的同步機制瞭解麼?
答:Redis可以使用主從同步,從從同步。第一次同步時,主節點做一次bgsave,並同時將後續修改操作記錄到記憶體buffer,待完成後將rdb檔案全量同步到複製節點,複製節點接受完成後將rdb映象載入到記憶體。載入完成後,再通知主節點將期間修改的操作記錄同步到複製節點進行重放就完成了同步過程。
14、Pipeline有什麼好處,為什麼要用pipeline?
答:可以將多次IO往返的時間縮減為一次,前提是pipeline執行的指令之間沒有因果相關性。使用redis-benchmark進行壓測的時候可以發現影響redis的QPS峰值的一個重要因素是pipeline批次指令的數目。
15、是否使用過Redis叢集,叢集的原理是什麼?

(1)、Redis Sentinal著眼於高可用,在master宕機時會自動將slave提升為master,繼續提供服務。

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

16、Redis叢集方案什麼情況下會導致整個叢集不可用?
答:有A,B,C三個節點的叢集,在沒有複製模型的情況下,如果節點B失敗了,那麼整個叢集就會以為缺少5501-11000這個範圍的槽而不可用。
17、Redis支援的Java客戶端都有哪些?官方推薦用哪個?
答:Redisson、Jedis、lettuce等等,官方推薦使用Redisson。
18、Jedis與Redisson對比有什麼優缺點?
答:Jedis是Redis的Java實現的客戶端,其API提供了比較全面的Redis命令的支援;Redisson實現了分散式和可擴充套件的Java資料結構,和Jedis相比,功能較為簡單,不支援字串操作,不支援排序、事務、管道、分割槽等Redis特性。Redisson的宗旨是促進使用者對Redis的關注分離,從而讓使用者能夠將精力更集中地放在處理業務邏輯上。
19、Redis如何設定密碼及驗證密碼?

設定密碼:config set requirepass 123456

授權密碼:auth 123456

20、說說Redis雜湊槽的概念?
答:Redis叢集沒有使用一致性hash,而是引入了雜湊槽的概念,Redis叢集有16384個雜湊槽,每個key通過CRC16校驗後對16384取模來決定放置哪個槽,叢集的每個節點負責一部分hash槽。
21、Redis叢集的主從複製模型是怎樣的?
答:為了使在部分節點失敗或者大部分節點無法通訊的情況下叢集仍然可用,所以叢集使用了主從複製模型,每個節點都會有N-1個複製品.
22、Redis叢集會有寫操作丟失嗎?為什麼?
答:Redis並不能保證資料的強一致性,這意味這在實際中叢集在特定的條件下可能會丟失寫操作。
23、Redis叢集之間是如何複製的?
答:非同步複製
24、Redis叢集最大節點個數是多少?
答:16384個。
25、Redis叢集如何選擇資料庫?
答:Redis叢集目前無法做資料庫選擇,預設在0資料庫。
26、怎麼測試Redis的連通性?
答:使用ping命令。
27、怎麼理解Redis事務?

答: 

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

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

28、Redis事務相關的命令有哪幾個?
答:MULTI、EXEC、DISCARD、WATCH
29、Redis key的過期時間和永久有效分別怎麼設定?
答:EXPIRE和PERSIST命令。
30、Redis如何做記憶體優化?
答:儘可能使用散列表(hashes),散列表(是說散列表裡面儲存的數少)使用的記憶體非常小,所以你應該儘可能的將你的資料模型抽象到一個散列表裡面。比如你的web系統中有一個使用者物件,不要為這個使用者的名稱,姓氏,郵箱,密碼設定單獨的key,而是應該把這個使用者的所有資訊儲存到一張散列表裡面.
31、Redis回收程序如何工作的?
答:一個客戶端運行了新的命令,添加了新的資料。Redi檢查記憶體使用情況,如果大於maxmemory的限制, 則根據設定好的策略進行回收。一個新的命令被執行,等等。所以我們不斷地穿越記憶體限制的邊界,通過不斷達到邊界然後不斷地回收回到邊界以下。如果一個命令的結果導致大量記憶體被使用(例如很大的集合的交集儲存到一個新的鍵),不用多久記憶體限制就會被這個記憶體使用量超越。
32、都有哪些辦法可以降低Redis的記憶體使用情況呢?
答:如果你使用的是32位的Redis例項,可以好好利用Hash,list,sorted set,set等集合型別資料,因為通常情況下很多小的Key-Value可以用更緊湊的方式存放到一起。
33、Redis的記憶體用完了會發生什麼?
答:如果達到設定的上限,Redis的寫命令會返回錯誤資訊(但是讀命令還可以正常返回。)或者你可以將Redis當快取來使用配置淘汰機制,當Redis達到記憶體上限時會沖刷掉舊的內容。
34、一個Redis例項最多能存放多少的keys?List、Set、Sorted Set他們最多能存放多少元素?
答:理論上Redis可以處理多達232的keys,並且在實際中進行了測試,每個例項至少存放了2億5千萬的keys。我們正在測試一些較大的值。任何list、set、和sorted set都可以放232個元素。換句話說,Redis的儲存極限是系統中的可用記憶體值。
35、MySQL裡有2000w資料,redis中只存20w的資料,如何保證redis中的資料都是熱點資料?

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

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

 voltile-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(驅逐):禁止驅逐資料

36、Redis最適合的場景?

(1)、會話快取(Session Cache) 

 最常用的一種使用Redis的情景是會話快取(session cache)。用Redis快取會話比其他儲存(如Memcached)的優勢在於:Redis提供持久化。當維護一個不是嚴格要求一致性的快取時,如果使用者的購物車資訊全部丟失,大部分人都會不高興的,現在,他們還會這樣嗎? 幸運的是,隨著 Redis 這些年的改進,很容易找到怎麼恰當的使用Redis來快取會話的文件。甚至廣為人知的商業平臺Magento也提供Redis的外掛。

(2)、全頁快取(FPC)

 除基本的會話token之外,Redis還提供很簡便的FPC平臺。回到一致性問題,即使重啟了Redis例項,因為有磁碟的持久化,使用者也不會看到頁面載入速度的下降,這是一個極大改進,類似PHP本地FPC。 再次以Magento為例,Magento提供一個外掛來使用Redis作為全頁快取後端。 此外,對WordPress的使用者來說,Pantheon有一個非常好的外掛 wp-redis,這個外掛能幫助你以最快速度載入你曾瀏覽過的頁面。

(3)、佇列 

 Reids在記憶體儲存引擎領域的一大優點是提供 list 和 set 操作,這使得Redis能作為一個很好的訊息佇列平臺來使用。Redis作為佇列使用的操作,就類似於本地程式語言(如Python)對 list 的 push/pop 操作。 如果你快速的在Google中搜索“Redis queues”,你馬上就能找到大量的開源專案,這些專案的目的就是利用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的釋出/訂閱功能來建立聊天系統!

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

答:使用keys指令可以掃出指定模式的key列表。

對方接著追問:如果這個redis正在給線上的業務提供服務,那使用keys指令會有什麼問題?

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

38、如果有大量的key需要設定同一時間過期,一般需要注意什麼?
答:如果大量的key過期時間設定的過於集中,到過期的那個時間點,redis可能會出現短暫的卡頓現象。一般需要在時間上加一個隨機值,使得過期時間分散一些。
39、使用過Redis做非同步佇列麼,你是怎麼用的?

答:一般使用list結構作為佇列,rpush生產訊息,lpop消費訊息。當lpop沒有訊息的時候,要適當sleep一會再重試。

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

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

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

在消費者下線的情況下,生產的訊息會丟失,得使用專業的訊息佇列如RabbitMQ等。

如果對方追問redis如何實現延時佇列?

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

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

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

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

這時候你要給予驚訝的反饋:唉,是喔,這個鎖就永遠得不到釋放了。緊接著你需要抓一抓自己得腦袋,故作思考片刻,好像接下來的結果是你主動思考出來的,然後回答:我記得set指令有非常複雜的引數,這個應該是可以同時把setnx和expire合成一條指令來用的!對方這時會顯露笑容,心裡開始默唸:摁,這小子還不錯。

注:另有需要JAVA、Android、IOS、Python、C++、HTML5等全套程式設計視訊教程的朋友,請關注微信公眾號trteach圖靈技術社群”獲取資源~~~