Redis 事件驅動與多路復用源碼剖析

Redis 事件驅動與多路復用源碼剖析

在這里插入圖片描述

1. 前言

Redis 是 單線程 + I/O 多路復用 的典型代表。
它并不是多線程處理請求,而是依賴 事件驅動(event-driven)模型,在一個線程內高效管理海量連接。

核心組件:

  • ae.c:事件驅動框架,封裝了事件循環(event loop)。
  • anet.c:網絡封裝層,簡化 socket API,提供可靠網絡通信。
  • I/O 多路復用:底層可使用 epoll(Linux)、kqueue(BSD)、select(通用)。

2. Redis 事件模型概覽

2.1 兩類事件

  • 文件事件(File Event):指網絡套接字上的讀寫操作。
  • 時間事件(Time Event):定時器任務(如定期持久化、心跳、清理)。

2.2 事件循環

Redis 的事件循環大致流程:

while (server is running) {# 處理文件事件(網絡 I/O)aeProcessEvents(loop);# 處理定時事件processTimeEvents();# 執行后臺任務(AOF 重寫、內存釋放)cron();
}

👉 事件循環是 Redis 單線程并發調度的核心


3. ae.c — 事件驅動框架

3.1 aeEventLoop 結構

ae.c 中,事件循環的核心結構是:

typedef struct aeEventLoop {int maxfd;                 // 當前已注冊的最大 fdfd_set rfds, wfds;         // 監聽的讀寫事件aeFileEvent *events;       // 已注冊的文件事件aeFiredEvent *fired;       // 已觸發的文件事件aeTimeEvent *timeEventHead;// 時間事件鏈表int stop;                  // 是否停止循環
} aeEventLoop;
  • events[]:保存所有已注冊的 socket 事件。
  • fired[]:保存已觸發的事件,等待回調執行。
  • timeEventHead:鏈表存放定時器任務。

3.2 注冊文件事件

當一個客戶端連接進來時,Redis 會調用 aeCreateFileEvent() 注冊事件:

int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask,aeFileProc *proc, void *clientData) {aeFileEvent *fe = &eventLoop->events[fd];fe->mask |= mask;      // 注冊讀/寫事件fe->rfileProc = proc;  // 設置事件處理回調
}

👉 每個 socket fd 都綁定了 讀寫事件回調函數

3.3 事件分發與處理

事件循環執行時,會調用 aeProcessEvents()

int aeProcessEvents(aeEventLoop *eventLoop) {int numevents = aeApiPoll(eventLoop, ...); // 調用 epoll/select 等等待事件for (int j = 0; j < numevents; j++) {int fd = eventLoop->fired[j].fd;int mask = eventLoop->fired[j].mask;aeFileEvent *fe = &eventLoop->events[fd];if (mask & AE_READABLE) fe->rfileProc(fd, fe->clientData);if (mask & AE_WRITABLE) fe->wfileProc(fd, fe->clientData);}
}

👉 核心邏輯:等待事件 → 找到回調 → 執行回調


4. anet.c — 網絡通信層

anet.c 對 BSD socket API 做了封裝,簡化了網絡調用。

4.1 建立連接

int anetTcpServer(char *err, int port, char *bindaddr) {int s = socket(AF_INET, SOCK_STREAM, 0);anetSetReuseAddr(s);   // 設置 SO_REUSEADDRbind(s, ...);listen(s, 511);        // backlog = 511return s;
}

👉 創建 TCP 服務器 socket,并監聽端口。

4.2 接收新連接

int cfd = accept(s, ...);
anetNonBlock(cfd);   // 設置非阻塞
anetEnableTcpNoDelay(cfd);

👉 新連接的 socket 設置為 非阻塞模式,避免 I/O 阻塞。


5. I/O 多路復用實現

Redis 在 ae_epoll.c / ae_kqueue.c / ae_select.c 中封裝了多路復用實現。

5.1 epoll 示例

static int aeApiPoll(aeEventLoop *eventLoop, ...) {int numevents = epoll_wait(epfd, events, ...);for (int j = 0; j < numevents; j++) {eventLoop->fired[j].fd = events[j].data.fd;eventLoop->fired[j].mask = events[j].events;}return numevents;
}

👉 Linux 上默認使用 epoll,可支持 百萬連接

5.2 select 回退

如果系統不支持 epoll/kqueue,Redis 會回退到 select 實現,保證兼容性。


6. 源碼調用鏈梳理

完整鏈路如下:

server.c (主循環)└─ aeMain()└─ aeProcessEvents()└─ aeApiPoll()   # 調用 epoll_wait└─ rfileProc()   # 讀事件回調,讀取客戶端命令└─ wfileProc()   # 寫事件回調,返回響應

