Redis為什么是單線程的


一、前言

  最近在學習Redis,這篇文章就來簡單聊聊一道常考的面試題——Redis為什么是單線程的。廢話不多說,直接開始吧。


二、正文

2.1 為什么需要多線程

  首先,現在的CPU一般都是由多個核心組成,每個核心可以認為是一個獨立的處理器,它們能夠並行地處理任務。所以,如果我們的CPU是多核的,但是程序是單線程的,那么執行程序時,這個線程在某一個時刻只能在一個核心上運行,而其它的核心卻是空閑的(如果沒有其他程序的話)。所以,為了提高CPU的使用率,我們可以創建多個線程,每個線程處理任務的一部分(每個部分互不依賴),而每個核心執行一個線程,此時CPU的使用率將提高,程序的運行速度自然也就加快了。

  除此之外,假設我們的程序有A、B、C三個任務需要執行,但是由於我們的程序使用的是單線程,這些任務只能輪流執行,A執行完畢只后,才能執行BB執行完畢只后,才能執行C。這也就意味着,在單線程的環境下,一個新的任務,需要等待它之前的任務執行完畢之后,才能被執行。假設A任務是一個非常耗時的任務,那么后面的B、C需要等待較長的一段時間,才能被執行,這樣的話提交B、C任務的用戶,需要等待較長的時間,才能得到響應。如果使用的是多線程,那么每個線程被分配到不同的核心上,可以並行地執行;若核心數量不夠,CPU將采用時間片輪轉算法,輪流為每一個線程分配時間片執行,這樣后續到達的任務,也可以並發地執行,而不需要等待之前任務的完成。此時,后續到達的任務,也可以較早地得到響應,任務的響應速度變得更加均勻。


2.2 如何理解Redis的單線程

  這里需要注意一個問題,我們所說的Redis的單線程,不是指Redis程序真的只會有一個線程。這里所說的單線程,指的是Redis處理客戶端發來的數據操作請求(增刪改查),只會使用一個線程去執行。但是實際上,Redis在執行其他操作的時候,可能會開啟多個進程或線程,比如說持久化。Redis執行BGSAVE指令,進行快照持久化時,就會fork出一個子進程,然后子進程去創建快照,完成持久化操作。


2.3 Redis為什么使用單線程

  官方解釋如下:因為Redis是基於內存的操作,CPU不是Redis的瓶頸,Redis的瓶頸最有可能是機器內存的大小或者網絡帶寬。既然單線程容易實現,而且CPU不會成為瓶頸,那就順理成章地采用單線程的方案了

  上面的解釋不是很好理解,我就簡單說一說我自己的理解吧。我們知道,Redis將數據存放在內存當中,這也就意味着,Redis在操作數據時,不需要進行磁盤I/O。磁盤I/O是一個比較耗時的操作,所以對於需要進行磁盤I/O的程序,我們可以使用多線程,在某個線程進行I/O時,CPU切換到當前程序的其他線程執行,以此減少CPU的等待時間。而Redis直接操作內存中的數據,所以使用多線程並不能有效提升效率,相反,使用多線程反倒會因為需要進行線程的切換而降低效率。

  除此之外,使用多線程的話,多個線程間進行同步,保證線程的安全,也是需要開銷的。尤其是Redis的數據結構都是一些實現較為簡單的集合結構,若使用多線程,將會頻繁地發生線程沖突,線程的競爭頻率較高,反倒會拖慢Redis的響應速度。

  綜上所述,Redis為了保持簡單和高效,自然而然地就使用了單線程。


2.4 Redis如何提高CPU的使用率

  前面也提過,現在的CPU一般都有多個核心,每個核心可以單獨執行。Redis處理客戶端請求使用單線程,那么自然而然,無法將CPU的所有核心都占用,也就造成了資源的浪費。而解決的方式也比較簡單,我們可以在同一個服務器上開啟多個Redis程序,每個Redis程序使用不同的端口,相互獨立,以此提高CPU的使用率。而這多個Redis程序可以配置成主從節點,共同為一個程序服務,也可以相互獨立,服務於多個程序。


三、總結

  以上就對Redis為何使用單線程,做了一個大致的介紹,總的來說,Redis使用單線程的原因就是:多線程並不能有效提升Redis的性能,相反可能還會降低性能,所以自然而然使用單線程。希望這篇博客對有需要的人有所幫助 ,若存在錯誤或者不足,歡迎指正和補充。


四、參考


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM