久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

為什么說(shuō)redis是單線程的

共計(jì) 3337 個(gè)字符,預(yù)計(jì)需要花費(fèi) 9 分鐘才能閱讀完成。

自動(dòng)寫(xiě)代碼機(jī)器人,免費(fèi)開(kāi)通

這篇文章主要介紹為什么說(shuō) redis 是單線程的,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!

Redis 即遠(yuǎn)程字典服務(wù),是一個(gè)開(kāi)源的使用 ANSI C 語(yǔ)言編寫(xiě)、支持網(wǎng)絡(luò)、可基于內(nèi)存亦可持久化的日志型、Key-Value 數(shù)據(jù)庫(kù),并提供多種語(yǔ)言的 API。

文件事件處理器

Redis 基于 Reactor 模式開(kāi)發(fā)了網(wǎng)絡(luò)事件處理器,這個(gè)處理器被稱為文件事件處理器。它的組成結(jié)構(gòu)為 4 部分:多個(gè)套接字、IO 多路復(fù)用程序、文件事件分派器、事件處理器。因?yàn)槲募录峙善麝?duì)列的消費(fèi)是單線程的,所以 Redis 才叫單線程模型。

為什么說(shuō) redis 是單線程的

消息處理流程

文件事件處理器使用 I / O 多路復(fù)用 (multiplexing) 程序來(lái)同時(shí)監(jiān)聽(tīng)多個(gè)套接字,并根據(jù)套接字目前執(zhí)行的任務(wù)來(lái)為套接字關(guān)聯(lián)不同的事件處理器。

當(dāng)被監(jiān)聽(tīng)的套接字準(zhǔn)備好執(zhí)行連接應(yīng)答 (accept)、讀取(read)、寫(xiě)入(write)、關(guān)閉(close) 等操作時(shí),與操作相對(duì)應(yīng)的文件事件就會(huì)產(chǎn)生,這時(shí)文件事件處理器就會(huì)調(diào)用套接字之前關(guān)聯(lián)好的事件處理器來(lái)處理這些事件。

盡管多個(gè)文件事件可能會(huì)并發(fā)地出現(xiàn),但 I / O 多路復(fù)用程序總是會(huì)將所有產(chǎn)生事件的套接字都推到一個(gè)隊(duì)列里面,然后通過(guò)這個(gè)隊(duì)列,以有序(sequentially)、同步(synchronously)、每次一個(gè)套接字的方式向文件事件分派器傳送套接字:當(dāng)上一個(gè)套接字產(chǎn)生的事件被處理完畢之后(該套接字為事件所關(guān)聯(lián)的事件處理器執(zhí)行完畢),I/ O 多路復(fù)用程序才會(huì)繼續(xù)向文件事件分派器傳送下一個(gè)套接字。

I/O 多路復(fù)用程序的實(shí)現(xiàn)

Redis 的 I / O 多路復(fù)用程序的所有功能是通過(guò)包裝 select、epoll、evport 和 kqueue 這些 I / O 多路復(fù)用函數(shù)庫(kù)來(lái)實(shí)現(xiàn)的,每個(gè) I / O 多路復(fù)用函數(shù)庫(kù)在 Redis 源碼中都對(duì)應(yīng)一個(gè)單獨(dú)的文件,比如 ae_select.c、ae_epoll.c、ae_kqueue.c 等。

因?yàn)?Redis 為每個(gè) I / O 多路復(fù)用函數(shù)庫(kù)都實(shí)現(xiàn)了相同的 API,所以 I / O 多路復(fù)用程序的底層實(shí)現(xiàn)是可以互換的,如下圖所示。

為什么說(shuō) redis 是單線程的

有關(guān) epoll 的詳細(xì)講解,可以點(diǎn)擊查看,徹底搞懂 epoll 高效運(yùn)行的原理

Redis 在 I / O 多路復(fù)用程序的實(shí)現(xiàn)源碼中用 #include 宏定義了相應(yīng)的規(guī)則,程序會(huì)在編譯時(shí)自動(dòng)選擇系統(tǒng)中性能最好的 I / O 多路復(fù)用函數(shù)庫(kù)來(lái)作為 Redis 的 I / O 多路復(fù)用程序的底層實(shí)現(xiàn):

/* Include the best multiplexing layer supported by this system.
 * The following should be ordered by performances, descending. */
#ifdef HAVE_EVPORT
#include  ae_evport.c 
#else
 #ifdef HAVE_EPOLL
 #include  ae_epoll.c 
 #else
 #ifdef HAVE_KQUEUE
 #include  ae_kqueue.c 
 #else
 #include  ae_select.c 
 #endif
 #endif
