阅读Redis源码

文章目录

1. 代码结构

redis源码结构是平铺的,全部都放在src文件夹下面,为方便学习阅读,可以分为几个功能部分:

  • 基础数据结构:atomicvar、sds、sdsalloc、t_set、t_zset、t_string、t_stream、t_list、t_hash、quicklist、listpack
  • 外部数据结构:adlist(双向链表)、bitops、dict、geo、geohash、hyperloglog、intset、zipmap、ziplist、stream、rax、pubsub、object、lolwut
  • 客户端框架:help(help信息,代码生成出来的)、tracking(客户端缓存)、redis-cli
  • 服务器框架:bio(后台io进程)、blocked(阻塞操作)、childinfo(客户端连接)、config(配置及GET/SET实现)、connection、db(核心内部API)、expire、tls、sort、server、network、multi、notify
  • 事件驱动框架:ae、ae_epoll、ae_kqueue、ae_evport、ae_select
  • 内存管理:dfrag(内存管理)、evict(lru内存分配)、lazyfree
  • 工具类:acl、anet(TCP网络库)、asciilogo、connhelpers、crc16、crc64、debug、debugmacro、、endianconv、fmacro、version、util、zmalloc、sha1、sha256、siphash、release(本地编译信息)、rand、localtime、lzf、lzf_d、lzf_c
  • 特性模块:aof(redo日志系统)、cluster(集群模式)、gopher、sparkline、slowlog、sentinal、scripting、replication、rdb、latency、module、 rio(rdb和aof的io抽象)

或者区分为:

1、网络:

  • ae(epoll,kqueue,select)事件库
  • anet TCP soket库
  • blocked 实现BLPOP & WAIT阻塞原语
  • latency 监控功能
  • networking 网络入口
  • notify

2、数据结构:

  • adlist 双向链表
  • dict hash表
  • geo 地理信息
  • geohash 地理hash
  • hash_helper 将c++代码转为c
  • hyperloglog
  • intset 数组
  • listpack 字符串打包
  • quicklist 双向ziplist
  • rax 基树实现
  • sds 可变长的string
  • stream 流
  • t_hash/ t_list / t_set/ t_stream/ t_string/ t_zset 原始底层实现ziplist zipmap

3、持久化

  • aof 日志系统
  • bio backgroud io线程系统实现
  • childinfo 进程处理,rdb或aof子进程工作分离
  • lazyfreerdb 快照实现
  • redis-check-aof
  • redis-check-rdb rio 流接口,供rdb使用
  • syncio 同步io库

4、集群:

  • cluster 集群管理入口
  • config 配置文件处理
  • db 简单的kv管理
  • debug 调试信息
  • expire 过期机制实现
  • help 帮助功能实现
  • module 模块功能
  • multi 多命令
  • object 内部对象
  • pubsub 命令
  • redis-cli 客户端实现
  • redismodule 模块宏
  • releasereplication 备份实现
  • scripting lua脚本
  • setinal 哨兵实现
  • server 服务端入口
  • slowlog 命令

5、基础:

  • asciilogo logo图形(怎么生成的?)
  • atomicvar 原子变量库
  • bitops 位操作库
  • crc16 、crc64 循环校验库
  • debugmacro 调试
  • 日志到文件
  • defrag 内存碎片整理库
  • endianconv 大小端转换库
  • evict LRU等算法
  • fmacro 基本宏参数
  • lzf 压缩解压库
  • pqsort 快排库
  • rand 随机库
  • redisassert 判断宏
  • sha1 库
  • siphash 库
  • sort 排序库
  • sparkline 绘图
  • util 助手方法库
  • zmalloc 在malloc分配内存基础上增加统计功能

2. 服务器框架

服务器启动步骤:server.c / main

  • 初始化服务器状态 server.c / initServerConfig(void)
  • 载入服务器配置 config.c / loadServerConfig(configfile,options)
  • 初始化服务器数据结构 server.c / initServer(void)
  • 还原数据库状态 (载入AOF和RDB) server.c / InitServerLast()
  • 执行事件循环 aeMain

命令请求步骤:

  • 客户端将命令请求发送给服务器(redisCommand,所有支持类型都在server.c中定义)
  • 服务器读取命令请求并解析出命令参数(从redisClient中queryBuf)
  • 命令执行器根据参数查找命令的实现函数,执行实现函数并得出命令回复
  • 服务器将命令回复返回给客户端

serverCron函数默认每100毫秒执行一次,主要包括更新服务器状态信息、处理服务接收的SIGTERM信号、管理客户端资源和数据库状态、检查执行持久化等。

3. AE事件驱动框架

3.1 polling处理

ae_epoll.c、 ae_kqueue.c、 ae_evport.c、 ae_select.c 这4个文件的功能是完全一样的,提供一致的API接口,给ae.c文件调用

3.2 核心结构体

aeEventLoop 用来创建事件循环

  • aeCreateEventLoop:初始化一个事件循环结构体(eventLoop)
  • aeSetBeforeSleepProc:注册回调函数,即每次主循环在休眠之前被调
  • aeStop:停止事件循环,即stop值设为1
  • aeMain启动事件循环,事件循环的入口
  • aeProcessEvents:事件处理逻辑
  • aeDeleteEventLoop删除事件循环eventLoop(释放内存空间)

其中关键是aeProcessEvents逻辑,设计仅需要支持两种事件:文件IO事件(统一了网络socket和文件读写)和定时事件。使用polling机制保证尽量在一次处理过程中,将时间事件和文件事件一次性处理。注意:这个逻辑因为是单线程的,所以简化了很多。

本文是全系列中第1 / 2篇:redis全面学习

打赏作者
提交看法

抢沙发

还没有评论,你可以来抢沙发