Redis一直是後端面試的熱門提問點,是“兵家必爭之地”,本文是Redis詳解系列的第一部分,介紹了Redis的基本概念,並輔以面試題進行知識點鞏固。 ...
目錄
聲明:Redis的相關知識是面試的一大熱門知識點,同時也是一個龐大的體系,所涉及的知識點非常多,如果用一篇文章羅列,往往會陷入知識海洋中無法感知其全貌,因此,這段時間我會試著拆分Redis的相關章節,輔以思維導圖的形式介紹Redis的相關知識點,知識點範圍包括如下幾部分
- Redis基本概念和特點
- Redis數據結構和底層數據類型
- Redis持久化(AOF和RDB)
- Redis集群和高可用性
- Redis緩存
- Redis分散式鎖
- Redis實現非同步隊列
- Redis運維問題
今天主要介紹的是Redis基本概念和特點。
1. Redis基本概念
最本質的,Redis是一個資料庫,作為一個資料庫,它和其他資料庫自然不會完全相同,如下是它的一些本質特性:
- C語言開發:這也是它高性能的一個重要原因;
- 基於
key-value
鍵值對存儲:鍵、值都有豐富的數據類型支持 - 數據存於記憶體中:這是訪問速度快的一個原因;
- 非關係型資料庫:NoSQL,之前所瞭解的MySQL是關係型資料庫的代表。
- 高性能:C語言開發+數據存於記憶體
- 開源
2. Redis特點
2.1 優點
Redis技術之所以被廣泛使用,是因為它具有很多優點,如下所示:
-
訪問速度快
- 訪問速度快主要有四個原因:C語言開發+數據存於記憶體+單線程+非阻塞I/O多路復用;
- 這也是它被web應用廣泛使用、在大廠技術中作為基礎的原因之一。
-
支持豐富的數據類型
Redis基於鍵值對完成數據存儲,那麼對於鍵key
、值value
都有相對應的數據類型支持,如下所示:- 鍵
key
:只能是字元串類型 - 值
value
:可支持豐富的數據類型,如下所示:- 五大基礎數據類型
- 字元串(String):最基礎的數據類型,可以是字元串、整數、浮點數、二進位數據。
- 很常用的數據結構,存儲一般數據都會使用。
- 列表(List):存儲有序元素
- 可在實現消息隊列中可使用。
- 哈希表(Hash):存儲鍵值對集合,也就是整體Redis存儲可實現鍵值對嵌套,從而提高數據存儲的靈活性。
- 可存儲用戶信息等。
- 集合(Set):無序、不可重覆的元素。
- 例如標簽tag、共同關註等數據信息,就可以使用集合來存儲。
- 有序集合(Sorted Set):可給每個元素設置權重,作為排序依據,同樣不可出現重覆元素,但是可以有順序。
- 在實現排行榜功能中可使用。
- 字元串(String):最基礎的數據類型,可以是字元串、整數、浮點數、二進位數據。
- 高級數據類型(瞭解即可)
- 點陣圖(Bitmap)
- HyperLogLog
- 布隆過濾器
- GeoHash
- Pub/Sub
- Stream
- 五大基礎數據類型
- 鍵
-
單線程
- Redis是單線程的,這是它訪問速度快的一個重要原因,因為單線程不需要考慮線程安全問題,也不需要考慮上下文切換的問題,因此,它的訪問速度自然會快很多。
- Redis單線程的一個重要原因:Redis的瓶頸不在於CPU,而是記憶體和網路帶寬,因此,單線程的Redis可以充分利用CPU的性能,從而提高訪問速度。
- Redis4.0的時候,嘗試在主線程外開闢後臺線程,處理一些較為耗時的操作,如清理臟數據、斷開無用鏈接、刪除過期
key
等,但是這些操作都是在後臺線程中完成,不會影響主線程的訪問速度。 - Redis6.0在某種程度上實現了多線程,使用多線程並行處理讀寫操作和協議分析,對於命令執行部分依然使用單線程保證訪問速度。
- 這種多線程的方式提高了IO效率,解決了Redis性能限制的瓶頸之一。
-
非阻塞I/O多路復用
- I/O多路復用指的是:在一個線程中,可以同時監聽多個文件描述符,一旦某個文件描述符就緒(可讀或可寫),就能夠通知程式進行相應的讀寫操作。這樣就不會出現“為了等待任意文件的I/O響應而阻塞主線程”。
- 也許這時候你會問“不對啊,Redis不是單線程的嗎?”,是啊,這裡所說的
多路復用
,指的正是上文中Redis6.0使用多線程處理讀寫操作的技術部分。 - I/O多路復用的實現方式主要有:
select
、poll
、epoll
.具體可參考此篇博客:【後端面經-Java】I/O多路復用 簡錄
-
支持持久化、分散式系統、事務、主從複製(集群)
- 這些在後續的學習中都會具體詳細解釋
2.2 缺點
任何一個技術都不會是完美的,有優點就必然也存在缺點。——魯迅(:“我沒說過”)
Redis的缺點如下所示
- 瓶頸問題:記憶體和網路帶寬
- 在分析Redis單線程原因的時候,我們已經提到過Redis的瓶頸問題,主要就是物理記憶體的容量大小和IO操作的帶寬限制。
- 舉個例子:一個資料庫就像一個自由職業者,它的賺錢速度(效率)取決於接單速度和完工速度,而Redis就像一個完工速度非常快的自由職業者(訪問速度快),且面對著海量的請求,因此,它的技術瓶頸就在於接單速度(IO操作帶寬)。不僅如此,它完工速度快是因為把所有東西都堆在房間(記憶體)裡面,因此,它也同樣受限於物理房間的大小(物理記憶體容量)。
- 不具備自動容錯/恢復的能力
- 主機從機的宕機都會導致前端部分讀寫請求失敗,需要等待機器重啟或者手動切換前端的IP才能恢復。
- 線上擴容難度高
- 集群容量在後續維護中很難擴容,因此一開始就需要根據使用規模預備合適的容量空間。
3. Redis的應用場景
Redis是Web應用的常用中間件,它的應用場景非常廣泛,如下所示:
- 緩存
- Redis作為客戶端和伺服器資料庫之間的緩存數據,可以有效減少資料庫的訪問壓力,提高訪問速度。
- 結構圖如下所示:
- 分散式鎖
- Redis可實現分散式鎖,解決分散式系統中的併發問題。
- 簡單消息隊列
- Redis提供發佈訂閱功能和阻塞隊列功能,可以滿足一般消息隊列功能。
- 網路流量管理
- 計數器
- 天然支持,可記錄瀏覽量、點贊了
- 排行榜
- Redis中的列表、有序集合可以用於構建排行榜
- 社交網路
- 各類數據之間的關聯,贊踩比例、共同好友、共同愛好等等可以使用Redis實現。
- 計數器
面試模擬
Q:Redis、記憶體、磁碟的區別,為什麼快為什麼慢?
A:Redis是記憶體資料庫,記憶體是電腦中最快的存儲介質,磁碟是最慢的存儲介質。Redis快速是因為它將數據存於記憶體之後,而記憶體訪問可以直接傳輸到CPU中,磁碟訪問則需要通過IO操作先將數據寫入記憶體空間之後然後再傳入CPU中。
Q:Redis的資料庫類型、存儲結構如何?如何實現排行榜功能
A:Redis屬於NoSQL資料庫,它的存儲結構是鍵值對,其中鍵的數據類型只支持字元串,而值可以支持豐富的數據類型,包括列表、有序集合、集合、哈希表、字元串等等,通過列表、有序集合等數據結構實現排行榜功能。
Q:Redis是單線程還是單進程?哪些模塊是單線程?
A:Redis執行指令的相關模塊是單線程,6.0之後,關於網路IO的處理則轉為多線程,使用非阻塞IO多路復用提高IO效率