<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

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

          共 2397字,需瀏覽 5分鐘

           ·

          2020-09-05 20:57

          ????????

          單線程模型設(shè)計

          單線程模型為何效率高

          文件事件處理器

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


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

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


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


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


          socket

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

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

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

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

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


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

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

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

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

          ?文件事件分派器


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

          ?文件事件處理器


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


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


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

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

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


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





          ?文件事件的類型


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




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



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


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

          總結(jié)

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


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

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

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

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

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


          參考

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


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

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  99热这只有精品66 | 三级视频手机在线播放 | 久久色视频在线观看 | 激情视频国产 | 欧洲精品在线免费观看 |