redis的線程模型 與 壓力測試


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

 *IO多路復用:可以參考我的這篇博客https://www.cnblogs.com/wlwl/p/10293057.html

下面舉一個例子來說明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事件跟命令請求處理器關聯起來。

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

  命令回復處理器寫完之后,就會刪除這個socket的AE_WRITABLE事件和命令回復處理器的關聯關系。

*為啥redis單線程模型也能效率這么高?

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

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

   


免責聲明!

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



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