2021最新 Redis面試題精選(附刷題小程序)


推薦使用小程序閱讀

為了能讓您更加方便的閱讀
本文所有的面試題目均已整理至小程序《面試手冊
可以通過微信掃描(或長按)下圖的二維碼享受更好的閱讀體驗!

image


最近梳理匯總了Java面試常遇到的面試題;並將其開發成小程序《面試手冊》,方便大家閱讀,可微信掃描文章開頭的二維碼使用;包含了Java基礎並發JVM數據庫SpringSpringMVCSpringBootSpringCloud設計模式MQLinuxDocker等多個類型,資料持續更新中;侵權聯刪。

本人不才,如出現錯誤或者不准確的地方,望各位大神指正。

分類 地址
2021最新 Java基礎面試題精選(附刷題小程序) https://www.cnblogs.com/pengfeilu/p/14348974.html
2021最新 Java虛擬機(JVM)面試題精選(附刷題小程序) https://www.cnblogs.com/pengfeilu/p/14349869.html
2021最新 Redis面試題精選(附刷題小程序) https://www.cnblogs.com/pengfeilu/p/14349266.html
2021最新 MySQL常見面試題精選(附刷題小程序) https://www.cnblogs.com/pengfeilu/p/14537921.html
2021最新 Spring面試題精選(附刷題小程序) https://www.cnblogs.com/pengfeilu/p/14350135.html
2021最新 SpringMVC面試題精選(附刷題小程序) https://www.cnblogs.com/pengfeilu/p/14353548.html
更多分類請點擊查看👉👉👉 https://blog.lupf.cn/category/ms

目錄


1. Redis基礎

1.1 什么是 Redis?

Redis 本質上是一個 Key-Value 類型的內存數據庫,很像 memcached,整個數據庫統統加載在內存當中進行操作,定期通過異步操作把數據庫數據 flush 到硬盤上進行保存。因為是純內存操作,Redis 的性能非常出色,每秒可以處理超過 10 萬次讀寫操作,是已知性能最快的 Key-Value DB。

Redis 的出色之處不僅僅是性能,Redis 最大的魅力是支持保存多種數據結構,此外單個value 的最大限制是 1GB,不像 memcached 只能保存 1MB 的數據,因此 Redis 可以用

來實現很多有用的功能,比方說用他的 List 來做FIFO 雙向鏈表,實現一個輕量級的高性 能消息隊列服務,用他的 Set 可以做高性能的 tag 系統等等。另外 Redis 也可以對存入的Key-Value 設置 expire 時間,因此也可以被當作一 個功能加強版的 memcached 來用。Redis 的主要缺點是數據庫容量受到物理內存的限制,不能用作海量數據的高性能讀寫,因此 Redis 適合的場景主要局限在較小數據量的高性能操作和運算上。

1.2 Redis 相比 memcached 有哪些優勢?

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

1.3 Redis 主要消耗什么物理資源?

內存。

1.4 Redis 的全稱是什么?

Remote Dictionary Server。

1.5 Redis 官方為什么不提供 Windows 版本?

因為目前 Linux 版本已經相當穩定,而且用戶量很大,無需開發 windows 版本,反而會帶來兼容性等問題。

1.6 為什么 Redis 需要把所有數據放到內存中?

Redis 為了達到最快的讀寫速度將數據都讀到內存中,並通過異步的方式將數據寫入磁盤。所以 Redis 具有快速和數據持久化的特征。

如果不將數據放在內存中,磁盤 I/O 速度為嚴重影響 Redis 的性能。在內存越來越便宜的今天,Redis 將會越來越受歡迎。

如果設置了最大使用的內存,則數據已有記錄數達到內存限值后不能繼續插入新值。

