深入聊聊 Redis 的事件
良心公眾號(hào)
關(guān)注不迷路
01
概述
Redis 服務(wù)器是一個(gè)事件驅(qū)動(dòng)程序,需要處理兩類事件:
文件事件:Redis 服務(wù)器通過(guò)套接字與外部進(jìn)行連接,而文件事件就是服務(wù)器對(duì)套接字操作的抽象。服務(wù)器與外部的通信會(huì)產(chǎn)生相應(yīng)的文件事件,服務(wù)器通過(guò)監(jiān)聽(tīng)并處理這些事件來(lái)完成一系列網(wǎng)絡(luò)通信操作。
時(shí)間事件:Redis 服務(wù)器中的一些操作需要在給定的時(shí)間點(diǎn)執(zhí)行,而時(shí)間事件就是服務(wù)器對(duì)這類定時(shí)操作的抽象。
02
文件事件
Redis 基于 Reactor 模式開(kāi)發(fā)了自己的網(wǎng)絡(luò)事件處理器——文件事件處理器。
文件事件處理器使用 I/O 多路復(fù)用程序來(lái)同時(shí)監(jiān)聽(tīng)多個(gè)套接字,并根據(jù)套接字目前執(zhí)行的任務(wù)來(lái)為套接字關(guān)聯(lián)不同的事件處理器。
當(dāng)被監(jiān)聽(tīng)的套接字準(zhǔn)備好執(zhí)行鏈接應(yīng)答,讀取,寫(xiě)入,關(guān)閉等操作時(shí),就會(huì)產(chǎn)生對(duì)應(yīng)的文件事件,文件事件處理器就會(huì)調(diào)用套接字之間關(guān)聯(lián)好的事件處理器來(lái)處理這些事件。
文件事件處理器可以拆分為四個(gè)部分:套接字、I/O 多路復(fù)用程序、文件事件分派器、事件處理器。具體工作如下圖所示:

從上圖可以看出,文件事件處理器的工作流程大致可以作如下描述:I/O 多路復(fù)用程序負(fù)責(zé)監(jiān)聽(tīng)套接字,并將其存放至隊(duì)列中,然后按照有序、同步的方式逐一向文件事件分派器進(jìn)行傳送,文件事件分派器接收到套接字之后,會(huì)根據(jù)套接字對(duì)應(yīng)的事件類型調(diào)用對(duì)應(yīng)的事件處理器。
Redis 的 I/O 多路復(fù)用程序的功能,是通過(guò)封裝下圖所示的多種 I/O 多路復(fù)用函數(shù)庫(kù)來(lái)實(shí)現(xiàn)的,程序在編譯時(shí)會(huì)根據(jù)當(dāng)前狀態(tài)選擇性能最高的函數(shù)庫(kù)。

Redis 的文件事件分派器會(huì)遍歷所有的事件,并調(diào)用相應(yīng)的事件處理器來(lái)對(duì)其進(jìn)行處理。
文件事件處理器可分為連接應(yīng)答處理器、命令請(qǐng)求處理器、命令回復(fù)處理器。它們的具體作用場(chǎng)景如下所示:
連接應(yīng)答處理器:客戶端向服務(wù)端發(fā)起建立 socket 連接請(qǐng)求,監(jiān)聽(tīng)套接字產(chǎn)生 AE_READABLE 事件,觸發(fā)連接應(yīng)答處理器執(zhí)行。
命令請(qǐng)求處理器:客戶端與服務(wù)器建立連接后,向服務(wù)器發(fā)送命令,客戶端套接字產(chǎn)生 AE_READABLE 事件,觸發(fā)命令請(qǐng)求處理器執(zhí)行。
命令回復(fù)處理器:當(dāng)服務(wù)器需要將命令回復(fù)回傳客戶端時(shí),服務(wù)器會(huì)將客戶端套接字的 AE_WRITABLE 事件和命令回復(fù)處理器作關(guān)聯(lián),客戶端產(chǎn)生 AE_WRITABLE 事件,觸發(fā)命令回復(fù)處理器執(zhí)行。
上述過(guò)程可以用下圖簡(jiǎn)化表示:

03
時(shí)間事件
Redis 的時(shí)間事件可分為定時(shí)事件和周期性事件,其含義如下:
定時(shí)事件:讓程序在一段時(shí)間之后執(zhí)行一次。
周期性事件:讓程序每隔一段時(shí)間執(zhí)行一次。
Redis 的一個(gè)時(shí)間事件主要由以下屬性構(gòu)成:
id:時(shí)間事件全局唯一的標(biāo)識(shí)號(hào),從小到大遞增
when:時(shí)間事件的到達(dá)時(shí)間,毫秒精度的UNIX時(shí)間戳
timeProc:時(shí)間事件處理器,當(dāng)時(shí)間事件到達(dá)時(shí),執(zhí)行該函數(shù)
服務(wù)器會(huì)將所有時(shí)間事件放入一個(gè)鏈表中,當(dāng)時(shí)間事件執(zhí)行器運(yùn)行時(shí),遍歷該鏈表,檢查事件當(dāng)前是否需要執(zhí)行,如需要,則調(diào)用相應(yīng)的時(shí)間事件處理器。舉例如下圖所示:

綜上所述,本文關(guān)于 Redis 事件相關(guān)的總結(jié)就到這里了。
歡迎關(guān)注【有理想的菜雞】公眾號(hào),大家一起討論技術(shù),共同成長(zhǎng)!
04
相關(guān)閱讀
05
參考資料
《Redis 設(shè)計(jì)與實(shí)現(xiàn)》黃健宏 著
https://github.com/redis/redis

學(xué)習(xí) | 工作 | 分享
??關(guān)注“有理想的菜雞”
