爲何單線程的Redis卻能支撐高併發

Redis的高併發和快速緣由redis

  1. redis是基於內存的,內存的讀寫速度很是快;
  2. 核心是基於非阻塞的IO多路複用機制
  3. redis是單線程的,反而省去了不少上下文切換線程的時間;

爲何Redis是單線程的
  Redis是基於內存的操做,CPU不是Redis的瓶頸,Redis的瓶頸最有多是機器內存的大小或者網絡帶寬。單線程容易實現。數據庫

  性能指標
  redis的性能,基於內存的,普通筆記本輕鬆處理每秒幾十萬的請求。服務器

  詳細緣由
  1)不須要各類鎖的性能消耗
  Redis的數據結構並不全是簡單的Key-Value,還有list,hash等複雜的結構,這些結構有可能會進行很細粒度的操做,好比在很長的列表後面添加一個元素,在hash當中添加或者刪除一個對象。這些操做可能就須要加很是多的鎖,致使的結果是同步開銷大大增長。
總之,在單線程的狀況下,就不用去考慮各類鎖的問題,不存在加鎖釋放鎖操做,沒有由於可能出現死鎖而致使的性能消耗。網絡

  2)單線程多進程集羣方案
  單線程的威力實際上很是強大,每核心效率也很是高,多線程天然是能夠比單線程有更高的性能上限,可是在今天的計算環境中,即便是單機多線程的上限也每每不能知足須要了,須要進一步摸索的是多服務器集羣化的方案,這些方案中多線程的技術照樣是用不上的。因此單線程、多進程的集羣不失爲一個時髦的解決方案。數據結構

  3)CPU消耗
  採用單線程,避免了沒必要要的上下文切換和競爭條件,也不存在多進程或者多線程致使的切換而消耗 CPU。
  可是若是CPU成爲Redis瓶頸,或者不想讓服務器其餘CUP核閒置,那怎麼辦?
  能夠考慮多起幾個Redis進程,Redis是key-value數據庫,不是關係數據庫,數據之間沒有約束。只要客戶端分清哪些key放在哪一個Redis進程上就能夠了。多線程

Redis單線程的優劣勢
  1.單進程單線程優點
  代碼更清晰,處理邏輯更簡單
  不用去考慮各類鎖的問題,不存在加鎖釋放鎖操做,沒有由於可能出現死鎖而致使的性能消耗
  不存在多進程或者多線程致使的切換而消耗CPU
  2.單進程單線程弊端
  CPU不是Redis的瓶頸,沒法發揮多核CPU性能,不過能夠經過在單機開多個Redis實例來完善;併發


IO多路複用技術
  redis 採用網絡IO多路複用技術來保證在多鏈接的時候, 系統的高吞吐量。socket

  多路-指的是多個socket鏈接,複用-指的是複用一個線程。多路複用主要有三種技術:select,poll,epoll。epoll是最新的也是目前最好的多路複用技術。函數

這裏「多路」指的是多個網絡鏈接,「複用」指的是複用同一個線程。採用多路I/O複用技術可讓單個線程高效的處理多個鏈接請求(儘可能減小網絡IO的時間消耗),且Redis在內存中操做數據的速度很是快(內存內的操做不會成爲這裏的性能瓶頸),主要以上兩點造就了Redis具備很高的吞吐量。高併發

  I/O 多路複用模型

  阻塞式的 I/O 模型並不能知足高併發的需求,須要一種效率更高的 I/O 模型來支撐 Redis 的多個客戶(redis-cli),這裏涉及的就是 I/O 多路複用模型了:

爲何Redis 單線程卻能支撐高併發?

在 I/O 多路複用模型中,最重要的函數調用就是 select,該方法的可以同時監控多個文件描述符的可讀可寫狀況,當其中的某些文件描述符可讀或者可寫時,select 方法就會返回可讀以及可寫的文件描述符個數。