1.7 Redis 有哪些適合的場景?

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

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

  • **隊列 **
    Redis在內存存儲引擎領域的一大優點是提供 list 和 set 操作,這使得 Redis 能作為一個很好的消息隊列平台來使用。Redis 作為隊列使用的操作,就類似於本地程序語言(如Python) 對 list 的 push/pop 操 作 。如果你快速的在 Google 中搜索“Redis queues”,你馬上就能找到大量的開源項目,這些項目的目的就是利用 Redis 創建非常好的后端工具,以滿足各種隊列需求。例如,Celery 有一個后台就是使用 Redis 作為 broker,你可以從這里去查看。

  • 排行榜/計數器
    Redis 在內存中對數字進行遞增或遞減的操作實現的非常好。集合(Set)和有序集合(Sorted Set)也使得我們在執行這些操作的時候變的非常簡單,Redis 只是正好提供了這兩種數據結構。所以, 我們要從排序集合中獲取到排名最靠前的 10 個用戶– 我們稱之為“user_scores”,我們只需要像下面一樣執行即可:
    當然,這是假定你是根據你用戶的分數做遞增的排序。如果你想返回用戶及用戶的分數,你需要這樣執行:

    ZRANGE user_scores 0 10 WITHSCORES
    Agora Games
    

    就是一個很好的例子,用 Ruby 實現的,它的排行榜就是使用 Redis 來存儲數據的,你可以在這里看到。

  • 發布/訂閱
    發布/訂閱的使用場景確實非常多。我已看見人們在社交網絡連接中使用,還可作為基於發布/訂閱的腳本觸發器,甚至用 Redis 的發布/訂閱功能來建立聊天系統!

1.8 Redis 如何設置密碼及驗證密碼?

  • 設置密碼

    config set requirepass 123456
    
  • 授權密碼

    auth 123456
    

1.9 怎么測試 Redis 的連通性?

ping

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

Redis 有着更為復雜的數據結構並且提供對他們的原子性操作,這是一個不同於其他數據庫的進化路徑。Redis 的數據類型都是基於基本數據結構的同時對程序員透明,無需進行額外的抽象。

Redis 運行在內存中但是可以持久化到磁盤,所以在對不同數據集進行高速讀寫時需要權衡內存,應為數據量不能大於硬件內存。在內存數據庫方面的另一個優點是, 相比在磁盤上相同的復雜的數據結構,在內存中操作起來非常簡單,這樣 Redis 可以做很多內部復雜性很強的事情。 同時,在磁盤格式方面他們是緊湊的以追加的方式產生的,因為他們並不需要進行隨機訪問。

1.11 Redis 的內存占用情況怎么樣?

舉個例子: 100 萬個鍵值對(鍵是 0 到 999999 值是字符串“hello world”)在我的 32 位的 Mac 筆記本上 用了 100MB。同樣的數據放到一個 key 里只需要 16MB, 這是因為鍵值有一個很大的開銷。 在 Memcached 上執行也是類似的結果,但是相對 Redis 的開銷要小一點點,因為 Redis 會記錄類型信息引用計數等等。
當然,大鍵值對時兩者的比例要好很多。
64 位的系統比 32 位的需要更多的內存開銷,尤其是鍵值對都較小時,這是因為 64 位的系統里指針占用了 8 個字節。 但是,當然,64 位系統支持更大的內存,所以為了運行大型的 Redis 服務器或多或少的需要使用 64 位的系統。

2. Redis使用

2.1 Redis 支持哪幾種數據類型?

  • String
  • List
  • Set
  • Sorted Set
  • hashes

2.2 一個字符串類型的值能存儲最大容量是多少?

512M

2.3 MySQL 里有 2000w 數據,Redis 中只存 20w 的數據,如何保證 Redis 中的數據都是熱點數據?

Redis 內存數據集大小上升到一定大小的時候,就會施行數據淘汰策略。

2.4 Redis 支持的 Java 客戶端都有哪些?官方推薦用哪個?

  • Redisson
  • Jedis
  • lettuce 等等

官方推薦使用 Redisson。

2.5 Redis 和 Redisson 有什么關系?

Redisson是一個高級的分布式協調 Redis 客服端,能幫助用戶在分布式環境中輕松實現一些Java 的對象 (Bloom filter, BitSet, Set, SetMultimap, ScoredSortedSet, SortedSet, Map, ConcurrentMap, List, ListMultimap, Queue, BlockingQueue, Deque, BlockingDeque, Semaphore, Lock, ReadWriteLock, AtomicLong, CountDownLatch, Publish / Subscribe, HyperLogLog) 。

2.6 Jedis 與 Redisson 對比有什么優缺點?

Jedis 是 Redis 的 Java 實現的客戶端,其 API 提供了比較全面的 Redis 命令的支持;

Redisson 實現了分布式和可擴展的 Java 數據結構,和 Jedis 相比,功能較為簡單,不支持字符串操作,不支持排序、事務、管道、分區等 Redis 特性。Redisson 的宗旨是促進使用者對 Redis 的關注分離,從而讓使用者能夠將精力更集中地放在處理業務邏輯上。

