Redis為什麼這麼快,你真的清楚嗎?

語言: CN / TW / HK

持續創作,加速成長!這是我參與「掘金日新計劃 · 6 月更文挑戰」的第23天,點選檢視活動詳情

前言

工作中我們經常會用到Redis,單機的Redis的併發量可以支援萬級別,那麼為什麼Redis為什麼會如此的快呢?

關於這個問題我們可以從如下的幾個方面來分析:

圖片.png

讀寫操作單執行緒

通常很多人都說Reids是單執行緒的,其實這句話不夠嚴謹,從嚴格意義上來講Redis並不是單執行緒,Redis的單執行緒指的是:Redis的網路IO和相關鍵值對的讀寫操作是單執行緒的。但 Redis 的其他功能,比如持久化、非同步刪除、叢集資料同步等,還是有其他的執行緒完成的。

為什麼Redis的讀寫會採用單執行緒操作,具體原因如下:

  • 1.多執行緒需要進行上下文的切換,而基於單執行緒無需進行上下文切換,節省CPU效能開銷
  • 2.多執行緒會存在資源共享和併發問題,為了解決問題就會引入鎖進位制來進行保護,那麼會降低系統程式碼的易除錯性和可維護性。而基於單執行緒我們無需考慮這些問題。

基於記憶體實現

記憶體讀寫比比磁碟讀寫快10倍以上。而Redis是基於記憶體實現,相對於資料存在磁碟的資料庫,節省磁碟磁碟I/O的消耗,所以速度很快。

高效的資料結構

Redis 的底層資料結構一共有6種,分別是,簡單動態字串,雙向連結串列,壓縮列表,雜湊表,跳錶和整數陣列,它們和資料型別的對應關係如下圖所示:

圖片.png

例如Redis的List的資料結構儲存,當滿足以下條件時資料會使用壓縮列表儲存,否則會採用雙向連結串列儲存。 - 1.列表物件儲存的所有字串元素的長度都小於64位元組 - 2.列表物件儲存的元素數量小於512個。

高效能的IO模型

常見網路IO模型

常見的網路I/O模型分為:同步阻塞式IO、同步非阻塞式IO、 多路複用IO模型、 非同步IO。

  • 同步阻塞式I/O:程式用IO呼叫開始,直到系統呼叫返回,在這段時間內,程序是阻塞的。直到返回成功後,應用程式開始處理使用者空間的快取區資料.簡稱BIO模型。

  • 同步非阻塞式I/O:當前連線就變成了非阻塞IO。使用非阻塞模式的IO讀寫,叫做同步非阻塞IO(None Blocking IO)簡稱NIO模型。

  • I/O多路複用:同一執行緒可以監視多個檔案控制代碼,一旦某個檔案控制代碼就緒,就能夠通知應用程式進行相應的讀寫操作。

  • 非同步I/O:使用者執行緒通過系統呼叫,向核心註冊某個IO操作。核心在整個IO操作(包括資料準備、資料複製)完成後,通知使用者程式,執行後續的業務操作。

Redis 多路複用I/O模型具體實現

Redis中採用的單執行緒Reactor網路模型,底層是基於IO多路複用,Redis多路複用具體實現如下:

圖片.png

  • 1.核心可同時監聽多個監聽套接字和多個已連線套接字。
  • 2.一旦核心監聽到套接字上有資料返回,就會觸發相應的事件,這些事件會被放進一個事件佇列,Redis單執行緒對該事件佇列不斷進行處理,事件進行處理時,會呼叫相應的處理函式,及時響應客戶端。

所以Redis可以同時處理多個客戶端請求,從而提升併發性。

I/O模型缺點

  • 1.一個執行緒支援處理的連線數非常有限CPU很容易打滿,效能方面有明顯瓶頸;
  • 2、任意一個請求在server中一旦發生耗時,都會影響整個server的效能,也就是說後面的請求都要等前面這個耗時請求處理完成,自己才能被處理到.

總結

本文從幾個方面講解了Redis為什麼這麼快,我們需要掌握其相關的原理,才能在使用過程中注意那些操作會影響到Redis的效能。