Redis 核心源码解析:从设计哲学到企业级应用实践

一、Redis 的核心设计哲学

Redis 的成功源于其 「用内存换时间」 的核心理念,围绕以下三个核心原则构建:

  1. 极简主义:单线程模型避免锁竞争,代码保持高度内聚。

  2. 性能至上:所有数据常驻内存,网络层采用事件驱动模型。

  3. 可扩展性:模块化设计,通过插件机制支持新功能。


二、源码目录结构解析

从 Redis 7.0 源码看核心模块:

redis/src
├── ae.c              # 事件循环(核心)
├── anet.c            # 网络抽象层
├── dict.c            # 哈希表实现
├── object.c          # 数据类型封装
├── rdb.c             # RDB持久化
├── aof.c             # AOF持久化
├── server.c          # 服务端主逻辑
├── networking.c      # 客户端连接处理
└── modules           # 模块化扩展

三、核心模块源码深度解析
1. 事件驱动模型:单线程为何能扛10万QPS?

Redis 采用 Reactor 模式 实现高并发,核心代码在 ae.c

// 事件循环主逻辑(ae.c)
void aeMain(aeEventLoop *eventLoop) {eventLoop->stop = 0;while (!eventLoop->stop) {aeProcessEvents(eventLoop, AE_ALL_EVENTS | AE_CALL_BEFORE_SLEEP);}
}// 处理事件(精简版)
int aeProcessEvents(aeEventLoop *eventLoop, int flags) {// 1. 获取最近要到期的时间事件shortest = aeSearchNearestTimer(eventLoop);// 2. 等待文件事件(epoll_wait/kevent等)numevents = aeApiPoll(eventLoop, tvp);// 3. 处理文件事件(网络请求)for (j = 0; j < numevents; j++) {fe = &eventLoop->events[eventLoop->fired[j].fd];fe->rfileProc(...); // 处理读事件fe->wfileProc(...); // 处理写事件}// 4. 处理时间事件(如过期键清理)processed += processTimeEvents(eventLoop);
}

技术要点

  • 基于 epoll/kqueue 实现多路复用

  • 单线程顺序处理事件,避免锁开销

  • 时间事件与文件事件协同调度


2. 内存管理:如何实现高效数据存储?

核心结构 redisObject(object.c):

typedef struct redisObject {unsigned type:4;        // 数据类型(string/hash等)unsigned encoding:4;    // 编码方式(优化存储)unsigned lru:24;        // LRU时间戳int refcount;           // 引用计数void *ptr;              // 数据指针
} robj;// 字符串类型示例(sds.h)
struct sdshdr {int len;        // 已用长度int free;       // 剩余空间char buf[];     // 柔性数组
};

编码优化策略

  • String:int编码(存储整数时) vs embstr编码(短字符串) vs raw编码

  • Hash:ziplist(元素少时) vs hashtable

  • Sorted Set:skiplist + dict 实现 O(logN) 查询


3. 持久化机制:RDB与AOF如何协同工作?

RDB 快照生成(rdb.c)

