Redis設計與實現:第十二章 - 事件

參考:《Redis設計與實現》

1、文件事件

Redis基於Reactor模式開發自己的網絡事件處理器,也稱爲文件事件。

  • 文件事件處理器使用I/O多路複用程序同時監聽多個套接字,並根據套接字目前執行的任務來爲套接字關聯不同的事件處理器。
  • 被監聽的套接字準備好執行操作時,與操作對應的文件事件就會產生,這時文件事件處理器就會調用套接字之前關聯好的事件處理器來處理對應事件

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

       文件事件處理器的四個組成部分圖示:
在這裏插入圖片描述

文件事件
       對套接字的抽象,每當一個套接字準備好執行連接應答、寫入、讀取、關閉等操作時,就會產生一個文件事件,多個文件事件可能併發的出現。
       
I/O多路複用程序
       負責監聽多個套接字,並向文件事件分派器傳送產生這些事件的套接字。通過有序隊列,同步、每次發送一個套接字的方式向文件事件分派器發送套接字,等上一個套接字處理完畢纔會繼續發送下一個套接字。
       
文件事件分派器
       接收I/O多路複用程序傳來的套接字,根據套接字的類型,調用對應的事件處理器。
       

事件處理器
       定義了某個事件發生時,服務器應該執行的動作的函數集。

       

2、I/O多路複用程序的實現

       所有功能都是通過包裝常見的select,epoll,evport和kqueue這些I/O多路複用函數庫來實現的。Redis爲每個I/O多路複用函數庫實現了相同的API,所以I/O多路複用的底層實現是可以互換的。程序在編譯的時候會自動選擇系統中性能最高的I/O多路複用函數庫來作爲Redis的底層實現。

       

3、事件的類型

       事件類型分爲兩種,一個是可讀事件,一種是可寫事件,如果一個套接字同時產生這兩種事件,那麼服務器按照先讀套接字,後寫套接字的方式進行處理。
       

4、文件事件處理器

1.連接應答處理器

       用於對連接服務器監聽套接字的客戶端進行應答,當redis服務器進行初始化的時候,程序會將這個連接應答處理器和服務器監聽套接字的可讀事件關聯起來。
       

2.命令請求處理器

       負責從套接字中讀入客戶端發送的命令的請求內容,當客戶端向服務器發送命令的時候,套接字產生可讀事件,會引發命令請求處理器執行,執行相應的套接字讀入操作。
       

3.命令回覆處理器

       當服務器有命令回覆需要傳送給客戶端,當客戶端準備好接收命令回覆時,會產生可寫事件,將命令回覆處理器關聯起來,執行相應的套接字寫入操作。
       

4、總體通信過程

在這裏插入圖片描述
       

2、時間事件

1、時間事件分類

Redis時間事件分成下面兩類:

  • 定時事件:讓一段程序在指定的時間之後執行一次。
  • 週期性事件:讓一段程序每個一段時間執行一次。

       

2、時間事件要素

一個時間事件由下面三個屬性組成:

  • id:服務器爲時間事件創建的全局唯一ID。
  • when:毫秒精度的UNIX時間戳,記錄時間時間到達的時間。
  • timeProc:時間事件處理器,一個函數。當時間事件到達的時候,服務器會調用相應的處理器來處理事件。
           

3、實現方式

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

       

3、事件的調度與執行

事件調度和執行規則:

  • 最大阻塞時間由到達時間最接近當前時間的時間事件決定,這個方法既可以避免服務器對時間進行頻繁輪詢,也可以確保事件處理函數不會阻塞很長時間。
  • 文件事件是隨機出現的,如果等待處理完一次文件事件以後,仍然沒有時間事件到來,那麼服務器會再次等待處理文件事件,隨着文件事件的出現時間也逐漸向時間事件設置的到達事件逼近,最終開始處理時間事件。
  • 對文件事件和時間事件的處理都是同步、有序原子的執行,服務器不會中斷事件處理,也不會對事件進行處理。事件在處理的時候都會盡量減少程序的阻塞時間,在有需要的時候讓出執行權,從而降低事件飢餓的可能性。
  • 因爲時間事件在文件事件之後處理,不會發生搶佔操作,所以時間事件實際處理時間會比到達的時間晚一點。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章