主流程
server.c
全局变量server,只有一个,记录本服务的信息。 1.spt_init初始化全局环境变量,关联变量environ 2.设置时区 3.初始化oom_handler 4.其他初始化:随机数种子,crc64,acl,服务配置,tls,哨兵模式,帮助,加载配置文件,moduleInitModulesSystem模块系统初始化 5.关键函数initServer,初始化核心。 6.创建pid文件 7.设置cpu亲和性 8.执行事件循环核心 9.异常情况退出释放结束。
initServer
1.初始化处理信号的handlers 2.设置线程可以被kill 3.全局变量server初始化默认属性 4.创初始化共享对象shared 5.adjustOpenFilesLimit,根据配置判断文件描述符的数量限制 6.aeCreateEventLoop创建epoll循环对象 7.监听端口,设置非阻塞 8.aeCreateTimeEvent定时器初始化 9.设置accpet回调 10.aeCreateFileEvent使用管道初始化唤醒event loop的线程通信 11.设置sleep前后的回调函数 12.初始化集群clusterInit,副本集replicationScriptCacheInit,lua脚本scriptingInit,慢查询 slowlogInit,延迟监控latencyMonitorInit,acl默认密码ACLUpdateDefaultUserPassword。
redisSetCpuAffinity设置cpu亲和性
linux调用setcpuaffinity->sched_setaffinity,glibc的接口,最终调用系统调用INTERNAL_SYSCALL。
aeMain
aeApiPoll执行事件循环,linux一般使用epoll,epoll_wait阻塞。定时器事件processTimeEvents在最后处理。
reactor模型
ae_epoll
linux使用ae_epoll封装epoll。 ae.h声明了通用的事件函数,基本都是epoll的封装。 anet.h声明了tcp连接的操作函数。
connection
connection.h封装了连接的通用接口,最终会调用anet的tcp函数。 ConnectionType以函数指针的形式封装了接口,可以切换绑定的函数。
networking
networking.c主要是和客户端相关的连接操作。
rio
rio是文件相关操作的抽象封装。
syncio
同步读写操作接口。
集群
cluster
集群相关操作
replication
副本集相关操作
基础工具
crc64
crc64_init初始化,crc64计算校验值
pgsort,sort
排序算法,_pqsort高速排序算法。
sha1,sha256
哈希算法
压缩算法
lz算法
调试优化
debug
debug.c:重点关注logStackTrace和dumpCodeAroundEIP logStackTrace:可通过信号,触发logStackTrace,核心原理是调用glibc的backtrace获取当前栈信息,backtrace_symbols_fd解析栈信息(查找符号表)到文件。 glibc通过elf库的_dl_addr获取详细信息解析。
dumpCodeAroundEIP:直接根据eip指针获得下一条指令的地址,然后通过dladdr能够得到dump信息。
memtest
内存测试
tracking
核心存储结构:使用基数树存储的TrackingTable和PrefixTable 客户端指令解析后,调用call的地方执行trackingRememberKeys,记录到TrackingTable 每个epoll循环的beforeSleep都会执行trackingBroadcastInvalidationMessages,发送tracking跟踪信息到客户端。
核心数据结构
redisServer
服务的全局信息,struct redisServer server; 包括pid,主线程id,配置文件路径,执行路径,参数,和其他客户端,连接,线程,备份,慢查询日志,oom_score,集群,scripts等等的配置和信息。
redisOp
定义了redis的操作,是解析客户端消息后的比较原始的结构数据
redisCommand
redisCommandTable数组:表驱动执行函数和命令信息。
redisDb
redis的db是字典查询的基本单位,需要指定db然后根据key查询字典找到对应的数据。
redisObject/robj
通用的redis数据结构封装,包含引用计数,获取和释放需要使用指定的函数。 incrRefCount/decrRefCount,引用计数为零,执行free
字典
所有redis数据类型的的存储都靠字典
rax基数树
* This is the vanilla representation:
*
* (f) ""
* \
* (o) "f"
* \
* (o) "fo"
* \
* [t b] "foo"
* / \
* "foot" (e) (a) "foob"
* / \
* "foote" (r) (r) "fooba"
* / \
* "footer" [] [] "foobar"
*
基数树层级固定了之后,最大时间复杂度就确定了,查询粒度小,速度快。
数据结构编码
编码属于redisObject的一个字段,占4位。 编码类型:
持久化的时候需要用到。类型比较判断也需要用到。
其他功能
notify
rdb,aof,sentinel
redismodule
scripting
slowlog
布隆过滤器模块插件
|