#endif

文件事件的類(lèi)型

I/O 多路復(fù)用程序可以監(jiān)聽(tīng)多個(gè)套接字的 ae.h/AE_READABLE 事件和 ae.h/AE_WRITABLE 事件,這兩類(lèi)事件和套接字操作之間的對(duì)應(yīng)關(guān)系如下:

當(dāng)套接字變得可讀時(shí)(客戶端對(duì)套接字執(zhí)行 write 操作,或者執(zhí)行 close 操作),或者有新的可應(yīng)答(acceptable)套接字出現(xiàn)時(shí)(客戶端對(duì)服務(wù)器的監(jiān)聽(tīng)套接字執(zhí)行 connect 操作),套接字產(chǎn)生 AE_READABLE 事件。

當(dāng)套接字變得可寫(xiě)時(shí)(客戶端對(duì)套接字執(zhí)行 read 操作),套接字產(chǎn)生 AE_WRITABLE 事件。I/ O 多路復(fù)用程序允許服務(wù)器同時(shí)監(jiān)聽(tīng)套接字的 AE_READABLE 事件和 AE_WRITABLE 事件,如果一個(gè)套接字同時(shí)產(chǎn)生了這兩種事件,那么文件事件分派器會(huì)優(yōu)先處理 AE_READABLE 事件,等到 AE_READABLE 事件處理完之后,才處理 AE_WRITABLE 事件。這也就是說(shuō),如果一個(gè)套接字又可讀又可寫(xiě)的話,那么服務(wù)器將先讀套接字,后寫(xiě)套接字。

文件事件的處理器

Redis 為文件事件編寫(xiě)了多個(gè)處理器,這些事件處理器分別用于實(shí)現(xiàn)不同的網(wǎng)絡(luò)通訊需求,常用的處理器如下:

為了對(duì)連接服務(wù)器的各個(gè)客戶端進(jìn)行應(yīng)答,服務(wù)器要為監(jiān)聽(tīng)套接字關(guān)聯(lián)連接應(yīng)答處理器。

為了接收客戶端傳來(lái)的命令請(qǐng)求,服務(wù)器要為客戶端套接字關(guān)聯(lián)命令請(qǐng)求處理器。

為了向客戶端返回命令的執(zhí)行結(jié)果,服務(wù)器要為客戶端套接字關(guān)聯(lián)命令回復(fù)處理器。

連接應(yīng)答處理器

networking.c 中 acceptTcpHandler 函數(shù)是 Redis 的連接應(yīng)答處理器,這個(gè)處理器用于對(duì)連接服務(wù)器監(jiān)聽(tīng)套接字的客戶端進(jìn)行應(yīng)答,具體實(shí)現(xiàn)為 sys/socket.h/accept 函數(shù)的包裝。

當(dāng) Redis 服務(wù)器進(jìn)行初始化的時(shí)候,程序會(huì)將這個(gè)連接應(yīng)答處理器和服務(wù)器監(jiān)聽(tīng)套接字的 AE_READABLE 事件關(guān)聯(lián)起來(lái),當(dāng)有客戶端用 sys/socket.h/connect 函數(shù)連接服務(wù)器監(jiān)聽(tīng)套接字的時(shí)候,套接字就會(huì)產(chǎn)生 AE_READABLE 事件,引發(fā)連接應(yīng)答處理器執(zhí)行,并執(zhí)行相應(yīng)的套接字應(yīng)答操作,如圖所示。

為什么說(shuō) redis 是單線程的

命令請(qǐng)求處理器

networking.c 中 readQueryFromClient 函數(shù)是 Redis 的命令請(qǐng)求處理器,這個(gè)處理器負(fù)責(zé)從套接字中讀入客戶端發(fā)送的命令請(qǐng)求內(nèi)容,具體實(shí)現(xiàn)為 unistd.h/read 函數(shù)的包裝。

當(dāng)一個(gè)客戶端通過(guò)連接應(yīng)答處理器成功連接到服務(wù)器之后,服務(wù)器會(huì)將客戶端套接字的 AE_READABLE 事件和命令請(qǐng)求處理器關(guān)聯(lián)起來(lái),當(dāng)客戶端向服務(wù)器發(fā)送命令請(qǐng)求的時(shí)候,套接字就會(huì)產(chǎn)生 AE_READABLE 事件,引發(fā)命令請(qǐng)求處理器執(zhí)行,并執(zhí)行相應(yīng)的套接字讀入操作,如圖所示。

為什么說(shuō) redis 是單線程的