2.7 Redis 中的管道有什么用?

一次請求/響應服務器能實現處理新的請求即使舊的請求還未被響應。這樣就可以將多個命令發送到服務器,而不用等待回復,最后在一個步驟中讀取該答復。
這就是管道(pipelining),是一種幾十年來廣泛使用的技術。
例如許多 POP3 協議已經實現支持這個功能,大大加快了從服務器下載新郵件的過程。

2.8 Twemproxy 是什么?

Twemproxy 是Twitter 維護的(緩存)代理系統,代理 Memcached 的ASCII 協議和 Redis 協議。它是單線程程序,使用 c 語言編寫,運行起來非常快。它是采用 Apache 2.0 license 的開源軟件。

Twemproxy 支持自動分區,如果其代理的其中一個 Redis 節點不可用時,會自動將該節點排除(這將改變原來的 keys-instances 的映射關系,所以你應該僅在把 Redis 當緩存時使用 Twemproxy)。

Twemproxy 本身不存在單點問題,因為你可以啟動多個 Twemproxy 實例,然后讓你的客戶端去連接任意一個 Twemproxy 實例。

Twemproxy 是 Redis 客戶端和服務器端的一個中間層,由它來處理分區功能應該不算復雜,並且應該算比較可靠的。

2.9 支持一致性哈希的客戶端有哪些?

Redis-rb、PRedis 等。

2.10 都有哪些辦法可以降低 Redis 的內存使用情況呢?

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

2.11 查看 Redis 使用情況及狀態信息用什么命令?

info

2.12 Redis 的內存用完了會發生什么

如果達到設置的上限,Redis 的寫命令會返回錯誤信息(但是讀命令還可以正常返回。)

或者你可以將 Redis 當緩存來使用配置淘汰機制,當 Redis 達到內存上限時會沖刷掉舊的內容。

2.13 Redis 是單線程的,如何提高多核 CPU 的利用率?

可以在同一個服務器部署多個 Redis 的實例,並把他們當作不同的服務器來使用,在某些時候,無論如何一個服務器是不夠的,所以,如果你想使用多個 CPU,你可以考慮一下分片(shard)。

2.14 一個 Redis 實例最多能存放多少的 keys?

List、Set、Sorted Set 他們最多能存放多少元素?

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

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

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

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

為了主從復制的速度和連接的穩定性,Master 和 Slave 最好在同一個局域網內<
盡量避免在壓力很大的主庫上增加從庫

主從復制不要用圖狀結構,用單向鏈表結構更為穩定,即:Master <- Slave1 <- Slave2<- Slave3…

2.16 修改配置不重啟 Redis 會實時生效嗎?

針對運行實例,有許多配置選項可以通過 CONFIG SET 命令進行修改,而無需執行任何形式的重啟。 從 Redis 2.2 開始,可以從 AOF 切換到 RDB 的快照持久性或其他方式而不需要重啟 Redis。檢索 ‘CONFIG GET *’ 命令獲取更多信息。

但偶爾重新啟動是必須的,如為升級 Redis 程序到新的版本,或者當你需要修改某些目前CONFIG 命令還不支持的配置參數的時候。

3. Redis持久化

3.1 Redis 持久化數據和緩存怎么做擴容?

如果 Redis 被當做緩存使用,使用一致性哈希實現動態擴容縮容。

如果 Redis 被當做一個持久化存儲使用,必須使用固定的 keys-to-nodes 映射關系,節點的數量一旦確定不能變化。否則的話(即 Redis 節點需要動態變化的情況),必須使用可以在運行時進行數據再平衡的一套系統,而當前只有 Redis 集群可以做到這樣。

3.2 Redis 提供了哪幾種持久化方式?

RDB 持久化方式能夠在指定的時間間隔能對你的數據進行快照存儲.

AOF 持久化方式記錄每次對服務器寫的操作,當服務器重啟的時候會重新執行這些命令來恢復原始的數據,AOF 命令以 Redis 協議追加保存每次寫的操作到文件末尾.Redis 還能對AOF 文件進行后台重寫,使得 AOF 文件的體積不至於過大.

如果你只希望你的數據在服務器運行的時候存在,你也可以不使用任何持久化方式.

