redis從一開始就使用單執行緒模型處理來自客戶端的絕大多數的網路請求,即redis可以支援io多路復用。除此之外還有其他原因:
1、使用單執行緒模型能帶來更好的維護性,方便開發和除錯。
2、使用單執行緒模型也能併發的處理客戶端的請求。
3、redis服務中執行的絕大多數操作的效能瓶頸都不是cpu。
雖然多執行緒能夠充分利用cpu的計算資源來併發的執行不同的任務,但是cpu資源並不是redis伺服器的效能瓶頸。
redis不是cpu密集型的服務,如果不開啟aof備份,所有redis的操作都會在記憶體中完成不會涉及任何的io操作,這些資料的讀寫由於只發生在記憶體中,所以處理速度是非常快的,整個服務的瓶頸在於網路傳輸帶來的延遲和等待客戶端的資料傳輸,也就是網路io,所以使用多執行緒模型處理全部的外部請求不是乙個好的方案。關鍵原因在於redis效能瓶頸在於記憶體和網路頻寬,並不在於cpu。
多執行緒雖然會幫助我們更充分的利用cpu資源,但是作業系統上線程的切換也會帶來開銷:
1、儲存執行緒1的執行上下文
2、載入執行緒2的執行上下文
頻繁的對執行緒的上下文進行切換可能會導致效能急劇下降,可能會導致我們不僅沒有提公升請求處理的平均速度,反而進行了負優化。
redis最新的幾個版本中加入了一些可以被執行緒非同步處理的刪除操作,即unlink,flushall async 和flushdb async。為什麼這些刪除操作需要通過多執行緒的方式非同步處理?
在redis中使用del命令來刪除乙個鍵對應的值,如果待刪除的鍵值對占用了較小的記憶體空間,同步刪除鍵值對也不會消耗太多時間。
但是對於redis中一些超大鍵值對,幾十mb或者幾百mb的資料並不能在幾毫秒的時間內處理完,redis可能會需要在釋放記憶體空間上消耗較多的時間,這些操作會阻塞待處理的任務,影響redis服務處理請求的pct99和可用性。
redis引入多執行緒也是從效能上考慮,對於一些大的鍵值對的刪除操作,通過多執行緒非阻塞的釋放記憶體空間能減少redis主線程阻塞的時間,提高執行的效率。
1、純記憶體操作:讀取不需要進行磁碟io,所以比傳統資料庫要快。(但不要有誤區說磁碟即一定慢,例如kafka就是使用磁碟順序讀取但仍然較快)
2、單執行緒,無鎖競爭:保證了沒有執行緒的上下文切換,不會因為多執行緒的一些操作而降低效能
3、多路io復用模型,非阻塞io:採用多路io復用技術可以讓單個執行緒高效的處理多個網路連線請求(儘量減少網路io的時間消耗)
4、高效的資料結構,加上底層做了大量的優化:redis對於底層的資料結構和記憶體占用做了大量的優化。例如不同長度的字串使用不同的結構來表示,hyperloglog的密集型儲存結構等。
redis為什麼選擇單執行緒工作模型
程序 在計算機發明之初就發現,在輸入資料時 i o速度慢 cpu是空閒的,這樣就浪費了cpu資源,為了充分利用cpu資源,發明了程序,在輸入程式a的資料時,程式b在占用cpu資源進行計算。執行緒 為了減少程序的上下文切換的損耗,滿足人機互動的實時性,同時保留程序充分利用cpu資源的優點,出現了執行緒...
Redis為什麼是單執行緒
經過多方資料收集 總結 思考,結論如下 準確地來說,該問題是 為什麼redis採用單程序單執行緒模型 我們從兩個層次去理解 第乙個層次 我們多執行緒的使用情景是io密集型,目的是為了充分利用cpu資源。也就是說當乙個執行緒io等待的時候,另乙個執行緒可以進行執行,達到充分利用cpu資源的效果,不要讓...
redis單執行緒模型
redis基於reactor模式開發了自己的網路事件處理器,稱之為檔案事件處理器 file event hanlder 檔案事件處理器由socket io多路復用程式 檔案事件分派器 dispather 事件處理器 handler 四部分組成。io多路復用程式會同時監聽多個socket,當被監聽的s...