乐于分享
好东西不私藏

Redis 4.0 → 7.2.13 源码演进完全指南

Redis 4.0 → 7.2.13 源码演进完全指南

一、源码结构全景Redis 7.2.13

先了解 7.2.13 的源码布局,这是理解演进的基础:

redis-7.2.13/src/├── server.h           # 核心头文件:redisObject、client、server 结构体├── server.c           # 主程序:main()、事件循环、命令分发├── anet.c / anet.h    # 网络封装(ANET = Redis networking)├── ae.c / ae_*.c      # 事件循环抽象层(epoll/kqueue/evport/select)├── connection.h       # 连接抽象(socket/Unix/TCP/TLS)├── [数据结构和命令]│   ├── t_string.c        # String 类型│   ├── t_hash.c          # Hash 类型│   ├── t_list.c          # List 类型│   ├── t_set.c           # Set 类型│   ├── t_zset.c          # Sorted Set 类型│   ├── t_stream.c        # Stream 类型(Redis 5.0+)│   ├── t_eval.c          # Lua 脚本│   ├── bitops.c          # 位操作│   └── hyperloglog.c     # HyperLogLog├── [集群]│   ├── cluster.c         # 集群管理│   └── cluster.h├── [持久化]│   ├── aof.c             # AOF 持久化│   ├── rdb.h / rdb.c     # RDB 格式和操作│   └── bio.c             # Background I/O 后台线程├── [复制]│   └── replication.c      # 主从复制(PSYNCv2)├── [安全]│   └── acl.c             # ACL 访问控制(Redis 6.0+)├── [模块系统]│   ├── redismodule.h     # 模块 API 头文件│   └── module.c / moduletype.c├── [其他核心]│   ├── dict.c            # 字典(Hash 表实现)│   ├── quicklist.c       # List 的压缩列表实现│   ├── sds.c             # 简单动态字符串│   ├── rax.c             # Radix Tree(Stream 索引)│   ├── latency.c          # 延迟监控│   ├── config.c           # 配置解析│   └── commands.def      # 命令定义(机器可读)└── [工具]    ├── redis-cli.c       # 客户端工具    └── cli_common.c      # 共享 CLI 代码

二、核心数据结构:理解一切的起点

2.1 redisObject — Redis 对象的基石

// server.h 中定义,贯穿整个 Redis 4→7 始终的核心结构struct redisObject {    unsigned type:4;        // 类型:STRING/LIST/HASH/SET/ZSET/...    unsigned encoding:4;    // 编码:int/embstr/hashtable/ziplist/listpack/...    unsigned lru:LRU_BITS; // LRU 或 LFU(Redis 4 开始支持 LFU)    int refcount;          // 引用计数(零拷贝的基础)    void *ptr;              // 指向实际数据};

演进

  • Redis 4.0 之前:只有 LRU(最近最少使用)
  • Redis 4.0 新增 LFU
    (Least Frequently Used):lru 字段的低 16 位存访问时间,高 8 位存频率计数

2.2 client — 连接与请求的封装

