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 過期等等特性。
Redis 與其他 key-value 存儲有什么不同?
-
Redis 有着更為復雜的數據結構並且提供對他們的原子性操作,這是一個不同於其他數據庫的進化路徑。Redis 的數據類型都是基於基本數據結構的同時對程序員透明, 無需進行額外的抽象。
-
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 有哪些好處?
-
速度快, 因為數據存在內存中, 類似於 HashMap, HashMap 的優勢就是查找和操作的時間復雜度都是 O1)
-
支持豐富數據類型, 支持 string, list, set, Zset, hash 等
-
支持事務, 操作都是原子性, 所謂的原子性就是對數據的更改要么全部執行, 要么全部不執行
-
豐富的特性:可用於緩存,消息,按 key 設置過期時間,過期后將會自動刪除
4、Redis 相比Memcached 有哪些優勢?
-
Memcached 所有的值均是簡單的字符串, redis 作為其替代者, 支持更為豐富的數據類
-
Redis 的速度比 Memcached 快很3、Redis 可以持久化其數據
-
更多面試題關注微信公眾號:Java2B
5、Memcache 與Redis 的區別都有哪些?
-
存儲方式 Memecache 把數據全部存在內存之中, 斷電后會掛掉, 數據不能超過內存大小。 Redis 有部份存在硬盤上, 這樣能保證數據的持久性
-
數據支持類型 Memcache 對數據類型支持相對簡單。 Redis 有復雜的數據類型。
-
使用底層模型不同 它們之間底層實現方式 以及與客戶端之間通信的應用協議不一樣。 Redis 直接自己構建了 VM 機制 ,因為一般的系統調用系統函數的話, 會浪費一定的時間去移動和請求。
6、Redis 是單進程單線程的?
答: Redis 是單進程單線程的, redis 利用隊列技術將並發訪問變為串行訪問, 消除了傳統數據庫串行控制的開銷。
7、一個字符串類型的值能存儲最大容量是多少?
答: 512M
8、Redis 的持久化機制是什么?各自的優缺點?
Redis 提供兩種持久化機制 RDB 和 AOF 機制:
RDBRedis DataBase)持久化方式: 是指用數據集快照的方式半持久化模式) 記錄 redis 數據庫的所有鍵值對,在某個時間點將數據寫入一個臨時文件, 持久化結束后, 用這個臨時文件替換上次持久化的文件, 達到數據恢復。
優點:
-
只有一個文件 dump.rdb, 方便持久化。
-
容災性好, 一個文件可以保存到安全的磁盤。
-
性能最大化, fork 子進程來完成寫操作, 讓主進程繼續處理命令, 所以是 IO 最大化。使用單獨子進程來進行持久化,主進程不會進行任何 IO 操作,保證了 redis 的高性能) 4.相對於數據集大時, 比 AOF 的啟動效率更高。
缺點:
- 數據安全性低。RDB 是間隔一段時間進行持久化,如果持久化之間 redis 發生故障, 會發生數據丟失。所以這種方式更適合數據要求不嚴謹的時候)
AOFAppend-only file)持久化方式: 是指所有的命令行記錄以 redis 命令請求協議的格式完全持久化存儲)保存為 aof 文件。
優點:
-
數據安全, aof 持久化可以配置 appendfsync 屬性, 有 always, 每進行一次命令操作就記錄到 aof 文件中一次。
-
通過 append 模式寫文件, 即使中途服務器宕機, 可以通過 redis-check-aof 工具解決數據一致性問題。
-
AOF 機制的 rewrite 模式。AOF 文件沒被 rewrite 之前( 文件過大時會對命令進行合並重寫), 可以刪除其中的某些命令( 比如誤操作的 flushall))
缺點:
-
AOF 文件比 RDB 文件大, 且恢復速度慢。
-
數據集大的時候, 比 rdb 啟動效率低。
9、Redis 常見性能問題和解決方案:
-
Master 最好不要寫內存快照,如果 Master 寫內存快照,save 命令調度 rdbSave函數, 會阻塞主線程的工作, 當快照比較大時對性能影響是非常大的, 會間斷性暫停服務,如果數據比較重要, 某個 Slave 開啟 AOF 備份數據, 策略設置為每秒同步一為了主從復制的速度和連接的穩定性, Master 和 Slave 最好在同一個局域網盡量避免在壓力很大的主庫上增加從主從復制不要用圖狀結構, 用單向鏈表結構更為穩定。
-
即:Master <- Slave1<- Slave2 <- Slave3… 這樣的結構方便解決單點故障問題,實現 Slave 對 Master 的替換。如果 Master 掛了, 可以立刻啟用 Slave1 做 Master, 其他不變。
10、Redis 過期鍵的刪除策略?
-
定時刪除:在設置鍵的過期時間的同時,創建一個定時器 timer). 讓定時器在鍵的過期時間來臨時, 立即執行對鍵的刪除操作。
-
惰性刪除:放任鍵過期不管,但是每次從鍵空間中獲取鍵時,都檢查取得的鍵是 否過期, 如果過期的話, 就刪除該鍵;如果沒有過期, 就返回該鍵。
-
定期刪除:每隔一段時間程序就對數據庫進行一次檢查,刪除里面的過期鍵。至 於要刪除多少過期鍵, 以及要檢查多少個數據庫, 則由算法決定。
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 永不回收的策略。
使用策略規則:
-
如果數據呈現冪律分布,也就是一部分數據訪問頻率高,一部分數據訪問頻率 低, 則使用 allkeys-lru
-
如果數據呈現平等分布, 也就是所有的數據訪問頻率都相同, 則使用allkeys-random
12、為什么 Redis 需要把所有數據放到內存中?
答: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 集群,集群的原理是什么?
Redis Sentinal 着眼於高可用, 在 master 宕機時會自動將 slave 提升為master, 繼續提供服務。
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
Redis 集群沒有使用一致性 hash,而是引入了哈希槽的概念, Redis 集群有16384 個哈希槽,每個 key 通過 CRC16 校驗后對 16384 取模來決定放置哪個槽, 集群的每個節點負責一部分 hash 槽。
20、說說 Redis 哈希槽的概念?
答: Redis 集群沒有使用一致性 hash,而是引入了哈希槽的概念, Redis 集群有16384 個哈希槽,每個 key 通過 CRC16 校驗后對 16384 取模來決定放置哪個槽, 集群的每個節點負責一部分 hash 槽。
總結
隨着互聯網高速發展,傳統的關系數據庫在應付超大規模數據量和高並發的情況時,已經顯得力不從心,暴露了很多難以克服的問題,而非關系型的數據庫則由於其本身的特點得到了非常迅速的發展。Redis 數據庫就是為了解決大規模數據和高並發訪問而產生的。