在客戶端連接服務(wù)器的整個(gè)過(guò)程中,服務(wù)器都會(huì)一直為客戶端套接字的 AE_READABLE 事件關(guān)聯(lián)命令請(qǐng)求處理器。

命令回復(fù)處理器

networking.c 中 sendReplyToClient 函數(shù)是 Redis 的命令回復(fù)處理器,這個(gè)處理器負(fù)責(zé)將服務(wù)器執(zhí)行命令后得到的命令回復(fù)通過(guò)套接字返回給客戶端,具體實(shí)現(xiàn)為 unistd.h/write 函數(shù)的包裝。

當(dāng)服務(wù)器有命令回復(fù)需要傳送給客戶端的時(shí)候,服務(wù)器會(huì)將客戶端套接字的 AE_WRITABLE 事件和命令回復(fù)處理器關(guān)聯(lián)起來(lái),當(dāng)客戶端準(zhǔn)備好接收服務(wù)器傳回的命令回復(fù)時(shí),就會(huì)產(chǎn)生 AE_WRITABLE 事件,引發(fā)命令回復(fù)處理器執(zhí)行,并執(zhí)行相應(yīng)的套接字寫(xiě)入操作,如圖所示。

為什么說(shuō) redis 是單線程的

當(dāng)命令回復(fù)發(fā)送完畢之后,服務(wù)器就會(huì)解除命令回復(fù)處理器與客戶端套接字的 AE_WRITABLE 事件之間的關(guān)聯(lián)。

一次完整的客戶端與服務(wù)器連接事件示例

假設(shè) Redis 服務(wù)器正在運(yùn)作,那么這個(gè)服務(wù)器的監(jiān)聽(tīng)套接字的 AE_READABLE 事件應(yīng)該正處于監(jiān)聽(tīng)狀態(tài)之下,而該事件所對(duì)應(yīng)的處理器為連接應(yīng)答處理器。

如果這時(shí)有一個(gè) Redis 客戶端向 Redis 服務(wù)器發(fā)起連接,那么監(jiān)聽(tīng)套接字將產(chǎn)生 AE_READABLE 事件,觸發(fā)連接應(yīng)答處理器執(zhí)行:處理器會(huì)對(duì)客戶端的連接請(qǐng)求進(jìn)行應(yīng)答,然后創(chuàng)建客戶端套接字,以及客戶端狀態(tài),并將客戶端套接字的 AE_READABLE 事件與命令請(qǐng)求處理器進(jìn)行關(guān)聯(lián),使得客戶端可以向主服務(wù)器發(fā)送命令請(qǐng)求。

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

執(zhí)行命令將產(chǎn)生相應(yīng)的命令回復(fù),為了將這些命令回復(fù)傳送回客戶端,服務(wù)器會(huì)將客戶端套接字的 AE_WRITABLE 事件與命令回復(fù)處理器進(jìn)行關(guān)聯(lián):當(dāng)客戶端嘗試讀取命令回復(fù)的時(shí)候,客戶端套接字將產(chǎn)生 AE_WRITABLE 事件,觸發(fā)命令回復(fù)處理器執(zhí)行,當(dāng)命令回復(fù)處理器將命令回復(fù)全部寫(xiě)入到套接字之后,服務(wù)器就會(huì)解除客戶端套接字的 AE_WRITABLE 事件與命令回復(fù)處理器之間的關(guān)聯(lián)。

為什么說(shuō) redis 是單線程的

以上是“為什么說(shuō) redis 是單線程的”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注丸趣 TV 行業(yè)資訊頻道!

向 AI 問(wèn)一下細(xì)節(jié)

正文完
 
丸趣
版權(quán)聲明:本站原創(chuàng)文章,由 丸趣 2023-12-16發(fā)表,共計(jì)3337字。
轉(zhuǎn)載說(shuō)明:除特殊說(shuō)明外本站除技術(shù)相關(guān)以外文章皆由網(wǎng)絡(luò)搜集發(fā)布,轉(zhuǎn)載請(qǐng)注明出處。
評(píng)論(沒(méi)有評(píng)論)
主站蜘蛛池模板: 沧源| 新晃| 西充县| 察哈| 安吉县| 齐河县| 泰安市| 明水县| 积石山| 高台县| 易门县| 林口县| 叶城县| 新建县| 云南省| 澳门| 蒙阴县| 合作市| 广德县| 麻阳| 墨玉县| 临汾市| 尚志市| 仙桃市| 楚雄市| 同仁县| 碌曲县| 壤塘县| 盐源县| 千阳县| 拉孜县| 灵川县| 来凤县| 东至县| 舟曲县| 肇东市| 香港 | 吉木萨尔县| 东乌珠穆沁旗| 宜章县| 鱼台县|