Redis事件驅動模型

1、多路複用

多路」指的是多個網絡鏈接,「複用」指的是複用同一個線程redis

多路I/O複用模型是利用 select、poll、epoll 能夠同時監察多個流的 I/O 事件的能力,在空閒的時候,會把當前線程阻塞掉,當有一個或多個流有 I/O 事件時,就從阻塞態中喚醒,因而程序就會輪詢一遍全部的流(epoll 是隻輪詢那些真正發出了事件的流),而且只依次順序的處理就緒的流,這種作法就避免了大量的無用操做數據庫

redis使用多路複用技術,能夠處理併發的鏈接。非阻塞IO 內部實現採用epoll,採用了epoll+本身實現的簡單的事件框架。epoll中的讀、寫、關閉、鏈接都轉化成了事件,而後利用epoll的多路複用特性,毫不在io上浪費一點時間服務器

2、Redis事件

Redis服務器是一個事件驅動程序,主要處理如下兩類事件:網絡

  • 文件事件:文件事件其實就是對Socket操做的抽象,Redis服務器與Redis客戶端的通訊會產生文件事件,服務器經過監聽並處理這些事件來完成一系列的網絡操做
  • 時間事件:時間事件其實就是對定時操做的抽象,前面咱們已經講了RDB、AOF、定時刪除鍵這些操做均可以由服務端去定時或者週期去完成,底層就是經過觸發時間事件來實現的

2.1 文件事件併發

文件事件是對套接字操做的抽象, 每當一個套接字準備好執行鏈接應答(accept)、寫入、讀取、關閉等操做時, 就會產生一個文件事件。 由於一個服務器一般會鏈接多個套接字, 因此多個文件事件有可能會併發地出現框架

Redis 基於 Reactor 模式開發了本身的事件處理器函數

儘管多個文件事件可能會併發地出現, 但 I/O 多路複用程序老是會將全部產生事件的套接字都入隊到一個隊列裏面, 而後經過這個隊列, 以有序(sequentially)、同步(synchronously)、每次一個套接字的方式向文件事件分派器傳送套接字: 當上一個套接字產生的事件被處理完畢以後(該套接字爲事件所關聯的事件處理器執行完畢), I/O 多路複用程序纔會繼續向文件事件分派器傳送下一個套接字.spa

Redis 客戶端與服務器進行鏈接併發送命令的整個過程線程

  1. Redis 客戶端向服務器發起鏈接
  2. 監聽套接字將產生 AE_READABLE 事件, 觸發鏈接應答處理器執行: 處理器會對客戶端的鏈接請求進行應答, 而後建立客戶端套接字, 以及客戶端狀態, 並將客戶端套接字的 AE_READABLE 事件與命令請求處理器進行關聯, 使得客戶端能夠向主服務器發送命令請求
  3. 客戶端向主服務器發送一個命令請求, 那麼客戶端套接字將產生 AE_READABLE 事件,發命令請求處理器執行, 處理器讀取客戶端的命令內容, 而後傳給相關程序去執行
  4. 執行命令將產生相應的命令回覆, 爲了將這些命令回覆傳送回客戶端, 服務器會將客戶端套接字的 AE_WRITABLE 事件與命令回覆處理器進行關聯: 當客戶端嘗試讀取命令回覆的時候, 客戶端套接字將產生 AE_WRITABLE 事件, 觸發命令回覆處理器執行, 當命令回覆處理器將命令回覆所有寫入到套接字以後, 服務器就會解除客戶端套接字的 AE_WRITABLE 事件與命令回覆處理器之間的關聯

2.2 時間事件code

持續運行的Redis服務器會按期對自身的資源和狀態進行檢查和調整,這些按期的操做由serverCron函數負責執行,它的主要工做包括:

  • 更新服務器的統計信息(時間、內存佔用、數據庫佔用)
  • 清理數據庫的過時鍵值對
  • AOF、RDB持久化
  • 若是是主從服務器,對從服務器進行按期同步
  • 若是是集羣模式,對進羣進行按期同步和鏈接

Redis服務器將時間事件放在一個鏈表中,當時間事件執行器運行時,會遍歷整個鏈表。時間事件包括:

  • 週期性事件(Redis通常只執行serverCron時間事件,serverCron時間事件是週期性的)
  • 定時事件

執行思路:

  1. 記錄最新一次執行這個函數的時間,用於處理系統時間被修改產生的問題。
  2. 遍歷鏈表找出全部 when_sec 和 when_ms 小於如今時間的事件。
  3. 執行事件對應的處理函數。
  4. 檢查事件類型,若是是週期事件則刷新該事件下一次的執行事件。
  5. 不然從列表中刪除事件
相關文章
相關標籤/搜索