Redis為什麼能抗住10萬併發?揭秘效能優越的背後原因

一燈架構發表於2023-04-13

1. Redis簡介

Redis是一個開源的,基於記憶體的,高效能的鍵值型資料庫。它支援多種資料結構,包含五種基本型別 String(字串)、Hash(雜湊)、List(列表)、Set(集合)、Zset(有序集合),和三種特殊型別 Geo(地理位置)、HyperLogLog(基數統計)、Bitmaps(點陣圖),可以滿足各種應用場景的需求。

Redis還提供了多種特性,如持久化、事務、釋出訂閱、Lua指令碼、管道、主從複製、哨兵機制、叢集機制等,可以保證資料的安全性、一致性和可用性。

Redis的速度非常快,官方稱其可以達到每秒10萬次的讀寫操作。和其他資料庫相比,Redis有著明顯的優勢。例如,和MySQL相比,Redis的速度大約快了100倍;和MongoDB相比,Redis的速度大約快了10倍。這些優勢使得Redis成為了很多網際網路公司和開發者的首選資料庫。

那麼,Redis為什麼這麼快呢?主要有以下幾個原因:

  • 使用記憶體儲存資料,避免了磁碟IO的開銷,提高了資料訪問的速度。
  • 豐富的物件型別,包含8種物件型別,滿足不同場景的需求。
  • 高效的資料結構,減少了記憶體佔用和計算複雜度,提高了資料操作的效率。
  • 單執行緒模型,避免了多執行緒之間的上下文切換和競爭條件,提升CPU利用率。
  • 非阻塞IO多路複用機制,充分利用CPU和網路資源,提高了併發處理能力。

本文將詳細介紹Redis為什麼這麼快的原理和機制,並給出一些實際應用和最佳化建議。

2. 記憶體操作

Redis是一種基於記憶體的資料庫,與傳統的基於磁碟的資料庫(例如MySQL)不同,它將所有的資料都儲存在記憶體中。

那麼,Redis為什麼選擇記憶體儲存資料呢?主要有以下幾個原因:

  1. 記憶體的速度遠遠快於磁碟。記憶體讀寫速度可以達到每秒數百GB,而磁碟讀寫速度通常只有數十MB,萬倍的差距。
  2. 記憶體可以支援更多的資料結構和操作。常見的資料結構如陣列、連結串列、樹、雜湊、集合等,常見的操作如排序、查詢、過濾、聚合等。記憶體是一個靈活介質,滿足各種複雜和高效的功能,不是磁碟操作可比的。
  3. 記憶體可以支援更高的併發和擴充套件性。記憶體是一種分散式和並行的儲存介質,它可以支援多個CPU核心同時訪問同一塊記憶體區域,也可以支援多個伺服器之間共享同一塊記憶體區域。磁碟是一種集中式和序列的儲存介質,它只能支援一個CPU核心或一個伺服器訪問同一塊磁碟區域,也不能支援多個伺服器之間共享同一塊磁碟區域。

當然,Redis使用記憶體儲存資料也有一些缺點和限制:

  1. 記憶體限制:記憶體是非常昂貴的,容量通常只有幾十GB或幾百GB,而磁碟目前都是TB起步。所以我們通常只會把少量的、經常訪問的資料儲存在記憶體中。
  2. 資料型別限制:Redis不支援複雜的資料結構,比如使用者物件,通常只能序列化成字串後再儲存,查詢的時候再把字串反序列化成使用者物件。
  3. 資料備份問題:在伺服器重啟或崩潰時,儲存的記憶體中的資料可能會丟失。通常採用持久化技術將資料儲存到磁碟上,同時定期備份資料以防止資料丟失。

3. 豐富的物件型別

