單機(jī)數(shù)據(jù)庫的實(shí)現(xiàn)(下)

事件

redis服務(wù)器是一個事件驅(qū)動程序,主要處理兩類事件:文件事件和時間事件。

文件事件

文件事件處理器使用I/O多路復(fù)用的程序來同時監(jiān)聽多個套接字,雖然redis的文件事件處理器以單線程方式運(yùn)行,但通過io多路復(fù)用監(jiān)聽多個套接字,這樣實(shí)現(xiàn)了高性能的網(wǎng)絡(luò)通訊模型,又可以很好地讓redis以單線程的方式運(yùn)行,保持了單線程設(shè)計(jì)的簡單性。(這是redis單線程還能那么快的原因之一)

文件事件的構(gòu)成

由四個組成部分:套接字,io多路復(fù)用程序,文件事件分派器以及事件處理器。

image-20200825161924824

當(dāng)套接字變得可讀(客戶端對套接字執(zhí)行write操作或者執(zhí)行close操作)的時候,或者有新的可應(yīng)答套接字出現(xiàn)時,套接字產(chǎn)生AE_READABLE事件。

當(dāng)套接字變得可寫時(客戶端對套接字執(zhí)行read操作),套接字產(chǎn)生AE_WRITABLE事件。

  • 一次完整的連接通訊流程是怎么樣子的?

假設(shè)一個redis服務(wù)器正在運(yùn)作,這個時候服務(wù)器的監(jiān)聽套接字的AE_READABLE事件處于監(jiān)聽情況下。

這時有個redis客戶端向服務(wù)器發(fā)起連接,那么監(jiān)聽套接字將產(chǎn)生AE_READABLE事件,觸發(fā)連接應(yīng)答處理器執(zhí)行。

連接處理器應(yīng)答之后會創(chuàng)建客戶端套接字,客戶端狀態(tài),并將客戶端套接字的AE_READABLE事件與命令請求處理器進(jìn)行關(guān)聯(lián)。

然后假設(shè)客戶端向主服務(wù)器發(fā)送一個命令請求,那么客戶端套接字將產(chǎn)生AE_READABLE事件,引發(fā)命令請求處理器執(zhí)行,處理器讀取相關(guān)的命令內(nèi)容,傳給相關(guān)的程序執(zhí)行。

之后命令會產(chǎn)生相關(guān)的恢復(fù),為了將這個回復(fù)給客戶端,服務(wù)器會將客戶端套接字的AE_WRITABLE事件與命令回復(fù)處理器關(guān)聯(lián)。當(dāng)客戶端嘗試讀取命令回復(fù)的時候,客戶端套接字會產(chǎn)生AE_WRITABLE事件,觸發(fā)命令回復(fù)處理器執(zhí)行,當(dāng)命令回復(fù)處理器將命令回復(fù)全部寫入到套接字后,服務(wù)器就會解除客戶端 套接字的事件和關(guān)聯(lián)。

image-20200825182326976

時間事件

redis的時間事件是用周期性事件(讓一個程序每隔指定時間就執(zhí)行一次)

主要有三個屬性組成,id(唯一標(biāo)識號),when(時間事件的到達(dá)時間),timeProc(時間事件處理函數(shù))

  • 那具體是怎么實(shí)現(xiàn)的?

redis服務(wù)器將所有的時間事件都放在一個無序列表中,事件執(zhí)行器會去遍歷這些節(jié)點(diǎn),如果發(fā)現(xiàn)時間到達(dá),就會執(zhí)行對應(yīng)的時間事件。

  • 這樣實(shí)現(xiàn)不會很耗費(fèi)資源嗎?

不會 ,因?yàn)閞edis的時間事件很少,正常模式下只有serverCron一個事件。

  • serverCron函數(shù)是干嘛的?

主要工作有:

  1. 更新服務(wù)器的各類統(tǒng)計(jì)消息,比如時間,內(nèi)存占用,數(shù)據(jù)庫占用等。
  2. 清理數(shù)據(jù)庫中的過期鍵值對。
  3. 關(guān)閉和清理鏈接失效的客戶端。
  4. 嘗試進(jìn)行AOF或RDB持久化操作。
  5. 如果服務(wù)器是主服務(wù)器,那么對服務(wù)器進(jìn)行定期同步。
  6. 如果處于集群模式,對集群進(jìn)行定期同步和連接測試。

調(diào)度

  • 因?yàn)榉?wù)器存在文件事件和時間事件,他們是怎么調(diào)度執(zhí)行的?

很簡單,ae.c/aeProcessEvents負(fù)責(zé),如果有時間事件要處理,就不阻塞去處理時間事件,如果沒有時間時間,會阻塞一下,來等待文件事件,然后執(zhí)行文件事件,執(zhí)行時間事件,然后不停死循環(huán)執(zhí)行。