// 异步生成RDB(fork子进程)
int rdbSaveBackground(char *filename, rdbSaveInfo *rsi) {if ((childpid = fork()) == 0) {// 子进程执行实际保存retval = rdbSave(filename,rsi);exitFromChild((retval == C_OK) ? 0 : 1);} else {// 父进程记录状态server.rdb_child_pid = childpid;}
}

AOF 重写(aof.c)

// 重写AOF文件(同样fork子进程)
int rewriteAppendOnlyFileBackground(void) {if (aofCreatePipes() != C_OK) return C_ERR;if ((childpid = fork()) == 0) {// 子进程重写if (rewriteAppendOnlyFile(tmpfile) == C_OK) {exitFromChild(0);}}
}

持久化流程对比

RDBAOF
原理内存快照操作日志追加
优点恢复快、文件小数据丢失风险低
缺点数据可能丢失文件大、恢复慢

4. 数据结构:Sorted Set 如何实现高效排序?

核心代码 t_zset.c

// 跳跃表节点定义
typedef struct zskiplistNode {sds ele;                            // 成员double score;                       // 分数struct zskiplistNode *backward;     // 后退指针struct zskiplistLevel {struct zskiplistNode *forward;  // 前进指针unsigned long span;             // 跨度} level[];                          // 层级数组
} zskiplistNode;// 插入节点核心逻辑
zskiplistNode *zslInsert(zskiplist *zsl, double score, sds ele) {// 1. 随机生成节点层级(幂次定律)level = zslRandomLevel();// 2. 查找插入位置for (i = zsl->level-1; i >= 0; i--) {while (x->level[i].forward && (x->level[i].forward->score < score || ... )) {x = x->level[i].forward;}update[i] = x;}// 3. 创建新节点并调整指针x = zslCreateNode(level,score,ele);for (i = 0; i < level; i++) {x->level[i].forward = update[i]->level[i].forward;update[i]->level[i].forward = x;}
}

性能优势

  • 跳跃表平均 O(logN) 时间复杂度

  • 结合哈希表实现 O(1) 成员存在性检查


四、企业级应用源码适配案例
案例1:分布式锁实现(Redlock算法)
// 加锁命令(基于SET命令)
SET lock_key $unique_id NX PX 30000// 解锁Lua脚本(保证原子性)
if redis.call("get",KEYS[1]) == ARGV[1] thenreturn redis.call("del",KEYS[1])
elsereturn 0
end

源码支撑

  • SET 命令在 t_string.c 实现

  • Lua 脚本执行逻辑在 scripting.c


案例2:热点数据缓存穿透防御
// 布隆过滤器实现(redisbloom模块)
BF.ADD hot_items:filter "item_123"
BF.EXISTS hot_items:filter "item_456"

源码扩展

  • 模块化开发接口在 redismodule.h

  • 底层使用 dablooms 库实现


五、Redis 核心架构图
+-------------------+
|      Client       |
+-------------------+|| 发送命令v
+-------------------+
|    Event Loop     | <--- 文件事件(网络I/O)
| (ae.c/ae_epoll.c) | 
|                   | <--- 时间事件(过期键清理)
+-------------------+|| 命令路由v
+-------------------+
|   Command Table   | ---> 命令处理器(get/set等)
|  (server.c/cmd)   |
+-------------------+|| 数据操作v
+-------------------+
|    Data Store     | ---> 字符串/hash/有序集合等
| (object.c/t_*.c)  |
+-------------------+|| 持久化触发v
+-------------------+
|  Persistence      | ---> RDB(rdb.c) / AOF(aof.c)
+-------------------+

六、Redis 的局限与优化方向
  1. 内存限制:可通过 Redis Cluster 分片扩展

  2. 单线程瓶颈:Redis 6.0 引入多线程I/O(仍保持命令处理单线程)

  3. 持久化风险:建议 RDB+AOF 混合使用,定期备份

  4. 扩展性:通过 Module 机制集成新功能(如 RedisSearch)


七、总结

通过源码分析可深入理解 Redis 的 高性能设计精髓

  1. 事件驱动模型:单线程扛高并发

  2. 内存数据结构:精心优化的编码方式

  3. 可扩展架构:模块化设计支持二次开发

企业级应用建议:

  • 性能敏感场景:结合跳跃表、哈希表特性设计数据结构

  • 高可用要求:部署 Redis Cluster + Sentinel 监控

  • 混合持久化:RDB 定期快照 + AOF 实时日志

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/74406.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GZCTF平台搭建及题目上传

前言 我用手里的Ubuntu虚拟机搭建的&#xff0c;大家根据自己的实际情况来吧 安装及部署 首先&#xff0c;你的虚拟机需要有Docker和Docker-Compose&#xff0c;前者可以看我之前的文章&#xff0c;另外一个可以输入下面的命令安装&#xff0c;注意先获取管理员权限&#xff…

Pycharm社区版创建Flask项目详解

一、创建工程项目 二、配置工程目录 新建的空项目下创建目录。 1、新建app.py文件 2、app.py代码如下&#xff1a; from flask import Flask, render_templateapp Flask(__name__)app.route("/") def root():"""主页:return: Index.html"&qu…

CentOS 7 64位安装Docker

以下是在已有的 CentOS 7 64 位虚拟机上安装 Docker 并配置华为镜像源的详细步骤&#xff1a; 1. 备份原有 Yum 源&#xff08;可选&#xff0c;建议操作&#xff09; # 备份原有仓库文件 sudo mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backu…

运动仿真——phased.Platform

在雷达仿真过程中&#xff0c;运动仿真的必要性&#xff0c;以及运动仿真可以实现哪些功能&#xff0c;在matlab对应的user guide中已经讲的很清楚了&#xff0c;这里不再赘述。 本文主要介绍phased.Platform的一些“坑”&#xff0c;和典型的用法。 第一坑&#xff1a;系统对…

缓存删除三级补偿方案:延迟队列+消息队列+定时任务兜底

问题背景: 在 Cache-Aside 模式中&#xff0c;更新数据库后删除缓存失败会导致数据不一致。本文提供工业级三级补偿方案&#xff0c;实现最终一致性保障。 整体架构: 更新操作触发 → 一级延迟队列 → 二级消息队列 → 三级定时任务方案实现: 一、第一级补偿&#xff1a;延迟队…

从零开始实现 C++ TinyWebServer 数据库连接池 SqlConnectPool详解

文章目录 数据库连接池是什么&#xff1f;Web Server 中为什么需要数据库连接池&#xff1f;SqlConnectPool 成员变量实现 Init() 函数实现 ClosePool() 函数SqlConnectRAII 类SqlConnectPool 代码SqlConnectPool 测试 从零开始实现 C TinyWebServer 项目总览 项目源码 数据库连…

C++题目

1、内存管理 1.内存模型 栈:在执行函数时&#xff0c;函数内局部变量的存储单元都可以在栈上创建&#xff0c;函数执行结束时这些存储单元自动被释放。 堆&#xff1a;就是那些由new分配的内存块&#xff0c;其释放由程序员控制&#xff08;一个new对应一个delete&#xff09…

天地图InfoWindow插入React自定义组件

截至2025年03月21日天地图的Marker不支持添加Label; 同时Label和Icon是不支持自定义HTMLElement只支持String&#xff1b;目前只有InfoWindow支持自定义HTMLElement; 效果图 React核心api import ReactDOM from react-dom/client const content document.createElement(div);…

Java并发编程面试汇总

Java并发编程 一、 基础概念1. 进程与线程的区别是什么&#xff1f;2. 创建线程的几种方式&#xff1f;3. 线程的生命周期&#xff08;状态&#xff09;有哪些&#xff1f;4. 什么是守护线程&#xff08;Daemon Thread&#xff09;&#xff1f;5. 线程优先级&#xff08;Priori…

【STM32】第一个工程的创建

目录 1、获取 KEIL5 安装包2、开始安装 KEIL52.1、 激活2.2、安装DFP库 3、工程创建4、搭建框架5、开始编写代码 1、获取 KEIL5 安装包 要想获得 KEIL5 的安装包&#xff0c;在百度里面搜索“KEIL5 下载”即可找到很多网友提供的下载文件&#xff0c;或者到 KEIL 的官网下载&a…

动态规划~01背包问题

01背包问题 经典的0 - 1背包问题的解决方案。 二维数组的版本 代码功能概述 0 - 1背包问题指的是有 n 个物品和一个容量为 m 的背包&#xff0c;每个物品有对应的体积 v[i] 和价值 w[i]&#xff0c;需要从这些物品里挑选若干个放入背包&#xff0c;让背包内物品的总价值达到最…

深入理解Java享元模式及其线程安全实践

引言 在软件系统中&#xff0c;当需要处理海量细粒度对象时&#xff0c;直接创建大量实例可能会导致内存消耗激增和性能下降。享元模式&#xff08;Flyweight Pattern&#xff09;通过共享对象内部状态&#xff0c;成为解决这类问题的经典方案。然而在多线程环境下&#xff0c…

1、mysql基础篇--概述

关系型数据库&#xff08;RDBMS&#xff09; 概念特点&#xff1a;数据模型&#xff1a; 概念 建立在关系模型基础上&#xff0c;有多张表相互连接的二维表组成的数据库 特点&#xff1a; 1、使用表存储&#xff0c;格式统一&#xff0c;便于维护 2、使用sql语言操作&#…

如何提升库存系统的高并发和稳定性:算法与设计模式

库存系统是企业运营的核心模块&#xff0c;尤其是在电商、零售和供应链管理中&#xff0c;系统的高并发和稳定性直接影响订单处理的准确性和效率。面对海量订单、复杂的库存管理需求&#xff0c;如何在高并发环境下确保库存数据的准确性和系统的稳定性&#xff1f;本文将从架构…

【多线程】synchronized底层实现的方式

前言 在java 开发中对于锁的应用非常的常见&#xff0c;如果对于什么时候该用什么锁&#xff0c;以及锁实现的原理有所不知道的&#xff0c;或者面试过程中面试官问你不知道怎么回答的&#xff0c;欢迎来看下面的文章 1、synchronized和ReentrantLock的区别 2、synchronized的…

Pytorch中Tensorboard的学习

1、Tensorboard介绍 TensorBoard 是 TensorFlow 开发的一个可视化工具&#xff0c;用于帮助用户理解和调试机器学习模型的训练过程。尽管它最初是为 TensorFlow 设计的&#xff0c;但通过 PyTorch 的 torch.utils.tensorboard 模块&#xff0c;PyTorch 用户也可以方便地使用 Te…

ETL 自动化:提升数据处理效率与准确性的核心驱动力

在数字化转型的浪潮中&#xff0c;数据已成为企业战略资产&#xff0c;高效处理数据的能力直接关系到企业的竞争力。ETL&#xff08;Extract, Transform, Load&#xff09;自动化作为数据处理领域的关键技术&#xff0c;正逐渐成为企业在数据时代脱颖而出、实现高效运营与精准决…

std::endl为什么C++ 智能提示是函数?

在使用vscode 的C智能提示后&#xff0c;输入endl 后&#xff0c;提示的却是std::endl(basic_ostream<CharT, Traits> &os), 感觉比较奇怪&#xff0c;各种代码里都是直接用的std::endl 啊&#xff0c; 这里怎么变成函数了呢&#xff1f; 在 C 中&#xff0c;std::en…

简洁、实用、无插件和更安全为特点的WordPress主题

简站WordPress主题是一款以简洁、实用、无插件和更安全为特点的WordPress主题&#xff0c;自2013年创立以来&#xff0c;凭借其设计理念和功能优势&#xff0c;深受用户喜爱。以下是对简站WordPress主题的详细介绍&#xff1a; 1. 设计理念 简站WordPress主题的核心理念是“崇…

数据结构篇:空间复杂度和时间复杂度

目录 1.前言&#xff1a; 1.1 学习感悟 1.2 数据结构的学习之路(初阶) 2.什么是数据结构和算法 2.1 数据结构和算法的关系 2.2 算法的重要性 2.3 如何衡量算法的好坏 3.时间复杂度 3.1 时间复杂度的概念 3.2 大O的渐进表示法 O() 4.空间复杂度 5. 常见的时间复杂度和…