Redis 事件(2) -- 時間事件

Redis時間事件分爲以下兩類: 

1.定時事件:程序在指定時間執行一次。 

2.週期性事件:程序每隔指定時間執行一次。 


時間事件的屬性:

1.id:服務器爲時間事件創建的全局唯一ID,ID號從小到大遞增。

2.when:毫秒精度的unix時間戳,記錄時間事件的到達時間。

3.timeProc:時間事件處理器,一個函數。當時間事件到達事,執行此函數。


時間事件的返回值決定了時間事件類型,如返回ae.h/AE_NOMORE,表示事件爲定時事件,到達一次後則刪除;如返回一個非AE_NOMORE的整數,表示事件爲週期性事件,當事件到達之後,服務器會根據返回值更新時間事件的when屬性,並以這種方式一直更新下去。當前Redis版本中只有週期性事件,沒有使用定時事件。

實現:

服務器將所有時間事件都存放在一個無序列表中,每當時間事件執行器執行時,它就遍歷整個鏈表,找到所有已到達的時間事件並調用相應事件處理器。這裏的的無序鏈表,指的是不按when屬性大小排序,其實是按ID排序了,新的時間事件總是插入鏈表的表頭。當前Redis版本中,服務器只使用serverCron一個時間事件,而在benchmark模式下,服務器也只使用2個時間事件,所以使用無序鏈表來保存時間事情,並不影響性能。


serverCron函數:

此函數定期對Redis服務的資源和狀態進行檢查和調整,由redis.c/serverCron執行,工作包括:

1.更新服務器各類統計信息,如時間、內存佔用、數據庫佔用等等。

2.清理數據庫中的過期鍵值對。

3.關閉和清理連接失效的客戶端。

4.嘗試進行AOF和RDB持久化操作。

5.如果當前服務器是主服務器,需要對從服務器進行定期同步。

6.如果出於集羣環境,需要對集羣進行定期同步和連接測試。


事件調度僞代碼:

def aeProcessEvents():

#獲取到達時間離當前時間最接近的時間事件

time_event = aeSearchNearestTimer()

#計算最接近的時間事件距離到達還有多少毫秒

remain_ms = time_event.when - unix_ts_now()

#如果事件已到達,那麼remain_ms 值可能爲負數,置爲0

if remain_ms < 0:

remain_ms = 0

#根據remain_ms值,創建timeval結構

timeval = create_timeval_with_ms(remain_ms)

#阻塞並等待文件事件產生,最大阻塞時間由傳入的timeval結構決定

#如果remaind_ms值爲0,那麼aeApiPoll調用之後馬上返回,不阻塞

aeApiPoll(timeval)

#處理所有已產生的文件事件

processFileEvents()

#處理所有已到達的時間事件

processTimeEvents()





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章