關於redis的幾件小事(二)redis執行緒模型

一條路上的鹹魚發表於2019-05-23

1.memcached和redis有什麼區別?

(1)Redis支援伺服器端的資料操作
redis和memcached相比,redis擁有更多的 資料結構並且支援更豐富的資料操作 ,通常在memcached裡面,你需要將資料拿到客戶端來進行型別的修改然後在set回去,這樣就嚴重增加了網路IO的次數和資料體積。在redis裡面,這些操作可以在服務端完成,所以這些複雜的操作就和一般的GET/SET一樣高效。所以,如果需要快取能支援更復雜的結構和操作,那麼redis是不錯的選擇 。
(2)記憶體使用率
如果使用簡單的 key-value 儲存的話,Memcached的記憶體利用率會更高,而如果Redis採用 hash 結構來做 key-value 儲存,由於其組合式的壓縮,其記憶體利用率會高於Memcached。
(3)效能
由於redis只使用單核,而Memcached可以使用多核,所以平均每一個核上redis在儲存小資料時比Memcached效能更好。而在100K以上的資料中,Memcached效能要高於redis。
(4)叢集模式
memcached沒有原生的叢集模式,需要依靠客戶端來實現叢集中分片寫入資料;redis原生支援cluster模式,官方支援redis cluster叢集模式。

對比點 memcached redis
是否支援服務端操作 不支援 支援
資料結構型別 簡單 複雜多樣
記憶體使用率 簡單 key-value 儲存,利用率高 採用hash結構儲存,記憶體利用率高
效能 儲存大資料效能高 儲存小資料效能高
叢集模式 沒有原生支援 原生支援cluster模式

2.redis的執行緒模式?

要了解redis的執行緒模式,必須先了解下面幾個概念
(1)檔案事件處理器
①redis是基於reactor模式開發了網路事件處理器,這個處理器叫做 檔案事件處理器(file event Handler)。這個檔案事件處理器是單執行緒的,所以redis才叫做單執行緒模式,採用IO多路複用機制去同時監聽多個socket,根據socket上的事件來選擇對應的事件處理器來處理這個事件。

②如果被監聽的socket準備好執行accept、read、write、close等操作的時候,跟操作對應的檔案事件就會產生,這個時候檔案處理器就會呼叫之前關聯好的的事件處理器來處理這個事件。

③檔案事件處理器是單執行緒模式執行的,但是通過IO多路複用機制監聽多個socket,可以實現高效能的網路通訊模型,又可以跟內部其他單執行緒的模組進行對接,保證了redis內部的執行緒模型的簡單性。

④檔案事件處理器的結構包含四個部分:多個socket、IO多路複用程式、檔案事件分派器、事件處理器(命令請求處理器、命令回覆處理器、連線應答處理器,等等)。

⑤多個socket可能併發的產生不同的操作,每個操作對應不同的檔案 事件,但是IO多路複用程式會監聽多個socket,但是會將socket放到一個佇列中去處理,每次從佇列中取出一個socket給事件分派器,事件分派器把socket給對應的事件處理器。

⑥然後一個socket的事件處理完了之後,IO多路複用程式才會將佇列中的下一個socket給事件分派器。事件分派器會根據每個socket當前產生的事件,來選擇對應的事件處理器來處理。

(2)檔案事件
①當socket變得可讀時(比如客戶端對redis執行write操作,或者close操作),或者有新的可以應答的socket出現時(客戶端redis執行connect操作),socket就會產生一個AE_READABLE事件。

②當socket變得可寫的時候(客戶端對redis執行read操作),socket就會產生一個AE_WRITABLE事件。

③IO多路複用程式可以同時監聽AE_READABLE和AE_WRITABLE兩種事件,要是一個socket同時差生了這兩種事件,那麼檔案分配器優先處理AE_READABLE事件,然後才是AE_WRITABLE事件。

(3)檔案事件處理器
如果是客戶端要連線redis,那麼會為socket關聯連線應答處理器。
如果是客戶端要寫資料到redis,那麼會為socket關聯命令請求處理器。
如果是客戶端要從redis讀資料,那麼會為socket關聯命令回覆處理器。

執行緒模型
(4)客戶端與redis通訊的一次流程
①在redis啟動初始化的時候,redis會將連線應答處理器跟AE_READABLE事件關聯起來,接著如果一個客戶端跟redis發起連線,此時redis會產生一個AE_READABLE事件,然後由連線應答處理器來處理跟客戶端建立連線,建立客戶端響應的socket,同時將這個socket的AE_READABLE事件跟命令請求處理器關聯起來。

②當客戶端向redis發起請求的時候(不管是讀請求還是寫請求,都一樣),首先就會在socket產生一個AE_READABLE事件,然後由對應的命令請求處理器來處理。這個命令請求處理器就會從socket中讀取請求的相關資料,然後執行操作和處理。

③接著redis這邊準備好了給客戶端的響應資料之後,就會將socket的AE_WRITABLE事件跟命令回覆處理器關聯起來,當客戶端這邊準備好讀取相應資料時,就會在socket上產生一個AE_WRITABLE事件,會由相應的命令回覆處理器來處理,就是將準備好的響應資料寫入socket,供客戶端讀取。

④命令回覆處理器寫完之後,就會刪除這個socket的AE_WRITABLE事件和命令回覆處理器的關聯關係。

一次通訊過程

3.為什麼單執行緒redis還可以支撐高併發?

(1)純記憶體操作。
(2)核心是基於非阻塞的IO多路複用機制
(3)單執行緒避免了多執行緒上下文切換的開銷。

相關文章