7. 單線程高并發的秘密

  1. 非阻塞 I/O:所有 socket 設置非阻塞。
  2. I/O 多路復用:同時監聽大量 socket。
  3. 事件回調機制:讀寫操作通過回調函數執行,不會阻塞主線程。
  4. 計算與 I/O 解耦:命令解析、執行、響應都在主線程完成,避免線程切換開銷。

👉 因此,Redis 在單線程下也能支撐 十萬級并發請求


8. 小結

本文解析了 Redis 事件驅動與多路復用的實現:

  • ae.c:事件循環框架,統一調度文件事件和時間事件。
  • anet.c:封裝 socket API,提供簡化的網絡接口。
  • I/O 多路復用:基于 epoll/kqueue/select,支持高并發連接。
  • 單線程模型:通過事件驅動和非阻塞 I/O,避免多線程鎖競爭。

📌 Redis 高性能的核心秘訣之一,就是 單線程 + 多路復用 的高效事件驅動架構。


👉 下一篇我們可以寫 Redis 命令執行流程與內核數據結構(命令表、解析、執行、回復機制),這樣整個 Redis 執行鏈路就完整了。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/923536.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/923536.shtml
英文地址,請注明出處:http://en.pswp.cn/news/923536.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

VR煤礦實訓系統相較于傳統煤礦培訓方式的獨特優勢?-廣州華銳互動

高度逼真&#xff0c;沉浸體驗?VR煤礦實訓系統運用先進的3D建模、動態仿真技術&#xff0c;對煤礦井下的復雜環境進行1:1還原。從幽深的巷道、運轉的采煤設備&#xff0c;到潮濕的空氣、昏暗的燈光&#xff0c;甚至細微的煤塵顆粒&#xff0c;都能逼真呈現。使用者戴上VR設備后…

javaweb XML DOM4J

XMLXML作用就是配置文件&#xff0c;properties使用不了較復雜的需求&#xff0c;xml應運而生配置文件對比 xml更方便tips1:新建resources目錄&#xff0c;并將src中的jdbc.properties移到resourcs中&#xff0c;并且右鍵標記為源代碼根目錄&#xff0c;這樣運行src時就會和pro…

多模態視頻理解領域 Benchmark 與 Leaderboard 整理

多模態視頻理解是當前人工智能領域的研究熱點&#xff0c;其核心目標是讓模型像人類一樣&#xff0c;綜合視頻中的視覺、聽覺&#xff08;部分場景&#xff09;及文本信息&#xff0c;實現對視頻內容的深度感知、理解與推理。為客觀評估模型性能&#xff0c;行業內涌現了眾多權…

18j621-3通風天窗圖集pdf(免費高清版)

18j621-3通風天窗已經替代05j621-3通風天窗圖集成為目前比較通用的建筑屋頂通風選型重要參考標準&#xff0c;18j621-3圖集是對前圖集的優化和革新&#xff0c;在18j621-3圖集中新增了TC8圓拱型電動采光天窗&#xff0c;豐富了屋面通風排煙設備的選型。在18j621-3天窗圖集中&am…

LawGPT:基于中文法律知識的大模型

本文轉載自&#xff1a;https://www.hello123.com/lawgpt ** 一、?? LawGPT&#xff1a;中文法律界的 “AI 法助”&#xff0c;啃透了 15 萬份判決書&#xff01; LawGPT 是一系列專攻中文法律知識的開源大模型&#xff0c;在通用中文基座&#xff08;如 ChatGLM&#xff0…

用 go-commons 快速寫一個監控 CPU/內存的 Exporter

歡迎加入開源項目&#xff0c;提你的 mr Go Commons&#xff1a;Golang 開發者的常用工具集&#xff0c;一站式解決常見需求 在 Go 語言的開發過程中&#xff0c;你是不是經常遇到這樣的情況&#xff1a; 想要做點小功能&#xff0c;卻得從零寫起&#xff0c;或者到處找三方…

KingbaseES客戶端工具Ksql使用全指南:從安裝到高級操作

引言 在國產數據庫蓬勃發展的今天&#xff0c;KingbaseES憑借其自主可控、高性能、高可用的特性&#xff0c;已成為政務、金融、能源等關鍵領域的首選數據庫。而作為其配套的命令行工具&#xff0c;Ksql更是DBA和開發人員的“瑞士軍刀”——它不僅能高效執行SQL查詢&#xff0c…

【LeetCode - 每日1題】可以輸入的最大單詞數

?? 個人主頁:(時光煮雨) ?? 高質量專欄:vulnhub靶機滲透測試 ?? 希望得到您的訂閱和支持~ ?? 創作高質量博文(平均質量分95+),分享更多關于網絡安全、Python領域的優質內容!(希望得到您的關注~) ??目錄?? 難度 ?? 題目回顧 ?解題思路 ??概述 ??核心…

3227. 字符串元音游戲

