【原始碼分析】redis網路通訊併發架構簡介
我記得有一陣子Redis以不可阻擋之勢火了起來,大家都說它的效能很高,單位時間內能處理大量請求。於是我很有興趣知道它是怎麼處理網路併發的。這篇文章適合想研究Redis程式碼而不知從何入手的朋友,並沒有展現很多的細節,只對Redis的網路通訊做了一個系統性的介紹。文章分成兩部分,第一部分是對Redis所用的事件驅動模型的原理的講解,第二部分採用跟蹤關鍵程式碼的形式去探究客戶端-服務端是怎麼使用這個框架進行通訊的。
第一部分:Redis的事件驅動模型
這個部分只需要看3個原始檔:
ae.h、ae.c — 定義並實現了一個事件驅動的反應器(什麼是反應器下文詳解),ae具體代表什麼我也不知道,
我猜的話大概,a:asynchronous,e:event
ae_epoll.c — 用系統API實現了反應器所用到的底層I/O功能
注:其實跟ae_epoll.c同樣功能的還有ae_evport.c 、ae_kqueue.c 、ae_select.c 3個原始檔,對應不同的系統API。因為epoll比較通用,所以這裡用epoll做例子
接下來解析一下反應器的工作原理:
反應器有三個要素:事件集合、回撥函式、單執行緒
他們的關係如圖所示:
反應器維護一個事件集合,使用者向反應器註冊事件時,宣告該檔案描述符關注的事件型別,並設定回撥函式,等該事件就緒時,由主執行緒呼叫該回調函式
程式主體是一個事件迴圈,使用多路複用技術處理多個讀寫請求以及定時器事件
第二部分 應用Redis事件驅動模型的一般通訊流程
2.1 啟動訊息迴圈
2.2 客戶端連線
2.3 獲取請求並回復
總結
Redis自己實現了一個反應器,使用多路複用技術處理併發的讀寫事件和定時器事件,單執行緒避免了執行緒切換的開銷和互斥量的等待時間,這些設施對Redis的效能大有裨益。