Redis包含五種基本型別 String(字串)、Hash(雜湊)、List(列表)、Set(集合)、Zset(有序集合),和三種特殊型別 Geo(地理位置)、HyperLogLog(基數統計)、Bitmaps(點陣圖),可以滿足各種應用場景的需求。

  1. String可以用來做快取、計數器、限流、分散式鎖、分散式Session等。
  2. Hash可以用來儲存複雜物件。
  3. List可以用來做訊息佇列、排行榜、計數器、最近訪問記錄等。
  4. Set可以用來做標籤系統、好友關係、共同好友、排名系統、訂閱關係等。
  5. Zset可以用來做排行榜、最近訪問記錄、計數器、好友關係等。
  6. Geo可以用來做位置服務、物流配送、電商推薦、遊戲地圖等。
  7. HyperLogLog可以用來做使用者去重、網站UV統計、廣告點選統計、分散式計算等。
  8. Bitmaps可以用來做線上使用者數統計、黑白名單統計、布隆過濾器等。

4. 高效的資料結構

Redis有6種資料結構sds(簡單動態字串)、ziplist(壓縮列表)、linkedlist(連結串列)、intset(整數集合)、hashtable(字典)、skiplist(跳躍表)。

Redis的8種物件型別底層都是基於這5種資料結構實現的,豐富的資料結構可以減少記憶體佔用和計算複雜度,提高資料操作的效率。

5. 單執行緒模型

Redis使用單執行緒模型,這意味著它只使用一個CPU來處理所有請求。因此,Redis不需要考慮多執行緒之間的同步、鎖、競爭等問題,也不需要花費時間和資源在多執行緒之間的上下文切換上。這使得Redis的設計和實現更簡單,效能和效率更高。

那麼,Redis為什麼選擇單執行緒模型呢?主要有以下幾個原因:

  1. Redis效能瓶頸不在於CPU,而在於記憶體和網路。因為Redis使用記憶體儲存資料,所以資料訪問非常迅速,不會成為效能瓶頸。此外,Redis的資料操作大多數都是簡單的鍵值對操作,不包含複雜計算和邏輯,因而CPU開銷很小。相反,Redis的瓶頸在於記憶體的容量和網路的頻寬,這些問題無法透過增加CPU核心來解決。
  2. Redis的單執行緒模型可以保證資料的一致性和原子性。由於Redis只有一個執行緒來處理所有的請求,所以不會出現多個執行緒同時修改同一個資料的情況,也不需要使用鎖或事務來保證資料的一致性和原子性。
  3. Redis的單執行緒模型可以避免多執行緒程式設計的複雜性和難度。例如執行緒安全、死鎖、記憶體洩漏、競態條件等,降低了開發和維護的成本和風險。

6. 多路IO複用模型

Redis使用單執行緒模型來處理客戶端的請求,但是它能夠利用多路I/O複用技術來實現高併發和高吞吐量。

那麼,什麼是多路I/O複用模型?

多路I/O複用模型是指使用一個執行緒來監控多個檔案描述符(fd)的讀寫狀態,當某個fd準備好執行讀或寫操作時,就通知相應的事件處理器來處理。這樣就避免了阻塞式I/O模型中,單個執行緒只能等待一個fd的問題,提高了I/O效率和利用率。

例如Linux系統中提供了多種多路I/O複用技術的實現方式,如select、poll、epoll等。

7. 總結

本文介紹了Redis為什麼如此快的原因。

首先,Redis使用記憶體儲存資料,避免了磁碟I/O的開銷,提高了資料訪問的速度。其次,Redis擁有豐富的物件型別,包含八種型別,滿足不同的需求。此外,Redis採用了高效的資料結構,減少了記憶體佔用和計算複雜度。Redis還使用單執行緒模型,避免了多執行緒之間的上下文切換和競爭條件,提升了CPU利用率。最後,Redis使用非阻塞I/O多路複用機制,充分利用CPU和網路資源,提高了併發處理能力。

我是「一燈架構」,如果本文對你有幫助,歡迎各位小夥伴點贊、評論和關注,感謝各位老鐵,我們下期見

image

相關文章