struct client {    int fd;                    // socket 文件描述符    sds querybuf;              // 累积请求缓冲区    int argc;                  // 命令参数个数    robj **argv;               // 命令参数    redisDb *db;               // 当前数据库    uint64_t flags;            // 客户端状态标志(Redis 4→7 持续膨胀)    list *reply;               // 回复缓冲区(链表)    char buf[PROTO_REPLY_CHUNK_BYTES]; // 固定大小回复缓冲(16KB)    // ... 大量字段持续增加};

2.3 server — 全局单例

struct redisServer {    redisDb *db;               // 数据库数组    dict *commands;            // 命令表(Redis 7 新增命令路由优化)    dict *orig_commands;        // 原始命令映射    list *clients;             // 所有客户端连接    client *master;             // 主节点(如果是从节点)    aeEventLoop *el;           // 事件循环    // ... 数百个字段};

三、Redis 4.0:模块化时代的起点

3.1 核心变化

特性
说明
Module API
外部模块动态加载(Redis 4.0 引入)
LFU 模式
淘汰策略新增 LFU(Least Frequently Used)
混合 AOF
AOF + RDB 混合持久化(aof-use-rdb-preamble
MEMORY USAGE
新增 MEMORY USAGE 命令
SWAPDB
交换数据库而不丢失数据
TLS
原生支持 TLS

3.2 LFU 原理详解

// redisObject.lru 字段在 LFU 模式下的布局(24 位)// LFU implementation: 16 bits for idle time, 8 bits for frequency// 高 16 位:自 LFU 初始化以来的分钟数(逻辑时钟)// 低 8 位:访问频率计数器(0-255)#define LFU_INIT_VAL 5  // 初始频率// 频率衰减:当对象未被访问时,频率会随时间衰减uint8_t LFULogIncr(uint8_t counter) {    if (counter < 255) {        double r = (double)rand() / RAND_MAX;        double base = (counter - LFU_INIT_VAL);        if (base > 0) counter = counter + (1/(base+1));        else counter++;    }    return counter;}

3.3 模块系统架构

┌─────────────────────────────────────────┐│           Redis Module System             ││                                         ││  redisModule.h(模块 API 头文件)         ││    ↓                                    ││  Module Type Registry                    ││    ↓                                    ││  ┌───────────────────────────────────┐  ││  │  Module A  │ Module B  │ Module C  │  ││  │  (RediSQL) │ (ReJSON) │ (vector)  │  ││  └───────────────────────────────────┘  ││    ↓                                    ││  Redis Core(server.c / server.h)       │└─────────────────────────────────────────┘

四、Redis 5.0:Stream 的诞生

4.1 核心变化

特性
说明
Redis Stream
新的数据类型,借鉴 Kafka 的持久化消息队列
Redis Cluster 改进
CLUSTER SLOTS命令
客户侧缓存(Client-side caching)
CSM,里程碑功能
新的 Redis 异步线程
UNLINK命令替代 DEL异步删除
ZPOPMAX / BZPOPMAX
有序集合弹出最高分元素
LOADAVERAGE
动态调整 HZ 频率

4.2 Stream 原理

Stream 是 Redis 5.0 最重要的数据结构创新:

// t_stream.c 中的核心结构typedef struct stream {    rax *rax;                  // Radix Tree(压缩前缀树),存储所有条目    uint64_t length;           // 条目数量    streamID last_id;          // 最后一条的 ID    rax *cgroups;              // 消费者组(Consumer Groups)} stream;// Stream ID:时间戳 + 序列号typedef struct streamID {    uint64_t ms;               // Unix 毫秒时间戳    uint64_t seq;              // 序列号} streamID;Stream 内部结构(Radix Tree 存储):root └── [0-9] → node → ...              ├── "1520000000000-0" → field1:value1, field2:value2              ├── "1520000000000-1" → ...              └── "1520000001234-99" → ...Consumer Group 消费模型:┌─────────────────────────────────────────────────┐│  Stream: mystream                               ││  1520000000000-0  → {field: value}              ││  1520000000000-1  → {field: value}              ││  1520000000000-2  → {field: value}              ││  1520000000000-3  → {field: value}              │└─────────────────────────────────────────────────┘                    ▲        ┌───────────┴───────────┐   Consumer Group A         Consumer Group B   last_delivered_id:       last_delivered_id:   1520000000000-1          1520000000000-0        │                         │        ▼                         ▼   Pending Entries List (PEL)  →  已ACK的自动清除

4.3 客户侧缓存(Client-side caching)原理

传统缓存模式:Client ────► Redis Server ────► 客户端本地缓存(自己管理失效)                ▲                │         网络往返延迟Client-side caching 模式:Redis Server ────[失效通知]───► Client    ▲                              ▲    │                              │    └────[请求/响应]────────────┘失效流程:1. Client 发送 CLIENT TRACKING ON2. Redis 记录该 Client 订阅的 Key3. 任何 Client 修改这些 Key 时,Redis 主动推送 INVALIDATE 消息4. 本地缓存立即失效,无需轮询

五、Redis 6.0:安全与性能的飞跃

5.1 核心变化

特性
说明
RESP3
新的客户端协议,支持更多数据类型
ACL v2
细粒度权限控制,支持命令/Key/通道规则
SSL/TLS
原生 TLS 支持
I/O Threads
多线程 I/O(实验性,6.0 是雏形,7.0 完善)
Threaded I/O

io-threads-do-reads yes

Client-output-buffer-limit
改进的输出缓冲区限制
DISCARD
MULTI/EXEC 事务中丢弃队列
功能:COMMAND INFO
命令级详情

5.2 ACL 核心原理

// acl.c 中的 ACL 结构typedef struct {    uint64_t bitfield;  // 位图表示权限    list *patterns;     // Key 允许模式(如 "cache:*")    list *commands;     // 允许的命令(如 "+get +set -del")    char *passwords;    // 密码(支持多个)    char *nkeys;        // Key 数量限制    char *channels;     // Pub/Sub 通道限制} user;// ACL 规则示例# 用户定义user reader on >password ~cached:* -@all +getuser writer on >password ~* +@write +@readuser admin on >password ~* +@admin +@dangerous +allkeys

5.3 RESP3 vs RESP2

RESP2(Redis 4-5.x 默认):+OK\r\n:100\r\n+string\r\n$-1\r\n  (nil)RESP3(Redis 6+):+OK\r\n:100\r\n=string\r\n        (类型前缀变化)#t\r\n            (true)#f\r\n            (false):123\r\n>100\r\n          (double)~[1,2,3]\r\n      (set 类型)%{key:val}\r\n    (map 类型)

5.4 I/O Threads 原理

// Redis 6.0 引入多线程 I/O,但处理逻辑仍然单线程// 线程分工://   Main Thread:协议解析 + 命令执行 + 响应生成//   I/O Threads:读取客户端请求 + 写入响应到 socket(可选)// io-threads 配置:// io-threads 4        → 4 个 I/O 线程// io-threads-do-reads yes  → I/O 线程也处理读请求// 注意:命令执行(command execution)始终在主线程// 多线程只加速了:read() / write() / accept() / connect()

六、Redis 7.0:架构重构的分水岭

6.1 核心变化

特性
说明
Redis Functions
替代 Lua 脚本,更好的管理和复用
Shard-level Pub/Sub
分片级发布订阅
ACL SELECTOR
更细粒度的 ACL 规则
Multi-part AOF
多部分 AOF,持久化更高效
新的 Shard-level replication
分片级复制
Command introspection
COMMAND 系列命令重构
Commands .def 文件
机器可读的命令定义
cluster-announce-*
集群节点通告优化

6.2 Redis Functions vs Lua Scripts

Redis 6.x Lua 脚本问题:.脚本不可复用(每次 EVAL 上传).无命名空间管理.版本控制困难.无法热更新Redis 7.x Functions:┌─────────────────────────────────────────┐│  LIBRARY(函数库)                       ││  #!js name=mylib                        ││  functionwrite_key(key, value{       ││    redis.call('SET', key, value)        ││  }                                      ││  redis.register_function(write_key)     │└─────────────────────────────────────────┘          │          ▼  FUNCTION LOAD → 函数注册到 Redis  FUNCTION LIST → 列出所有函数  FCALL write_key mykey myvalue → 调用  FUNCTION FLUSH → 清空所有函数

6.3 Multi-part AOF

Redis 7.0 之前(单 AOF):appendonly.aof  ├── base: RDB 格式(初始全量)  └── incr: AOF 命令增量Redis 7.0 Multi-part AOF:appendonlydir/  ├── base.${timestamp}.aof      → RDB 格式全量  ├── incr.${timestamp}.aof      → 增量 AOF  ├── incr.${timestamp}.aof.idx  → 索引  └── manifest                     → 文件清单(协调各部分)加载顺序:manifest → base → 按顺序重放 incr

6.4 命令定义文件(commands.def)

# Redis 7.0 引入的机器可读命令定义# src/commands.def 中每个命令的定义格式{    "GET": {        "summary""Get the value of a key",        "complexity""O(1)",        "arguments": [            {"name""key""type""key""key": {"flags": ["RO"]}}        ],        "flags": ["READONLY""FAST"]    }}

七、Redis 7.2:性能与安全的持续进化

7.1 性能优化(7.2 GA 引入)

命令
优化前复杂度
优化后
提升
PSUBSCRIBE / PUNSUBSCRIBE
O(N*M)
O(N)
订户多时显著
SCAN / SSCAN / HSCAN / ZSCAN
O(N)
更高效
减少阻塞
ZINTERCARD
创建临时 Sorted Set
避免临时对象
减少内存峰值
HRANDFIELD / ZRANDMEMBER
O(N) listpack
更优编码
减少 CPU
SPOP / RESTORE
同步删除
异步 unlink
减少主线程阻塞

7.2 事件循环的多路复用

// ae.c - Redis 事件循环抽象层,同时支持 4 种 I/O 多路复用:ae_select.c   → select()     (POSIX 通用,跨平台)ae_epoll.c    → epoll_wait() (Linux,高性能)ae_kqueue.c   → kqueue()     (macOS/BSD,高性能)ae_evport.c   → port_getn()  (Solaris/Illumos,高性能)// Redis 启动时自动选择最高效的后端:// Linux → epoll// macOS → kqueue// 其他  → select(兜底)// aeEventLoop 结构typedef struct aeEventLoop {    int maxfd;                // 最大 fd 编号    long long timeEventNextId;    aeFileEvent *events;      // 文件事件数组    aeFiredEvent *fired;      // 已触发事件数组    aeTimeEvent *timeEventHead;    int apidata;              // 平台特定数据(epoll_fd / kqueue_fd)    enum aeEventLoopFlags flags;} aeEventLoop;

八、演进全景图

┌─────────────────────────────────────────────────────────────────────────────┐│                      Redis 4.0 → 7.2.13 演进时间线                          │├─────────────────────────────────────────────────────────────────────────────┤│                                                                         ││  2017-07                         Redis 4.0 GA                            ││  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐    ││  │ Module   │ │  LFU     │ │ 混合AOF  │ │ MEMORY   │ │  SWAPDB  │    ││  │  API     │ │ 淘汰策略 │ │ (RDB+AOF)│ │ USAGE    │ │          │    ││  └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘    ││                                                                         ││  2018-10                         Redis 5.0 GA                            ││  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐    ││  │ Stream   │ │  CSM     │ │ UNLINK   │ │ ZPOPMAX  │ │ 动态 HZ  │    ││  │ (Kafka式)│ │ 客户端   │ │ 异步删除 │ │ /BZPOPMAX│ │ 调整     │    ││  │          │ │ 缓存     │ │          │ │          │ │          │    ││  └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘    ││                                                                         ││  2019-05                         Redis 6.0 GA                            ││  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐    ││  │ RESP3   │ │ ACL v2   │ │ I/O      │ │ SSL/TLS   │ │  大量    │    ││  │ 协议    │ │ 细粒度   │ │ 多线程   │ │ 原生支持  │ │ 安全修复 │    ││  │          │ │ 权限    │ │ (实验)   │ │          │ │ (CVE)    │    ││  └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘    ││                                                                         ││  2021-09                         Redis 7.0 GA                            ││  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐    ││  │ Functions│ │ Multi-   │ │ Shard    │ │ ACL      │ │ 命令定义 │    ││  │ (替代Lua)│ │ part AOF │ │ level    │ │ SELECTOR │ │ 机器可读 │    ││  │          │ │          │ │ Pub/Sub  │ │          │ │ (.def)   │    ││  └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘    ││                                                                         ││  2023-08 → 2026-02               Redis 7.2.x(持续维护)                  ││  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐    ││  │ 性能优化 │ │ 大量     │ │ PSUBSCRIBE│ │ HyperLog │ │ 安全修复 │    ││  │ PSUBSCRIBE│ │ Lua RCE │ │ O(N*M→  │ │ Log 漏洞 │ │ (7.2.13)│    ││  │ O(N)优化 │ │ 修复     │ │ O(N)     │ │ 修复     │ │          │    ││  └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘    ││                                                                         │└─────────────────────────────────────────────────────────────────────────────┘

九、源码层面的关键演进

9.1 内存分配器

// Redis 4.0 之前:jemalloc 是 Linux 默认(已有)// Redis 4-7:无变化,jemalloc 仍是默认分配器// 切换方式:#define make//jemalloc(默认 Linux)→ libc mallocmake MALLOC=libc//jemalloc(macOS 默认)→ jemallocmake MALLOC=jemalloc

9.2 持久化架构演进

Redis 3.x(单一 RDB):  BGSAVE → dump.rdb(全量快照)Redis 4.x(RDB + AOF 混合):  BGSAVE → dump.rdb  AOF    → appendonly.aof(增量命令)  两种同时开,互补长短Redis 7.x(Multi-part AOF):  appendonlydir/    base.${ts}.aof   → RDB 格式(定期生成)    incr.${ts}.aof  → 增量命令流    manifest         → 协调文件  → 加载更快,重写更高效

9.3 复制协议演进

Redis 3.x:PSYNCv1  - 完全同步(SYNC)或部分同步(PSYNC)  - 主库崩溃后从库需要全量同步Redis 4.x:无大变化,PSYNCv1 继续Redis 5.x:无大变化Redis 6.x:PSYNCv2(改进)  - 引入 Replica Offset Tracking  - 更好处理网络分区场景Redis 7.x  Shard-level replication  → 集群模式下副本可以跨分片复制

十、总结:每个版本的核心贡献

版本
最大的技术贡献
对业务的影响
4.0
Module API + LFU
第三方扩展生态;缓存淘汰更精准
5.0
Stream + CSM
消息队列能力;客户侧缓存减少 Redis 压力
6.0
RESP3 + ACL v2 + I/O Threads
协议升级;安全权限;性能提升
7.0
Functions + Multi-part AOF
脚本管理规范化;AOF 重写不再阻塞
7.2
PSUBSCRIBE 优化 + 大量安全修复
Pub/Sub 性能飞跃;安全性追平