天天看點

2020年面試題總結Redis重要知識點

2020年面試題總結Redis重要知識點

1、什麼是 Redis?

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

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

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

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

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

Redis 優勢

(1)性能極高 – Redis 能讀的速度是 110000 次/s,寫的速度是 81000 次/s 。

(2)豐富的資料類型 – Redis 支援二進制案例的 Strings, Lists, Hashes, Sets 及Ordered Sets 資料類型操作。

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

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

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

(1)Redis 有着更為複雜的資料結構并且提供對他們的原子性操作,這是一個不同于其他資料庫的進化路徑。Redis 的資料類型都是基于基本資料結構的同時對程式員透明,無需進行額外的抽象。

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

2、Redis 的資料類型?

答:Redis 支援五種資料類型:string(字元串),hash(哈希),list(清單),set(集合)及 zsetsorted set:有序集合)。

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

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

3、使用 Redis 有哪些好處?

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

(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、RDBRedis DataBase)持久化方式:

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

優點:

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

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

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

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

缺點:

資料安全性低。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 啟動效率低。

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 種資料淘汰政策:

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

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 可能會出現短暫的卡頓現象。一般需要在時間上加一個随機值,使得過期時間分散一些。

2020年面試題總結Redis重要知識點

繼續閱讀