redis是一個事件驅動程序
主要包含
文件事件和時間事件
文件事件:主要就是server和client進行操作產生的文件
時間事件:主要就是一些需要定時執行的事件。
文件事件:
文件事件處理器是單線程運行的,但是通過IO多路復用,可以處理多個套接字
下面是文件事件處理器的結構
文件事件處理器主要是上面四個部分構成的
文件事件其實就是對套接字操作的抽象,我們當執行讀寫的時候就會產生,因為文件事件處理器可以連接多個套接字,所以可能多個文件事件同時發生,但是IO多路程序會將這些文件事件都放在一個隊列里面,通過文件事件分派器分配不同的處理器,每次只能分配一個,必須等上一個處理結束了才會繼續處理下一個
IO多路復用的所有功能都是sselct,epoll這些庫封裝形成的,至於調用哪一個,完全看具體情況使用哪一個的效率
事件處理器的io多路復用可以監聽多個socket的讀寫時間,當發生讀事件的時候,產生AE_READABLE,當產生寫事件的時候,發生AE_WRITABLE事件。,如果多個套接字同時產生讀寫時間,我們會先執行讀事件,在執行寫事件
文件的事件處理器:
連接應答處理器
命令請求處理器:
命令回復處理器
當client連接server的時候,會觸發socket的readable執行連接應答處理器。當客戶端通過連接應答處理器成功連接到server的時候,我們會將AE_READABLE和命令請求處理器關聯起來,當客戶端向服務器發送請求命令的時候,套接字就會產生AE_READABLE事件,並發送給命令請求處理器,結束后,當server需要回復client的時候,就會將socket和AE_WRITEABLE事件關聯起來。當客戶端需要read的時候就會觸發這個事件。發送結束會,就會將socket和AE_WRITEABEL解除關聯
一次完整的客戶端與服務器連接事件示例
讓我們來追蹤一次 Redis 客戶端與服務器進行連接並發送命令的整個過程, 看看在過程中會產生什么事件, 而這些事件又是如何被處理的。
假設一個 Redis 服務器正在運作, 那么這個服務器的監聽套接字的 AE_READABLE 事件應該正處於監聽狀態之下, 而該事件所對應的處理器為連接應答處理器。
如果這時有一個 Redis 客戶端向服務器發起連接, 那么監聽套接字將產生 AE_READABLE 事件, 觸發連接應答處理器執行: 處理器會對客戶端的連接請求進行應答, 然后創建客戶端套接字, 以及客戶端狀態, 並將客戶端套接字的 AE_READABLE 事件與命令請求處理器進行關聯, 使得客戶端可以向主服務器發送命令請求。
之后, 假設客戶端向主服務器發送一個命令請求, 那么客戶端套接字將產生 AE_READABLE 事件, 引發命令請求處理器執行, 處理器讀取客戶端的命令內容, 然后傳給相關程序去執行。
執行命令將產生相應的命令回復, 為了將這些命令回復傳送回客戶端, 服務器會將客戶端套接字的 AE_WRITABLE 事件與命令回復處理器進行關聯: 當客戶端嘗試讀取命令回復的時候, 客戶端套接字將產生 AE_WRITABLE 事件, 觸發命令回復處理器執行, 當命令回復處理器將命令回復全部寫入到套接字之后, 服務器就會解除客戶端套接字的 AE_WRITABLE 事件與命令回復處理器之間的關聯。
時間事件:
時間事件包括定時事件和周期性事件
定時事件就是執行一次
周期性事件都按照周期執行的
時間事件的屬性有下面3個
id遞增的
when:unix時間戳,表示什么時候執行
timeproc:時間事件處理器,一個函數,
實現其實就是一個鏈表
服務器會定期處理時間事件:
首先會遍歷1所有的時間事件,看看哪個到了時間,如果時間到了的話。會判斷返回值是否為AE_NOMORE,如果是的話,從server刪除,不是的話,會設置返回值的時間后繼續觸發執行
時間事件函數:servercron函數
server會定期執行這個函數,這個函數有很多工作,比如對server資源的統計,比如內存,cpu等等
清理過期鍵
關閉和清理失效的客戶端請求
嘗試進行AOF和RBD
主從的同步
集群的定期連接測試
因為有兩種事件,所以調度就是一個問題,我們需要怎么合理安排事件的調度
我們在選擇的時候,經常會選擇距離到達時間最近的時間事件,計算時間差,如果沒有文件事件到達,可能會阻塞,等待文件事件的到來,文件事件到了之后,會先處理文件事件,等文件事件處理完了之后,在處理時間事件,所以通常時間事件的處理時間有的時候會被到來的晚一些
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。