客戶端

redis保存了客戶端當(dāng)前的狀態(tài)信息,以及執(zhí)行相關(guān)功能時需要用到的數(shù)據(jù)結(jié)構(gòu),其中包括:

  • 客戶端的套接字描述符(偽客戶端是-1,在aof恢復(fù)用到,否則大于1,每個客戶端都是唯一的)。
  • 客戶端的名字。(通過setname設(shè)置)
  • 客戶端的標(biāo)識符。(標(biāo)識客戶端的角色(從服務(wù)器,微客戶端)和客戶端的狀態(tài)(執(zhí)行monitor命令等))
  • 客戶端正在使用的數(shù)據(jù)庫的指針,已經(jīng)該數(shù)據(jù)庫的號碼。
  • 客戶端當(dāng)前要執(zhí)行的命令,命令的參數(shù),命令參數(shù)的個數(shù),以及指向命令實(shí)現(xiàn)函數(shù)的指針。(從緩存區(qū)分析的到的命令內(nèi)容)
  • 客戶端的輸入緩沖區(qū)和輸出緩沖區(qū)。(緩存了客戶端的命令以及服務(wù)端的輸出)
  • 客戶端的復(fù)制狀態(tài)信息,以及進(jìn)行復(fù)制所需的數(shù)據(jù)結(jié)構(gòu)。
  • 客戶端執(zhí)行BRPOP,BLPOP等列表阻塞命令時使用的數(shù)據(jù)結(jié)構(gòu)。
  • 客戶端的事務(wù)狀態(tài),以及執(zhí)行WATCH命令時用到的數(shù)據(jù)結(jié)構(gòu)。
  • 客戶端執(zhí)行發(fā)布與訂閱功能用到的數(shù)據(jù)結(jié)構(gòu)。
  • 客戶端的身份驗(yàn)證標(biāo)志。
  • 客戶端的創(chuàng)建時間,最后一次通信時間。

是通過鏈表把多個客戶端狀態(tài)記錄到服務(wù)器中。

  • 客戶端的關(guān)閉時機(jī)是什么時候?
  1. 客戶端退出。
  2. 客戶端發(fā)送了不符合協(xié)議內(nèi)容的數(shù)據(jù)。
  3. 服務(wù)端調(diào)用CLIENT KILL
  4. 服務(wù)端設(shè)置了timeout配置,那么客戶端空轉(zhuǎn)太長就會被關(guān)閉。
  5. 客戶端的命令大小超過1G。
  6. 輸出緩沖區(qū)大于限制大小會被關(guān)閉。

服務(wù)器

命令執(zhí)行器是如何工作的?

命令執(zhí)行器首先根據(jù)argv[0]的值,在命令表中找到對應(yīng)的redisCommand對象。

這個對象記錄了命令相關(guān)的細(xì)節(jié),比如允許參數(shù)多少,實(shí)現(xiàn)函數(shù)指針,對該命令的標(biāo)識符,以及一些統(tǒng)計(jì)信息。

image-20200826114220363

服務(wù)器先利用這些對命令進(jìn)行檢查,如果檢查失敗了,則返回一個錯誤,如果打開了監(jiān)視器,就會把要執(zhí)行的命令和參數(shù)等消息發(fā)給監(jiān)視器。

檢查完畢之后,就調(diào)用執(zhí)行命令的相關(guān)函數(shù),得到回復(fù)之后會保存在客戶端狀態(tài)的輸出緩沖區(qū)里面。

執(zhí)行結(jié)束之后還有一些特殊任務(wù),有統(tǒng)計(jì)慢查詢,修改鏈接的統(tǒng)計(jì)信息,aof寫入到AOF緩沖區(qū)里面,復(fù)制命令到其它從服務(wù)器。

最后套接字變?yōu)榭蓪憼顟B(tài)的時候,把輸出緩沖區(qū)里面的數(shù)據(jù)返回給客戶端。

  • serverCron函數(shù)詳細(xì)作用?
  1. 更新緩存服務(wù)器的lruclock時鐘,算每個key的lru值并不是實(shí)時的,而是這個值減去每個key的lru的值。
  2. info中的一些統(tǒng)計(jì)信息。
  3. 處理sigterm信號,在退出redis之前做相關(guān)的操作,比如RDB持久化。
  4. 關(guān)閉無用客戶端連接。
  5. 抽查部分key,并刪除過期的部分key。
  6. 將延遲的FGREWRITEAOF執(zhí)行。
  7. 將AOF緩沖區(qū)的內(nèi)容寫入AOF文件。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容