redis(7)——事件

Redis服務器是一個事件驅動程序,服務器需要處理以下兩類事件:

文件事件(file event):Redis服務器通過套接字與客戶端(或者其他Redis服務器)進行連接,而文件事件就是服務器對套接字操作的抽象。服務器與客戶端(或者其他服務器)的通信會產生相應的文件事件,而服務器則通過監聽並處理這些事件來完成一系列網絡通信操作。

時間事件(time event):Redis服務器中的一些操作(比如serverCron函數)需要在給定的時間點執行,而時間事件就是服務器對這類定時操作的抽象。

 

一、文件事件

文件事件處理器使用I/O多路複用(multiplexing)程序來同時監聽多個套接字,並根據套接字目前執行的任務來爲套接字關聯不同的事件處理器。

當被監聽的套接字準備好執行連接應答(accept )、讀取(read )、寫人(write )、關閉(close)等操作時,與操作相對應的文件事件就會產生,這時文件事件處理器就會調用套接字之前關聯好的事件處理器來處理這些事件。   

雖然文件事件處理器以單線程方式運行,但通過使用I/O多路複用程序來監聽多個套接字,文件事件處理器既實現了高性能的網絡通信模型,又可以很好地與Redis服務器中其他同樣以單線程方式運行的模塊進行對接,這保持了Redis內部單線程設計的簡單性

1、文件事件處理器的構成

文件事件處理器的四個組成部分,它們分別是套接字、I/O多路複用程序、文件事件分派器(dispatcher ),以及事件處理器。

 

處理併發問題時,I/O多路複用程序總是會將所有產生事件的套接字都放到一個隊列裏面,然後通過這個隊列,以有序(sequentially )、同步( synchronously )、每次一個套接字的方式向文件事件分派器傳送套接字。當上一個套接字產生的事件被處理完畢之後(該套接字爲事件所關聯的事件處理器執行完畢),I/O多路複用程序纔會繼續向文件事件分派器傳送下一個套接字。


2、事件類型

當套接字變得可讀時(客戶端對套接字執行write操作,或者執行close操作),或者有新的可應答(acceptable)套接字出現時(客戶端對服務器的監聽套接字執行connect操作),套接字產生AE_READABLE事件。

當套接字變得可寫時(客戶端對套接字執行read操作),套接字產生AE_WRITABLE事件。

如果一個套接字同時產生了這兩種事件,那麼文件事件分派器會優先處理AE_READABLE事件,等到AE_READABLE事件處理完之後,才處理AE_WRITABLE事件。

3、文件事件的處理器

爲了對連接服務器的各個客戶端進行應答,服務器要爲監聽套接字關聯連接應答處理器。


爲了接收客戶端傳來的命令請求,服務器要爲客戶端套接字關聯命令請求處理器。


爲了向客戶端返回命令的執行結果,服務器要爲客戶端套接字關聯命令回覆處理器。


當主服務器和從服務器進行復制操作時,主從服務器都需要關聯特別爲複製功能編寫的複製處理器。

客戶端與服務器端的通信過程:


 

二、時間事件

Redi s的時間事件分爲以下兩類:

定時事件:讓一段程序在指定的時間之後執行一次。比如說,讓程序X在當前時間的30毫秒之後執行一次。

週期性事件:讓一段程序每隔指定時間就執行一次。比如說,讓程序Y每隔30毫秒就執行一次。

一個時間事件主要由以下三個屬性組成:

id:服務器爲時間事件創建的全局唯一ID(標識號)。ID號按從小到大的順序遞增,新事件的ID號比舊事件的ID號要大。

when:毫秒精度的CJNIX時間戳,記錄了時間事件的到達(arrive)時間。

timeProc:時間事件處理器,一個函數。當時間事件到達時,服務器就會調用相應的處理器來處理事件。

一個時間事件是定時事件還是週期性事件取決於時間事件處理器的返回值。

時間事件的實現

服務器將所有時間事件都放在一個無序鏈表中,每當時間事件執行器運行時,它就遍歷整個鏈表,查找所有已到達的時間事件,並調用相應的事件處理器。

事件的調度與執行

因爲文件事件是隨機出現的,如果等待並處理完一次文件事件之後,仍未有任何時間事件到達,那麼服務器將再次等待並處理文件事件。

對文件事件和時間事件的處理都是同步、有序、原子地執行的,服務器不會中途中斷事件處理,也不會對事件進行搶佔,因此,不管是文件事件的處理器,還是時間事件的處理器,它們都會盡可地減少程序的阻塞時間,並在有需要時主動讓出執行權,從而降低造成事件飢餓的可能性。

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