Redis執行緒模型
redis 內部使用檔案事件處理器 file event handler,這個檔案事件處理器是單執行緒的,所以 redis 才叫做單執行緒的模型。
它採用 IO 多路複用機制同時監聽多個 socket,根據 socket 上的事件來選擇對應的事件處理器進行處理。
檔案事件處理器的結構包含 4 個部分:
- 多個 socket
- IO 多路複用程式
- 檔案事件分派器
- 事件處理器(包括:連線應答處理器、命令請求處理器、命令回覆處理器)
多個 socket 可能會併發產生不同的操作,每個操作對應不同的檔案事件,但是IO 多路複用 程式會監聽多個 socket,會將 socket 產生的事件放入佇列中排隊,事件分派器每次從佇列中取出一個事件,把該事件交給對應的事件處理器進行處理。
來看客戶端與 redis 的一次通訊過程:

redis-single-thread-model
-
客戶端 socket01 向 redis 的 server socket 請求建立連線,此時 server socket 會產生一個 AE_READABLE 事件,IO 多路複用程式監聽到 server socket 產生的事件後,將該事件壓入佇列中。檔案事件分派器從佇列中獲取該事件,交給連線應答處理器。連線應答處理器會建立一個能與客戶端通訊的 socket01,並將該 socket01 的 AE_READABLE 事件與命令請求處理器關聯。
-
假設此時客戶端傳送了一個 set key value 請求,此時 redis 中的 socket01 會產生 AE_READABLE 事件,IO 多路複用程式將事件壓入佇列,此時事件分派器從佇列中獲取到該事件,由於前面 socket01 的 AE_READABLE 事件已經與命令請求處理器關聯,因此事件分派器將事件交給命令請求處理器來處理。命令請求處理器讀取 socket01 的 key value 並在自己記憶體中完成 key value 的設定。操作完成後,它會將 socket01 的 AE_WRITABLE 事件與命令回覆處理器關聯。
-
如果此時客戶端準備好接收返回結果了,那麼 redis 中的 socket01 會產生一個 AE_WRITABLE 事件,同樣壓入佇列中,事件分派器找到相關聯的命令回覆處理器,由命令回覆處理器對 socket01 輸入本次操作的一個結果,比如 ok,之後解除 socket01 的 AE_WRITABLE 事件與命令回覆處理器的關聯。
這樣便完成了一次通訊。
為啥 redis 單執行緒模型也能效率這麼高?
- 純記憶體操作
- 核心是基於非阻塞的 IO 多路複用機制
- 單執行緒反而避免了多執行緒的頻繁上下文切換問題