reactor 模式的基本設計思想是基於i/o復用模型來實現的。
這裡說下i/o復用模型。和傳統io多執行緒阻塞不同,i/o復用模型中多個連線共用乙個阻塞物件,應用程式只需要在乙個阻塞物件等待。當某個連線有新的資料可以處理時,作業系統通知應用程式,執行緒從阻塞狀態返回,開始進行業務處理。
什麼意思呢?餐廳老闆也發現了顧客點餐慢的問題,於是他採用了一種大膽的方式,只留了乙個服務員。當客人點餐的時候,這個服務員就去招待別的客人,客人點好餐後直接喊服務員來進行服務。這裡的顧客和服務員可以分別看作多個連線和乙個執行緒。服務員阻塞在乙個顧客那裡,當有別的顧客點好餐後,她就立刻去服務其他的顧客。
了解了 reactor 的設計思想後,再來看下單 reactor 單執行緒的實現方案:
reactor通過 i/o復用程式監控客戶端請求事件,收到事件後通過任務分派器進行分發。針對建立連線請求事件,通過 acceptor 處理,並建立對應的 handler 負責後續業務處理。針對非連線事件,reactor 會呼叫對應的 handler 完成read->業務處理->write處理流程,並將結果返回給客戶端。整個過程都在乙個執行緒裡完成。
redis基於reactor模式開發了自己的網路事件處理器,這個處理器被稱為檔案事件處理器。i/o多路復用程式負責監聽多個套接字,並向檔案事件分派器傳送那些產生了事件的套接字。儘管多個檔案事件可能會併發地出現,但i/o多路復用程式總是會將所有產生事件的套接字都放到乙個佇列裡面,然後通過這個佇列,以有序(sequentially)、同步(synchronously)、每次乙個套接字的方式向檔案事件分派器傳送套接字。當上乙個套接字產生的事件被處理完畢之後(該套接字為事件所關聯的事件處理器執行完畢),i/o多路復用程式才會繼續向檔案事件分派器傳送下乙個套接字。整個過程都在乙個執行緒裡完成,因此 redis 被稱為是單執行緒的操作。
redis6 版本中引入了多執行緒。之前已經提到過 redis 單執行緒處理有著很快的速度,那為什麼還要引入多執行緒呢?單執行緒的瓶頸在什麼地方?
先來看第二個問題,在 redis 中,單執行緒的效能瓶頸主要在網路io操作上。也就是在讀寫網路的read/write系統呼叫執行期間會占用大部分cpu時間。如果要對一些大的鍵值對進行刪除操作的話,在短時間內是刪不完的,那麼對於單執行緒來說就會阻塞後邊的操作。回想下上邊講得 reactor 模式中單執行緒的處理方式。針對非連線事件,reactor 會呼叫對應的 handler 完成read->業務處理->write 處理流程,也就是說這一步會造成效能上的瓶頸。
redis6.0的多執行緒是指,將網路資料讀寫和協議解析通過多執行緒的方式來處理,對於命令執行來說,仍然使用單執行緒操作。也就是說,redis6.0的多執行緒是為了解決其網路io的瓶頸。
紅色字型部分待理解
redis6.0之多執行緒
Redis 6 0 為什麼要引入多執行緒呢
檢視 redis 版本 redis cli v redis cli 3.2.1 reactor 模式 redis 是基於 reactor 模式開發了網路事件處理器,這個處理器稱為檔案事件處理器。組成結構為4個部分 一般來說 redis 的瓶頸並不在 cpu,而在記憶體和網路。如果要使用 cpu 多核...
為什麼要用多執行緒
以前我認為多執行緒的作用就是提公升效能。實際上,多執行緒並不一定能提公升效能 甚至還會降低效能 多執行緒也不只是為了提公升效能。多執行緒主要有以下的應用場景 1 避免阻塞 非同步呼叫 單個執行緒中的程式,是順序執行的。如果前面的操作發生了阻塞,那麼就會影響到後面的操作。這時候可以採用多執行緒,我感覺...
為什麼要用多執行緒
1 避免阻塞 非同步呼叫 2 避免cpu空轉 需要處理的資訊提供得太慢,導致 cpu 效能沒有充分利用,這個時候多程序能充分利用 cpu 在io程式設計一節中,我們已經知道,cpu的速度遠遠快於磁碟 網路等io。在乙個執行緒中,cpu執行 的速度極快,然而,一旦遇到io操作,如讀寫檔案 傳送網路資料...