你也可以同時開啟兩種持久化方式, 在這種情況下, 當 Redis 重啟的時候會優先載入 AOF 文件來恢復原始的數據,因為在通常情況下AOF 文件保存的數據集要比RDB 文件保存的數據集要完整.

最重要的事情是了解 RDB 和 AOF 持久化方式的不同,讓我們以 RDB 持久化方式開始。

3.3 如何選擇合適的持久化方式?

一般來說, 如果想達到足以媲美 PostgreSQL 的數據安全性, 你應該同時使用兩種持久化功能。如果你非常關心你的數據, 但仍然可以承受數分鍾以內的數據丟失,那么你可以只使用 RDB 持久化。

有很多用戶都只使用 AOF 持久化, 但並不推薦這種方式: 因為定時生成 RDB 快照(snapshot)非常便於進行數據庫備份, 並且 RDB 恢復數據集的速度也要比 AOF 恢復的速度要快,除此之外, 使用 RDB 還可以避免之前提到的 AOF 程序的 bug。

4. Redis集群

4.1 Redis 集群方案應該怎么做?都有哪些方案?

  1. twemproxy
    大概概念是,它類似於一個代理方式,使用方法和普通 Redis 無任何區別, 設置好它下屬的多個 Redis 實例后, 使用時在本需要連接 Redis 的地方改為連接twemproxy,它會以一個代理的身份接收請求並使用一致性 hash 算法,將請求轉接到具體 Redis,將結果再返回 twemproxy。使用方式簡便(相對 Redis 只需修改連接端口),對舊項目擴展的首選。 問題:twemproxy 自身單端口實例的壓力,使用一致性 hash 后,對Redis 節點數量改變時候的計算值的改變,數據無法自動移動到新的節點。

  2. codis
    目前用的最多的集群方案,基本和 twemproxy 一致的效果,但它支持在 節點數量改變情況下,舊節點數據可恢復到新 hash 節點。

  3. Redis cluster
    3.0 自帶的集群,特點在於他的分布式算法不是一致性 hash,而是 hash 槽的概念,以及自身支持節點設置從節點。具體看官方文檔介紹。

  4. 在業務代碼層實現
    起幾個毫無關聯的 Redis 實例,在代碼層,對 key 進行 hash 計算, 然后去對應的 Redis 實例操作數據。 這種方式對 hash 層代碼要求比較高,考慮部分包括, 節點失效后的替代算法方案,數據震盪后的自動腳本恢復,實例的監控,等等

4.2 Redis 集群方案什么情況下會導致整個集群不可用?

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

4.3 說說 Redis 哈希槽的概念?

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

4.4 Redis 集群的主從復制模型是怎樣的

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

4.5 Redis 集群會有寫操作丟失嗎?為什么?

Redis 並不能保證數據的強一致性,這意味這在實際中集群在特定的條件下可能會丟失寫操作。

4.6 Redis 集群之間是如何復制的?

異步復制

4.7 Redis 集群最大節點個數是多少?

16384 個

4.8 Redis 集群如何選擇數據庫?

Redis 集群目前無法做數據庫選擇

單節點,默認在 0 數據庫。

4.9 分布式Redis 是前期做還是后期規模上來了再做好?為什么?

既然 Redis 是如此的輕量(單實例只使用 1M 內存),為防止以后的擴容,最好的辦法就是一開始就啟動較多實例。即便你只有一台服務器,你也可以一開始就讓 Redis 以分布式的方式運行,使用分區,在同一台服務器上啟動多個實例。

一開始就多設置幾個 Redis 實例,例如 32 或者 64 個實例,對大多數用戶來說這操作起來可能比較麻煩,但是從長久來看做這點犧牲是值得的。

這樣的話,當你的數據不斷增長,需要更多的 Redis 服務器時,你需要做的就是僅僅將 Redis 實例從一台服務遷移到另外一台服務器而已(而不用考慮重新分區的問題)。一旦你添加了另一台服務器,你需要將你一半的 Redis 實例從第一台機器遷移到第二台機器。

5. Redis事務

5.1 怎么理解 Redis 事務?

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

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

5.2 Redis 事務相關的命令有哪幾個?

  • MULTI
  • EXEC
  • DISCARD
  • WATCH

6. Redis回收

