redis的線程模型 與 壓力測試

  當客戶端與ServerSocket產生鏈接時,會產生一個 AE_REABLE / AE_WRITABL 事件, 多個Socket可能併發產生不一樣的事件,IO多路複用程序會監聽這些Socket,按照順序將這些Socket放到隊列中排隊。而後每次從隊列中取出一個Socket來進行相應的操做。(這種io多路複用+事件驅動模式,在redis和netty中獲得了很好的應用)html

 *IO多路複用:能夠參考個人這篇博客https://www.cnblogs.com/wlwl/p/10293057.htmlredis

下面舉一個例子來講明io多路複用,模擬一個tcp服務器處理30個客戶socket。
假設你是一個老師,讓30個學生解答一道題目,而後檢查學生作的是否正確,你有下面幾個選擇:
  1. 第一種選擇:按順序逐個檢查,先檢查A,而後是B,以後是C、D。。。這中間若是有一個學生
   卡主,全班都會被耽誤。這種模式就比如,你用循環挨個處理socket,根本不具備併發能力。
  2. 第二種選擇:你建立30個分身,每一個分身檢查一個學生的答案是否正確。 這種相似於爲每個
用戶建立一個進程或者線程處理鏈接。
  3. 第三種選擇,你站在講臺上等,誰解答完誰舉手。這時C、D舉手,表示他們解答問題完畢,你下
去依次檢查C、D的答案,而後繼續回到講臺上等。此時E、A又舉手,而後去處理E和A。。。 這種就是IO複用模型。

 *文件事件處理器:服務器

  若是是客戶端要鏈接redis,那麼會爲socket關聯鏈接應答處理器
  若是是客戶端要寫數據到redis,那麼會爲socket關聯命令請求處理器
  若是是客戶端要從redis讀數據,那麼會爲socket關聯命令回覆處理器多線程

*客戶端與redis通訊的一次流程:併發

  在redis啓動初始化的時候,redis會將鏈接應答處理器跟AE_READABLE事件關聯起來,接着若是一個客戶端跟redis發起鏈接,此時會產生一個AE_READABLE事件,而後由鏈接應答處理器來處理跟客戶端創建鏈接,建立客戶端對應的socket,同時將這個socket的AE_READABLE事件跟命令請求處理器關聯起來。socket

  當客戶端向redis發起請求的時候(無論是讀請求仍是寫請求,都同樣),首先就會在socket產生一個AE_READABLE事件,而後由對應的命令請求處理器來處理。這個命令請求處理器就會從socket中讀取請求相關數據,而後進行執行和處理。接着redis這邊準備好了給客戶端的響應數據以後,就會將socket的AE_WRITABLE事件跟命令回覆處理器關聯起來,當客戶端這邊準備好讀取響應數據時,就會在socket上產生一個AE_WRITABLE事件,會由對應的命令回覆處理器來處理,就是將準備好的響應數據寫入socket,供客戶端來讀取。tcp

  命令回覆處理器寫完以後,就會刪除這個socket的AE_WRITABLE事件和命令回覆處理器的關聯關係。工具

*爲啥redis單線程模型也能效率這麼高?測試

1)簡潔的命令表達式
2)純內存操做
3)核心是基於非阻塞的IO多路複用機制
4)單線程反而避免了多線程的頻繁上下文切換問題spa

redis自帶redis-benchmark這個壓力測試工具,我以一臺2G2核的虛擬機爲例作一下壓力測試:
cd /redis/bin
  *1. 模擬100個鏈接,一共發起100000個請求,它會打印出redis各個命令的執行效率
  ./redis-benchmark -h 127.0.0.1 -p 6379 -c 100 -n 100000

  

  2. 查看簡單信息:
  以100個字節裝載來壓測 (-q表示簡單信息,只會打印出每一個命令的每秒處理請求個數)
  ./redis-benchmark -h 127.0.0.1 -p 6379 -q -d 100

  

  3. 查看指定命令每秒處理請求量
  查看set/lpush命令的tps
  ./redis-benchmark -t set,lpush -n 10000 -q

   

相關文章
相關標籤/搜索