阅读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抽象)

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全面学习

打赏作者
提交看法

抢沙发

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