6.1 Redis 有哪幾種數據淘汰策略?

  • no-eviction
    返回錯誤當內存限制達到並且客戶端嘗試執行會讓更多內存被使用的命令(大 部分的寫入指令,但 DEL 和幾個例外)
  • allkeys-lru
    嘗試回收最少使用的鍵(LRU),使得新添加的數據有空間存放。
  • volatile-lru
    嘗試回收最少使用的鍵(LRU),但僅限於在過期集合的鍵,使得新添加的數據有空間存放。
  • allkeys-random
    回收隨機的鍵使得新添加的數據有空間存放。
  • volatile-random
    回收隨機的鍵使得新添加的數據有空間存放,但僅限於在過期集合的鍵。
  • volatile-ttl
    回收在過期集合的鍵,並且優先回收存活時間(TTL)較短的鍵,使得新添加的數據有空間存放。

6.2 Redis key 的過期時間和永久有效分別怎么設置?

EXPIRE 和 PERSIST 命令

6.3 Redis 如何做內存優化?

盡可能使用散列表(hashes),散列表(是說散列表里面存儲的數少)使用的內存非常小,所以你應該盡可能的將你的數據模型抽象到一個散列表里面。比如你的 web 系統中有一個用戶對象,不要為這個用戶的名稱,姓氏,郵箱,密碼設置單獨的 key,而是應該把這個用戶的所有信息存儲到一張散列表里面。

6.4 Redis 回收進程如何工作的?

一個客戶端運行了新的命令,添加了新的數據。
Redi 檢查內存使用情況,如果大於 maxmemory 的限制, 則根據設定好的策略進行回收。一個新的命令被執行,等等。
所以我們不斷地穿越內存限制的邊界,通過不斷達到邊界然后不斷地回收回到邊界以下。
如果一個命令的結果導致大量內存被使用(例如很大的集合的交集保存到一個新的鍵),不用多久內存限制就會被這個內存使用量超越。

6.5 Redis 回收使用的是什么算法?

LRU 算法

6.6 Redis 如何做大量數據插入?

Redis2.6 開始 Redis-cli 支持一種新的被稱之為pipe mode 的新模式用於執行大量數據插入工作。

7. Redis分區

7.1 為什么要做 Redis 分區?

分區可以讓 Redis 管理更大的內存,Redis 將可以使用所有機器的內存。
如果沒有分區,你最多只能使用一台機器的內存。
分區使 Redis 的計算能力通過簡單地增加計算機得到成倍提升,Redis 的網絡帶寬也會隨着計算機和網卡的增加而成倍增長。

7.2 你知道有哪些 Redis 分區實現方案?

  • 客戶端分區
    就是在客戶端就已經決定數據會被存儲到哪個 Redis 節點或者從哪個 Redis 節點讀取。大多數客戶端已經實現了客戶端分區。
  • 代理分區
    意味着客戶端將請求發送給代理,然后代理決定去哪個節點寫數據或者讀數據。代理根據分區規則決定請求哪些 Redis 實例,然后根據 Redis 的響應結果返回給客戶端。Redis 和 memcached 的一種代理實現就是 Twemproxy
  • 查詢路由(Query routing)
    客戶端隨機地請求任意一個 Redis 實例,然后由 Redis 將請求轉發給正確的 Redis 節點。Redis Cluster 實現了一種混合形式的查詢路由,但並不是直接將請求從一個 Redis 節點轉發到另一個 Redis 節點,而是在客戶端的幫助下直接redirected 到正確的 Redis 節點。

7.3 Redis 分區有什么缺點?

涉及多個 key 的操作通常不會被支持。例如你不能對兩個集合求交集,因為他們可能被存儲到不同的 Redis 實例(實際上這種情況也有辦法,但是不能直接使用交集指令)。

同時操作多個 key,則不能使用 Redis 事務.

分區使用的粒度是key,不能使用一個非常長的排序key 存儲一個數據集(The partitioning granularity is the key, so it is not possible to shard a dataset with a single huge key like a very big sorted set).

當使用分區的時候,數據處理會非常復雜,例如為了備份你必須從不同的 Redis 實例和主機同時收集 RDB / AOF 文件。

分區時動態擴容或縮容可能非常復雜。Redis 集群在運行時增加或者刪除 Redis 節點,能做到最大程度對用戶透明地數據再平衡,但其他一些客戶端分區或者代理分區方法則不支持 這種特性。然而,有一種預分片的技術也可以較好的解決這個問題。


微信掃碼關注公眾號,回復【資料】獲取更多粉絲福利;學習、面試資料。
image


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM