多執行緒的 Redis

2021-10-08 21:53:09 字數 2353 閱讀 6332

link

相信redis6.0以前一直都是單執行緒,到了6的版本才加入了多執行緒.

一、問題概述

redis 6.0 之後的版本拋棄了單執行緒模型這一設計,原本使用單執行緒執行的 redis 也開始選擇性使用多執行緒模型,乍一看redis的作者這麼牛,也逃不過「真香定律」,

這個問題其實可以拆分,拆分為兩個主要的問題:

(1)為什麼 redis 一開始選擇單執行緒模型(單執行緒的好處)?

(2)為什麼 redis 在 6.0 之後加入了多執行緒(在某些情況下,單執行緒出現了缺點,多執行緒可以解決)?

隨著時間的推移,單執行緒出現的問題也越來越多,原來的設計肯定就有些不合時宜,該做出改變就做出改變.技術並不是一成不變的.

二、為什麼redis一開始使用單執行緒

不管是單執行緒或者是多執行緒都是為了提公升redis的開發效率,因為redis是乙個基於記憶體的資料庫,還要處理大量的外部的網路請求,這就不可避免的要進行多次io.好在redis使用了很多優秀的機制來保證了它的高效率.那麼為什麼redis要設計成單執行緒模式的呢?可以總結如下:

(1)io多路復用

我們來看一下redis頂層設計.

[外鏈轉存失敗,源站可能有防盜煉機制,建議將儲存下來直接上傳(img-bzoagzay-1596677298326)(

fd是乙個檔案描述符,意思是表示當前檔案處於可讀、可寫還是異常狀態.使用 i/o 多路復用機制同時監聽多個檔案描述符的可讀和可寫狀態.你可以理解為具有了多執行緒的特點.

一旦受到網路請求就會在記憶體中快速處理,由於絕大多數的操作都是純記憶體的,所以處理的速度會非常地快.也就是說在單執行緒模式下,即使連線的網路處理很多,因為有io多路復用,依然可以在高速的記憶體處理中得到忽略.

(2)可維護性高

多執行緒模型雖然在某些方面表現優異,但是它卻引入了程式執行順序的不確定性,帶來了併發讀寫的一系列問題.單執行緒模式下,可以方便地進行除錯和測試.

(3)基於記憶體,單執行緒狀態下效率依然高

多執行緒能夠充分利用cpu的資源,但對於redis來說,由於基於記憶體速度那是相當的高,能達到在一秒內處理10萬個使用者請求,如果一秒十萬還不能滿足,那我們就可以使用redis分片的技術來交給不同的redis伺服器.這樣的做飯避免了在同乙個 redis 服務中引入大量的多執行緒操作.

而且基於記憶體,除非是要進行aof備份,否則基本上不會涉及任何的 i/o 操作.這些資料的讀寫由於只發生在記憶體中,所以處理速度是非常快的;用多執行緒模型處理全部的外部請求可能不是乙個好的方案.

現在我們知道了基本上可以總結成兩句話,基於記憶體而且使用多路復用技術,單執行緒速度很快,又保證了多執行緒的特點.因為沒有必要使用多執行緒.

三、為什麼引入多執行緒?

剛剛說了一堆使用單執行緒的好處,現在話鋒一轉,又要說為什麼要引入多執行緒,別不適應.引入多執行緒說明redis在有些方面,單執行緒已經不具有優勢了.

因為讀寫網路的read/write系統呼叫在redis執行期間占用了大部分cpu時間,如果把網路讀寫做成多執行緒的方式對效能會有很大提公升.

redis 的多執行緒部分只是用來處理網路資料的讀寫和協議解析,執行命令仍然是單執行緒.之所以這麼設計是不想 redis 因為多執行緒而變得複雜,需要去控制 key、lua、事務,lpush/lpop 等等的併發問題.

redis 在最新的幾個版本中加入了一些可以被其他執行緒非同步處理的刪除操作,也就是我們在上面提到的 unlink、flushall async 和 flushdb async,我們為什麼會需要這些刪除操作,而它們為什麼需要通過多執行緒的方式非同步處理?

我們知道redis可以使用del命令刪除乙個元素,如果這個元素非常大,可能佔據了幾十兆或者是幾百兆,那麼在短時間內是不能完成的,這樣一來就需要多執行緒的非同步支援.

[外鏈轉存失敗,源站可能有防盜煉機制,建議將儲存下來直接上傳(img-xiw4zurk-1596677298327)(

現在刪除工作可以在後台進行.

四、總結

redis 選擇使用單執行緒模型處理客戶端的請求主要還是因為 cpu 不是 redis 伺服器的瓶頸,所以使用多執行緒模型帶來的效能提公升並不能抵消它帶來的開發成本和維護成本,系統的效能瓶頸也主要在網路 i/o 操作上;而 redis 引入多執行緒操作也是出於效能上的考慮,對於一些大鍵值對的刪除操作,通過多執行緒非阻塞地釋放記憶體空間也能減少對 redis 主線程阻塞的時間,提高執行的效率.

一句話講完:之前用單執行緒是因為基於記憶體速度快,而且多路復用有多路復用的作用,也就是足夠了,現在引入是因為在某些操作要優化,比如刪除操作,因此引入了多執行緒.

redis單執行緒還是多執行緒

redis 是單執行緒模型,指的是執行 redis 命令的核心模組是單執行緒的,而不是整個 redis 例項就乙個執行緒,redis 其他模組還有各自模組的執行緒的。redis基於reactor模式開發了網路事件處理器,這個處理器被稱為檔案事件處理器。它的組成結構為4部分 多個套接字 io多路復用程...

Redis佇列php多執行緒請求

在資料採集的過程中,會有很多次請求.每個請求要傳送的資訊無外乎都有乙個關鍵的key,多數是id.把這個id寫入到乙個棧裡面 redis lpush idlist id 然後在php 裡面寫乙個死迴圈 public function getinfos else 然後再在外面這樣呼叫 function ...

redis 多執行緒 取消訂閱 頻道

問題1,呼叫exit 返回0,但無法立刻退出dispatch,必須等待收到新的channel推送才能退出 ret event base loopexit base,null 問題2,呼叫exit 返回0,呼叫loopbreak,始終返回 1,無法退出dispath 必須等待收到新的channel推送...