Redis的文件事件与时间事件处理
目錄
- 文件事件處理
- 事件類型
- 客戶端和服務(wù)端的通信過程
- 時間事件處理
- 執(zhí)行器執(zhí)行
- 周期性事件作用
- 事件的調(diào)度與執(zhí)行
文件事件處理
Redis基于Reactor模式開發(fā)了文件事件處理器。文件事件處理器以單線程方式運(yùn)行,通過IO多路復(fù)用程序監(jiān)聽多個套接字,實(shí)現(xiàn)了高性能網(wǎng)絡(luò)通信模型,又可以很好的與Redis服務(wù)器中同樣以單線程運(yùn)行的模塊進(jìn)行對接,保證了設(shè)計的簡單性。
文件事件處理器的構(gòu)成:套接字、I/O多路復(fù)用程序、文件事件分派器、事件處理器
每當(dāng)一個套接字準(zhǔn)備好執(zhí)行連接應(yīng)答、寫入、讀取、關(guān)閉操作時就會產(chǎn)生一個文件事件。一個服務(wù)器通常會連接多個套接字,所以多個文件事件有可能并發(fā)出現(xiàn)。
I/O多路復(fù)用程序負(fù)責(zé)監(jiān)聽多個套接字,并向文件事件分派器傳送產(chǎn)生了事件的套接字。
I/O復(fù)用程序總是將所有產(chǎn)生事件的套接字放在一個隊列里,通過這個隊列以有序、同步、每次一個套接字的方式向文件事件分派器傳送套接字。
事件類型
- 當(dāng)套接字可讀(客戶端對套接字執(zhí)行write操作,或者執(zhí)行close操作),或者有新的可應(yīng)答套接字出現(xiàn)(客戶端對服務(wù)器的監(jiān)聽套接字執(zhí)行connect操作),套接字產(chǎn)生AE_READABLE事件
- 當(dāng)套接字可寫(客戶端對套接字執(zhí)行read操作),套接字產(chǎn)生AE_WRITABLE
如果一個套接字同時產(chǎn)生了這兩種事件,那么事件分派器會優(yōu)先處理讀套接字,后處理寫套接字。
客戶端和服務(wù)端的通信過程
時間事件處理
一個時間事件主要由三個屬性組成:
1、id:全局唯一id,新事件的id比老事件的id大
2、when:記錄時間事件的到達(dá)時間(ms級別)
3、timeProc:時間時間處理器,表示事件到達(dá),服務(wù)器會調(diào)用相應(yīng)的函數(shù)
時間事件分為定時事件與周期性事件,區(qū)別在于定時事件在到達(dá)一次之后就會被刪除,之后不再到達(dá)。而周期性事件在到達(dá)一次之后會對when屬性更新值,表示在一段時間后再次到達(dá)。
Redis的實(shí)現(xiàn)原理是將所有的時間事件放在一個無序鏈表中,每當(dāng)時間事件執(zhí)行器運(yùn)作,遍歷鏈表,查找所有已達(dá)到時間時間,并調(diào)用相應(yīng)的事件處理器。新的時間時間總是插入鏈表頭部,所以往往是按照ID逆序排列的,這里無序表示不按照when屬性大小排序。
由于時間事件個數(shù)較少,所以無序鏈表并不影響時間事件處理器的性能。
執(zhí)行器執(zhí)行
執(zhí)行器具體執(zhí)行步驟如下:
遍歷服務(wù)器中的所有時間事件 for (time_event : list) {檢查該事件是否已經(jīng)到達(dá)if (time_event <= now_time) {已到達(dá),執(zhí)行事件處理器,獲取返回值retval = time_event.timeProc()如果是一個定時事件,將事件從服務(wù)器中刪除if (retval == AE_NOMORE) delete_time_event(time_event)else否則更新when,讓該事件在指定時間后再次到達(dá)update_when(time_event, retval )} }周期性事件作用
Redis服務(wù)器需要定期對自身的資源和狀態(tài)進(jìn)行檢查和調(diào)整,此時就會用到serverCron函數(shù),該函數(shù)就是以周期性事件觸發(fā)的。默認(rèn)是每秒運(yùn)行10次。
主要作用為:
1、更新服務(wù)器各類統(tǒng)計信息,如時間、內(nèi)存占用、數(shù)據(jù)庫占用情況
2、清理數(shù)據(jù)庫中過期鍵值對
3、關(guān)閉和清理連接失效的客戶端
4、嘗試進(jìn)行AOF或RDB持久化操作
5、如果是主服務(wù)器還需要對從服務(wù)器定期同步
6、如果處于集群模式,還需要對集群定期同步和連接測試
事件的調(diào)度與執(zhí)行
文件事件與時間事件之間是合作關(guān)系,服務(wù)器會輪流處理兩種事件,并且處理的過程中也不會進(jìn)行在·搶占,所以時間時間的實(shí)際處理時間通常回避設(shè)定到達(dá)時間晚一些。
事件處理角度下的服務(wù)器運(yùn)行流程:
需要注意的點(diǎn):
1、為了避免服務(wù)器對時間時間進(jìn)行頻繁輪詢(忙等待),也為了避免阻塞過長時間,每次最大阻塞時間由到達(dá)時間最接近當(dāng)前時間的時間事件決定。
2、文件事件是隨機(jī)出現(xiàn)的,所以等處理完一個文件事件之后如果還沒有時間事件到達(dá),則服務(wù)器再次等待并處理文件事件,隨著文件事件不斷執(zhí)行,逐漸接近時間事件設(shè)置的到達(dá)時間。
3、由于文件處理時同步、有序、原子執(zhí)行,所以服務(wù)器不會中斷事件處理,也不會對事件進(jìn)行搶占。所以不管是那種事件的處理都需要盡可能減少程序阻塞時間。將耗時的操作放到子線程或者子進(jìn)程中處理
總結(jié)
以上是生活随笔為你收集整理的Redis的文件事件与时间事件处理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Redis的RDB文件与AOF文件
- 下一篇: 如何在梦想城镇游戏中建造灯塔建筑