redis学习过程

可以从github上拉一份redis来看,发现redis是用C语言来实现的。高性能kv数据库,为何高效呢?因为在内存,内存离CPU比磁盘更近,所以高效。

你可以先把 Redis 理解成一句话:

Redis 主线程不断从 socket 读命令,解析成 argv ,查命令表,调用对应函数,最后操作 db->keys 这个内存字典。

我们从第0层开始学习

cpp 复制代码
客户端
  │  (网络层)
  ▼
[1.网络/连接]  ──→  [2.命令分发]  ──→  [3.数据结构与对象]
  ae.c              server.c           object.c + t_*.c
  networking.c      command table      dict/sds/listpack...
                          │
                          ▼
                    [4.数据库语义]
                    db.c / expire.c / evict.c
                          │
            ┌─────────────┼─────────────┐
            ▼             ▼             ▼
      [5.持久化]    [6.复制/高可用]  [7.集群]
      rdb.c/aof.c   replication.c    cluster.c
                    sentinel.c

存到内存的到底是什么

struct redisObject {

unsigned type:4; // 这是什么类型?string/list/hash/set/zset...

unsigned encoding:4; // 底层用什么结构存?(同一类型可以有多种存法)

unsigned refcount : 23; // 引用计数:有多少人在用我,降到0就释放

unsigned iskvobj : 1;

unsigned metabits :8;

unsigned lru:LRU_BITS; // 上次访问时间,用于 LRU/LFU 淘汰

void *ptr; // 真正的数据在这里(指向 sds、dict、quicklist...)

};

这是整个 Redis 最核心的一个结构。 你执行 SET a 1 ,那个 "1" 在内存里就是一个 robj 。理解它:

#define OBJ_STRING 0 // 字符串

#define OBJ_LIST 1 // 列表

#define OBJ_SET 2 // 集合

#define OBJ_ZSET 3 // 有序集合

#define OBJ_HASH 4 // 哈希

typedef struct redisDb {

kvstore *keys; // ★ 所有的 key→value 都在这里(这就是"数据库"本体)

kvstore *expires; // 设置了过期时间的 key 在这里

...

dict *watched_keys; // 被 WATCH 监视的 key(事务用)

int id; // 数据库编号 0~15

...

} redisDb;

struct redisObject {

unsigned type:4; // 这是什么类型?string/list/hash/set/zset...

unsigned encoding:4; // 底层用什么结构存?(同一类型可以有多种存法)

unsigned refcount : 23; // 引用计数:有多少人在用我,降到0就释放

unsigned iskvobj : 1;

unsigned metabits :8;

unsigned lru:LRU_BITS; // 上次访问时间,用于 LRU/LFU 淘汰

void *ptr; // 真正的数据在这里(指向 sds、dict、quicklist...)

};

cpp 复制代码
1. 客户端发字节 "SET a 1"
        │
2. 网络层读进来,解析成 argv = ["SET", "a", "1"]      (robj 数组)
        │
3. 拿 "SET" 查命令表 → 找到 redisCommand → 调用 proc = setCommand
        │
4. setCommand 把值 "1" 包成一个 robj(用 INT 编码)
        │
5. 把 "a" → robj("1") 写进当前 db->keys
        │
6. 回复客户端 "+OK"

最值得学

cpp 复制代码
最值得学

- 事件驱动模型 :Redis 用事件循环处理网络 IO、定时任务、后台状态推进,是理解高性能服务端的绝佳样本。
- 简单抽象叠复杂能力 :核心就是 client 、 redisCommand 、 redisDb 、对象系统、事件循环,但上面能长出事务、Lua、复制、AOF、集群。
- 数据结构工程化 :不是教科书里的 Hash/List/Skiplist,而是 SDS、dict、quicklist、listpack、intset、rax 这些"为内存和性能妥协过"的实现。
- 命令执行管线 :从网络协议到 argv ,再到命令表和函数指针分发,这是很多数据库、网关、RPC 框架都共通的设计。
- 持久化设计 :RDB 是快照,AOF 是日志,二者组合体现了数据库系统里性能、恢复速度、可靠性之间的取舍。
- 复制与高可用 :主从复制、PSYNC、backlog、Sentinel、failover,是理解分布式系统的好入口。
- 过期与内存淘汰 :懒删除、主动过期、LRU/LFU 近似算法,非常适合学习"如何在性能和准确性之间折中"。
- 渐进式维护 :渐进式 rehash、active expire、lazyfree,把大任务拆成小步做,是高性能系统非常核心的思想。

1.理解主循环、命令分发、GET/SET 读写路径

主循环

cpp 复制代码
void aeMain(aeEventLoop *eventLoop) {
    eventLoop->stop = 0;
    while (!eventLoop->stop) {
        aeProcessEvents(eventLoop, AE_ALL_EVENTS|
                                   AE_CALL_BEFORE_SLEEP|
                                   AE_CALL_AFTER_SLEEP);
    }
}

RDB和AOF

RDB的流程是fork一个子进程,利用虚拟内存地址的写实拷贝,去全量的把数据全部拿出来。

AOF的话类似于MYSQL的binlog,记录的命令执行过程。

现代生产环境一般是复合使用的。过一段时间先frok进程去全量RDB文件,然后在此期间产生的命令在以AOF的形式追加到文件的末尾。

相关推荐
IT北辰2 小时前
神通数据库管理系统V7.0.251210 for Windows(x86 64bit)安装部署
数据库·神通
北顾笙9802 小时前
MySQL-day2
数据库·mysql
Demons_kirit2 小时前
新项目如何连接上自己本地的数据库
数据库
洪晓露3 小时前
将 rke2 集群证书延长至 10 年
运维·服务器·数据库
程序猿乐锅3 小时前
【MySQL | 第八篇】MySQL 视图
数据库·mysql
旅僧4 小时前
Π环境部署(运行 且 无理论讲解)
学习
jushi89994 小时前
Lucas Chess R国际象棋、中国象棋、日本将棋、五子棋训练学习工具游戏软件
学习
自传.4 小时前
尚硅谷 Vibe Coding|第一章 AI 编程基础理论 学习笔记
笔记·学习·尚硅谷·vibe coding
jieyucx4 小时前
SQL 查询终极高阶通鉴:从零基础拆解到工业级多表联查、窗口函数与索引优化
数据库·sql