3227. 字符串元音游戲 題目鏈接&#xff1a;3227. 字符串元音游戲 代碼如下&#xff1a; class Solution { public:bool doesAliceWin(string s) {return ranges::any_of(s, [](char c) {return c a || c e || c i || c o || c u;});} };

微信小程序坐標位置使用整理(四)map組件

一、地圖上標點&#xff0c;marker 1.wxml <map id"map" scale"9" class"map"markers"{{markers}}" longitude"{{longitude}}" latitude"{{latitude}}" show-location"{{true}}"><cover-vie…

Parlant框架深度技術解析:革命性AI代理行為建模引擎

引言 在人工智能快速發展的今天&#xff0c;AI代理&#xff08;Agent&#xff09;技術已經成為連接人工智能與實際應用場景的重要橋梁。然而&#xff0c;傳統的AI代理開發面臨著諸多挑戰&#xff1a;提示詞工程的復雜性、行為不可預測性、工具調用的不確定性等問題嚴重制約了AI…

AI重構車載測試:從人工到智能的跨越

目錄 一、AI 在車載測試中的核心價值 二、AI 在車載測試的具體應用場景 (一)自動駕駛測試:AI 解決 “場景覆蓋” 與 “決策可靠性” 難題 (二)車機系統測試:AI 優化 “交互體驗” 與 “功能穩定性” (三)車載硬件測試:AI 實現 “故障預測” 與 “精準校準” (四)功能…

從職責劃分看架構:MVC 的 Controller 與 MVVM 的 ViewModel 差異

深入淺出&#xff1a;前端MVC與MVVM架構模式&#xff0c;你真的懂了嗎&#xff1f;? 序言 各位前端的“程序猿”和“程序媛”們&#xff0c;大家好&#xff01;&#x1f44b; 在前端開發的江湖中&#xff0c;MVC和MVVM這兩個詞&#xff0c;就像武林秘籍一樣&#xff0c;常常被…

Vue-color:Vue.js 專業顏色選擇器組件庫 – 支持Vue2/3,TypeScript,暗色主題

簡介 Vue-color 是一個專為 Vue.js 設計的顏色選擇器組件庫&#xff0c;提供了多種風格的顏色選擇器組件。它支持 Vue 2.7 和 Vue 3&#xff0c;具有 TypeScript 支持、SSR 兼容性和暗色主題支持。 特性 多種顏色選擇器 – 提供 Chrome、Sketch、Photoshop 等多種風格Vue 2.…

ArcGIS定向影像(2)——非傳統影像輕量級解決方案

ArcGIS能讓用戶自己低成本的做出谷歌街景嗎&#xff1f;現在ArcGIS Pro 3.2 和 ArcGIS Enterprise 11.2 能夠讓用戶不使用任何插件和擴展的情況下完成街景數據集的構建&#xff0c;數據管理&#xff0c;發布服務和調用的完整解決方案。非常體系化&#xff0c;由底層數據驅動&am…

CKA05--service

Task 重新配置 spline-reticulator namespace 中現有的 front-end Deployment&#xff0c;以公開現有容器 nginx 的端口 80/tcp 創建一個名為 front-end-svc 的新 Service &#xff0c;以公開容器端口 80/tcp 配置新的 Service &#xff0c;以通過 NodePort 公開各個 Pod 解析&…

用 Go 采集服務器資源指標:從原理到實踐

在后端開發或運維工作中&#xff0c;采集服務器資源指標 是個繞不開的需求&#xff1a; 運維要看 CPU、內存、磁盤的使用情況監控系統要定期上報這些數據應用程序有時候也需要根據系統負載做限流、彈性伸縮 那么問題來了&#xff1a;用 Go 怎么優雅地采集這些指標呢&#xff…

安卓學習 之 上下文菜單的操作

先來認識一下上下文菜單是什么樣子的&#xff1f;如圖&#xff0c;當長按一個控件時彈出來的菜單叫做上下文菜單&#xff1a;圖中第一個和第二個就是一個上下文菜單&#xff0c;第二個菜單里面還有一層菜單&#xff0c;這個上下文菜單被綁定到注冊按鈕中&#xff0c;也就是長按…

fabric啟動節點var/hyperledger/production: permission denied

場景我在節點的compose文件中進行了數據掛載&#xff1a;- ../../data/bank1/peer1:/tmp/hyperledger/bank1/peer1但是運行是依然報錯為var/hyperledger/production的權限問題&#xff0c;并且我也已經對../../data/bank1/peer1目錄設置了操作權限services:peer1-bank1:contain…

uni-app + Vue3 開發展示 echarts 圖表

場景:使用 uni-app 開發手機端,需要展示 echarts 圖表 1. 打開 uni-app 官網 https://uniapp.dcloud.net.cn/ 2. 點擊右上角搜索 3. 點擊插件市場,搜索 echarts 找到 echarts 插件 4. 下載到自己的項目中 使用詳情在該頁面下方.