深入學習redis 的執行緒模型

MrMirror發表於2020-08-30

一、redis 的執行緒模型


redis 內部使用檔案事件處理器 file event handler,它是單執行緒的,所以redis才叫做單執行緒模型。它採用IO多路複用機制同時監聽多個 socket,將產生事件的 socket 壓入記憶體佇列中,事件分派器根據 socket 上的事件型別來選擇對應的事件處理器進行處理。

檔案事件處理器的結構:
  • 多個 socket
  • IO 多路複用程式
  • 檔案事件分派器
  • 事件處理器(連線應答處理器、命令請求處理器、命令回覆處理器)
執行緒模型

多個 socket 可能會併發產生不同的操作,每個操作對應不同的檔案事件,但是 IO多路複用程式會監聽多個 socket,會將產生事件的 socket 放入佇列中排隊,事件分派器每次從佇列中取出一個 socket,根據 socket 的事件型別交給對應的事件處理器進行處理。


二、一次客戶端與redis的完整通訊過程

建立連線
  1. 首先,redis 服務端程式初始化的時候,會將 server socket 的 AE_READABLE 事件與連線應答處理器關聯。

  2. 客戶端 socket01 向 redis 程式的 server socket 請求建立連線,此時 server socket 會產生一個 AE_READABLE 事件,IO 多路複用程式監聽到 server socket 產生的事件後,將該 socket 壓入佇列中。

  3. 檔案事件分派器從佇列中獲取 socket,交給連線應答處理器。

  4. 連線應答處理器會建立一個能與客戶端通訊的 socket01,並將該 socket01 的 AE_READABLE 事件與命令請求處理器關聯。

執行一個set請求
  1. 客戶端傳送了一個 set key value 請求,此時 redis 中的 socket01 會產生 AE_READABLE 事件,IO 多路複用程式將 socket01 壓入佇列,

  2. 此時事件分派器從佇列中獲取到 socket01 產生的 AE_READABLE 事件,由於前面 socket01 的 AE_READABLE 事件已經與命令請求處理器關聯,

  3. 因此事件分派器將事件交給命令請求處理器來處理。命令請求處理器讀取 socket01 的 key value 並在自己記憶體中完成 key value 的設定。

  4. 操作完成後,它會將 socket01 的 AE_WRITABLE 事件與命令回覆處理器關聯。

  5. 如果此時客戶端準備好接收返回結果了,那麼 redis 中的 socket01 會產生一個 AE_WRITABLE 事件,同樣壓入佇列中,

  6. 事件分派器找到相關聯的命令回覆處理器,由命令回覆處理器對 socket01 輸入本次操作的一個結果,比如 ok,之後解除 socket01 的 AE_WRITABLE 事件與命令回覆處理器的關聯。


三、redis為什麼效率這麼高?


  • 純記憶體操作。
  • 核心是基於非阻塞的 IO 多路複用機制。
  • C 語言實現,語言更接近作業系統,執行速度相對會更快。
  • 單執行緒反而避免了多執行緒的頻繁上下文切換問題,預防了多執行緒可能產生的競爭問題。

參考:中華石衫老師的億級流量電商詳情頁快取架構設計教程



hi~我是Mirror,一個為了自由安逸的未來而不斷前進的的程式設計師。
如果你覺得文章對你有一點點幫助,一個小小贊,便是對我的認可,如果有不足之處,也歡迎各位指正。

相關文章