天天看點

關于redis單線程的分析

redis為什麼那麼快?結論有三點,大家都知道,這裡主要是分析。

首先第一點

redis是記憶體通路的,是以快

當然這個大家都知道,是以不是重點

io密集型和cpu密集型

一般我們把任務分為io密集型和cpu密集型

io密集型

  • IO密集型指的是系統的CPU性能相對硬碟、記憶體要好很多,此時,系統運作,大部分的狀況是CPU在等I/O (硬碟/記憶體) 的讀/寫操作,此時CPU Loading并不高。
  • 對于io密集型的任務,它的主要時間都在磁盤io上,而io本身在發出中斷告知cpu後,cpu隻需要短暫的處理一下,之後就由DMA(詳見附錄)負責資料傳輸,整個過程對cpu的使用率很低。是以我們需要開更多的線程去充分利用cpu。即一般線程數 = cpu核心數 * 2,如資料庫連接配接池

cpu密集型

  • CPU密集型也叫計算密集型,指的是系統的硬碟、記憶體性能相對CPU要好很多,此時,系統運作大部分的狀況是CPU Loading 100%,CPU要讀/寫I/O(硬碟/記憶體),I/O在很短的時間就可以完成,而CPU還有許多運算要處理,CPU Loading很高。
  • 對于cpu密集型的任務,它對cpu的使用率很高,是以不需要開更多的線程去提高cpu使用率。假如增加線程,隻會引起線程的頻繁切換導緻本來就不夠用的cpu更加不夠用。是以一般是線程數 = cpu核心數 + 1

redis的瓶頸在哪裡

redis基本都在進行記憶體io,那它的瓶頸在io上嗎?

redis在網絡io上使用epoll實作了一個io多路複用的reactor模型,epoll是非阻塞io,是以避免了cpu阻塞在io上,是以它不是io密集型,瓶頸不在于等待io導緻cpu使用率不高,不需要多個線程來屏蔽等待io執行完成的時間。當然redis的io使用率很高,但是io使用率高并不代表它是io密集型,因為它瓶頸不在等待io上。

是以第二點

redis在網絡io上使用epoll實作了一個io多路複用的reactor模型使得cpu使用率更高,浪費在io上的時間更少

redis并不需要多線程來提高cpu使用率減少io等待時間,并且單線程架構也比較容易實作,是以順理成章就采用了單線程架構。

第三點

由于采用了單線程架構,避免了線程與線程之間切換産生的消耗

因為一次CPU上下文的切換大概在 1500ns 左右。

從記憶體中讀取 1MB 的連續資料,耗時大約為 250us,假設1MB的資料由多個線程讀取了1000次,那麼就有1000次時間上下文的切換,

那麼就有1500ns * 1000 = 1500us ,我單線程的讀完1MB資料才250us ,你光時間上下文的切換就用了1500us了,我還不算你每次讀一點資料 的時間

那麼redis是cpu密集型嗎?答案是否定的。

redis也不是cpu密集型。大多數情況下redis機器上的cpu是很夠用的。

redis的瓶頸在于記憶體大小和網絡帶寬。

如果想要更充分的利用多核cpu,可以采用多個redis執行個體的方法,同時為了減少線程争用,可以将執行個體和cpu綁定的方法。

但是如果做了CPU綁定,在rdb和aof時子程序會與父程序共享使用一個CPU。子程序重寫時對單核CPU使用率通常在90%以上,父程序與子程序将産生激烈CPU競争,極大影響Redis穩定性。(解決方法不清楚,也許多綁定一個CPU會好點?)

附錄

DMA

繼續閱讀