1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        純干貨|深度解析Redis線程模型設(shè)計(jì)原理

        共 2397字,需瀏覽 5分鐘

         ·

        2020-09-05 20:57

        ????????

        單線程模型設(shè)計(jì)

        單線程模型為何效率高

        文件事件處理器

        Redis 基于 Reactor 模式開發(fā)了自己的網(wǎng)絡(luò)事件處理器 - 文件事件處理器(file event handler,后文簡稱為 FEH),而該處理器又是單線程的,所以redis設(shè)計(jì)為單線程模型。


        • 采用I/O多路復(fù)用同時(shí)監(jiān)聽多個(gè)socket,根據(jù)socket當(dāng)前執(zhí)行的事件來為 socket 選擇對(duì)應(yīng)的事件處理器。

        • 當(dāng)被監(jiān)聽的socket準(zhǔn)備好執(zhí)行accept、read、write、close等操作時(shí),和操作對(duì)應(yīng)的文件事件就會(huì)產(chǎn)生,這時(shí)FEH就會(huì)調(diào)用socket之前關(guān)聯(lián)好的事件處理器來處理對(duì)應(yīng)事件。


        所以雖然FEH是單線程運(yùn)行,但通過I/O多路復(fù)用監(jiān)聽多個(gè)socket,不僅實(shí)現(xiàn)高性能的網(wǎng)絡(luò)通信模型,又能和 Redis 服務(wù)器中其它同樣單線程運(yùn)行的模塊交互,保證了Redis內(nèi)部單線程模型的簡潔設(shè)計(jì)。


        下面來看文件事件處理器的幾個(gè)組成部分。


        socket

        文件事件就是對(duì)socket操作的抽象, 每當(dāng)一個(gè) socket 準(zhǔn)備好執(zhí)行連接accept、read、write、close等操作時(shí), 就會(huì)產(chǎn)生一個(gè)文件事件。一個(gè)服務(wù)器通常會(huì)連接多個(gè)socket, 多個(gè)socket可能并發(fā)產(chǎn)生不同操作,每個(gè)操作對(duì)應(yīng)不同文件事件。

        ?I/O多路復(fù)用程序

        I/O 多路復(fù)用程序會(huì)負(fù)責(zé)監(jiān)聽多個(gè)socket。

        盡管文件事件可能并發(fā)出現(xiàn), 但 I/O 多路復(fù)用程序會(huì)將所有產(chǎn)生事件的socket放入隊(duì)列, 通過該隊(duì)列以有序、同步且每次一個(gè)socket的方式向文件事件分派器傳送socket。

        ????? 當(dāng)上一個(gè)socket產(chǎn)生的事件被對(duì)應(yīng)事件處理器執(zhí)行完后, I/O 多路復(fù)用程序才會(huì)向文件事件分派器傳送下個(gè)socket, 如下:


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

        ???? Redis 的 I/O 多路復(fù)用程序的所有功能都是通過包裝常見的 select 、 epoll 、 evport 和 kqueue 這些 I/O 多路復(fù)用函數(shù)庫實(shí)現(xiàn)的。

        ???? 每個(gè) I/O 多路復(fù)用函數(shù)庫在 Redis 源碼中都對(duì)應(yīng)一個(gè)單獨(dú)的文件:

        ???? 因?yàn)?Redis 為每個(gè) I/O 多路復(fù)用函數(shù)庫都實(shí)現(xiàn)了相同的 API , 所以 I/O 多路復(fù)用程序的底層實(shí)現(xiàn)是可以互換的。Redis 在 I/O 多路復(fù)用程序的實(shí)現(xiàn)源碼`ae.c`文件中宏定義了相應(yīng)規(guī)則,使得程序在編譯時(shí)自動(dòng)選擇系統(tǒng)中性能最高的 I/O 多路復(fù)用函數(shù)庫作為 Redis 的 I/O 多路復(fù)用程序的底層實(shí)現(xiàn):性能降序排列。

        ?文件事件分派器


        文件事件分派器接收 I/O 多路復(fù)用程序傳來的socket, 并根據(jù)socket產(chǎn)生的事件類型, 調(diào)用相應(yīng)的事件處理器。

        ?文件事件處理器


        服務(wù)器會(huì)為執(zhí)行不同任務(wù)的套接字關(guān)聯(lián)不同的事件處理器, 這些處理器是一個(gè)個(gè)函數(shù), 它們定義了某個(gè)事件發(fā)生時(shí), 服務(wù)器應(yīng)該執(zhí)行的動(dòng)作。


        Redis 為各種文件事件需求編寫了多個(gè)處理器,若客戶端:


        • 連接Redis,對(duì)連接服務(wù)器的各個(gè)客戶端進(jìn)行應(yīng)答,就需要將socket映射到連接應(yīng)答處理器

        • 寫數(shù)據(jù)到Redis,接收客戶端傳來的命令請(qǐng)求,就需要映射到命令請(qǐng)求處理器

        • 從Redis讀數(shù)據(jù),向客戶端返回命令的執(zhí)行結(jié)果,就需要映射到命令回復(fù)處理器


        當(dāng)主服務(wù)器和從服務(wù)器進(jìn)行復(fù)制操作時(shí), 主從服務(wù)器都需要映射到特別為復(fù)制功能編寫的復(fù)制處理器。





        ?文件事件的類型


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




        • 當(dāng)socket可讀(比如客戶端對(duì)Redis執(zhí)行write/close操作),或有新的可應(yīng)答的socket出現(xiàn)時(shí)(即客戶端對(duì)Redis執(zhí)行connect操作),socket就會(huì)產(chǎn)生一個(gè)AE_READABLE事件



        • 當(dāng)socket可寫時(shí)(比如客戶端對(duì)Redis執(zhí)行read操作),socket會(huì)產(chǎn)生一個(gè)AE_WRITABLE事件。


        I/O多路復(fù)用程序可以同時(shí)監(jiān)聽AE_REABLE和AE_WRITABLE兩種事件,要是一個(gè)socket同時(shí)產(chǎn)生這兩種事件,那么文件事件分派器優(yōu)先處理AE_REABLE事件。即一個(gè)socket又可讀又可寫時(shí), Redis服務(wù)器先讀后寫socket。

        總結(jié)

        ????最后,讓我們梳理一下客戶端和Redis服務(wù)器通信的整個(gè)過程:


        1. Redis啟動(dòng)初始化時(shí),將連接應(yīng)答處理器跟AE_READABLE事件關(guān)聯(lián)。

        2. 若一個(gè)客戶端發(fā)起連接,會(huì)產(chǎn)生一個(gè)AE_READABLE事件,然后由連接應(yīng)答處理器負(fù)責(zé)和客戶端建立連接,創(chuàng)建客戶端對(duì)應(yīng)的socket,同時(shí)將這個(gè)socket的AE_READABLE事件和命令請(qǐng)求處理器關(guān)聯(lián),使得客戶端可以向主服務(wù)器發(fā)送命令請(qǐng)求。

        3. 當(dāng)客戶端向Redis發(fā)請(qǐng)求時(shí)(不管讀還是寫請(qǐng)求),客戶端socket都會(huì)產(chǎn)生一個(gè)AE_READABLE事件,觸發(fā)命令請(qǐng)求處理器。處理器讀取客戶端的命令內(nèi)容, 然后傳給相關(guān)程序執(zhí)行。

        4. 當(dāng)Redis服務(wù)器準(zhǔn)備好給客戶端的響應(yīng)數(shù)據(jù)后,會(huì)將socket的AE_WRITABLE事件和命令回復(fù)處理器關(guān)聯(lián),當(dāng)客戶端準(zhǔn)備好讀取響應(yīng)數(shù)據(jù)時(shí),會(huì)在socket產(chǎn)生一個(gè)AE_WRITABLE事件,由對(duì)應(yīng)命令回復(fù)處理器處理,即將準(zhǔn)備好的響應(yīng)數(shù)據(jù)寫入socket,供客戶端讀取。

        5. 命令回復(fù)處理器全部寫完到 socket 后,就會(huì)刪除該socket的AE_WRITABLE事件和命令回復(fù)處理器的映射。


        參考

        • 《Redis 設(shè)計(jì)與實(shí)現(xiàn)》


        點(diǎn)個(gè)在看支持我吧,轉(zhuǎn)發(fā)就更好了
        瀏覽 53
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            操啊操 | 人人妻人人澡人人DⅤD | 自由日本语亚洲人高潮 | 国产做爰全免费的视频黑人 | 韩国sejin室拍大尺度人体 | 欧美日日日日bbbbb视频 涩爱av色老久久精品偷偷鲁 | 韩国电影丰满的少妇 | 午夜福利精品在线观看 | 日本大香蕉网 | 国产乱伦视频 |