看完這篇博客之後,別再說你不會 Redis 的線程模型

前言

我們常說 Redis 是單線程的,那爲什麼 Redis 是單線程的呢?
在這裏插入圖片描述

Redis 的線程模型

Redis 有一個網絡事件處理器,這個處理器基於 Reactor 模式開發,又稱文件事件處理器,它包含以下四個部分:

  1. 套接字:與客戶端建立連接,接收客戶端的指令,並給客戶端返回數據
  2. IO 多路複用程序:監聽多個套接字的消息,根據套接字目前執行的任務來爲套接字關聯不同的事件處理器,會將產生事件的套接字都推到同一個隊列上
  3. 文件事件分派器:從隊列中獲取套接字,並將套接字分配給不同的事件處理器
  4. 事件處理器:根據套接字目前執行的任務,對事件進行處理

之所以 Redis 是單線程的,是因爲 Redis 是基於文件事件分派器工作的,且文件事件分派器隊列的消費是單線程的。

消息處理流程

文件事件處理器會使用 I/O 多路複用來同時監聽多個套接字,並根據套接字目前執行的任務來爲套接字關聯不同的事件處理器。當被監聽的套接字準備執行連接應答,讀取,寫入,關閉等操作時,與操作相對應的文件事件就會產生,這時文件事件處理器就會調用套接字之前關聯好的事件處理器來處理這些事件。

文件事件是可能併發的,但 I/O 多路複用程序會將所有產生事件的套接字推送到一個隊列上,根據隊列可以實現以有序,同步,每次一個套接字的方式向文件事件分派器傳送套接字。只有當上一個套接字產生的事件被處理完畢之後(該套接字爲事件所關聯的事件處理器執行完畢),I/O 多路複用程序纔會繼續向文件事件分派器傳送下一個套接字。

IO 多路複用程序

Redis 所謂的 I/O 多路複用程序實際上是包裝了 select,epoll,evport,kqueue 這些 I/O 多路複用函數庫來實現的,在底層,Redis 爲每個 I/O 多路複用函數庫都實現了相同的 API,故實際上 I/O 多路複用程序的底層實現是可以進行互換的。在編譯時,程序會選擇系統中性能最好的 I/O 多路複用函數庫來作爲 Redis 的 I/O 多路複用程序的底層實現。

事件處理器

Redis 提供的事件處理器有很多種,各種不同的事件處理器用於實現不同的網絡通訊需求。幾種常見的事件處理器如下:

  1. 連接應答處理器:對連接服務器的各個客戶端進行應答。當 Redis 服務器初始化時,程序會把這個連接應答處理器與服務器監聽套接字的 AE_READABLE 事件進行關聯。當客戶端連接服務器監聽套接字時,套接字會產生 AE_READABLE 事件,使連接應答處理器執行
  2. 命令請求處理器:接收客戶端傳來的命令請求,該處理器可以從套接字讀入客戶端發送的命令請求內容。每當客戶端通過連接應答處理器連接上服務器之後,服務器會將客戶端套接字的 AE_READABLE 事件與命令請求處理器相關聯。當客戶端向服務器發送命令請求的時候,套接字會產生 AE_READABLE 事件,使命令請求處理器執行
  3. 命令回覆處理器:向客戶端返回命令的執行結果,將服務器執行命令後得到的命令回覆通過套接字返回給客戶端。在服務器需要給客戶端傳送命令回覆時,服務器會將客戶端套接字的 AE_WRITABLE 事件與命令回覆處理器相關聯。當客戶端準備接收服務器傳回的命令回覆時,就會產生 AE_WRITABLE 事件,使命令回覆處理器執行

一次客戶端與服務器相連接的流程

  1. 如果 Redis 服務器正在工作,那麼服務器的監聽套接字的 AE_READABLE 事件應該處於監聽狀態下,該事件處理器爲連接應答處理器
  2. Redis 客戶端向 Redis 服務器發起連接,監聽套接字產生 AE_READABLE 事件,觸發連接應答處理器執行
  3. 處理器對客戶端的連接請求進行應答, 然後創建客戶端套接字
  4. 處理器將客戶端套接字的 AE_READABLE 事件與命令請求處理器進行關聯,使客戶端可以向主服務器發送命令請求
  5. 當客戶端向 Redis 服務器發送一個命令請求時,客戶端套接字會產生 AE_READABLE事件,觸發命令請求處理器執行,處理器會去讀取客戶端的命令內容, 然後傳給相關程序執行
  6. Redis服務器執行命令,產生相應的命令回覆
  7. 服務器將客戶端套接字的 AE_WRITABLE 事件與命令回覆處理器相關聯,用以將命令回覆傳送回客戶端
  8. 當客戶端嘗試讀取命令回覆時,客戶端套接字產生 AE_WRITABLE 事件, 觸發命令回覆處理器執行
  9. 命令回覆處理器將命令回覆全部寫入到套接字後, 服務器會解除客戶端套接字的 AE_WRITABLE 事件與命令回覆處理器之間的關聯

參考: 徹底搞懂Redis的線程模型

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章