Redis服务启动流程:
Redis服务启动流程中会初始化redisServer结构的变量server,并开启事件循环。
一、加载配置
加载配置分为两步:加载默认配置(initServerConfig)和加载配置文件(loadServerConfig)。initServerConfig函数中会按照server.h文件中预定义宏初始化server的属性:
initServerConfig函数还会初始化命令列表(populateCommandTable),将redisCommandTable中硬编码的配置保存到字典结构中(server.commands/server.orig_commands),并将一些常用命令的引用保存在server中。
默认配置加载完成后,Redis会判断启动参数中是否包含配置文件路径,如果有会调用loadServerConfig函数,按照配置文件中的配置覆盖默认配置。例如以如下命令启动Redis:
./redis-server /etc/myredis.conf --loglevel verbose
main函数中会把配置文件路径/etc/myredis.conf保存到server.configfile,loadServerConfig函数会将文件内容读取到sds字符串中,并将options(上面的--loglevel verbose)拼到sds字符串尾部。loadServerConfigFromString函数会按行解析sds中的配置,loadServerConfigFromString执行结束,加载配置这一步就算是完成了。
二、初始化
Redis的初始化阶段需要根据配置初始化一些运行时依赖的数据结构,可以看到创建了链表结构的客户端列表、从服务器客户端列表,创建了常用的共享对象等:
注册事件处理器:
server.el = aeCreateEventLoop(server.maxclients+CONFIG_FDSET_INCR);
aeCreateTimeEvent(server.el, 1, serverCron, NULL, NULL)
aeCreateFileEvent(server.el, server.ipfd[j], AE_READABLE, acceptTcpHandler,NULL)
在Redis中有文件事件和时间事件两种事件。文件事件是对网络IO操作(客户端连接、客户端执行命令等)的抽象。时间事件是指Redis中需要定时执行的任务,主要就是serverCron函数。
三、事件循环
Redis初始化最后一步是开启事件循环。在aeMain函数中会调用aeProcessEvents函数处理文件事件和时间事件。
首先会计算最近要发生的时间事件得到shortest,会根据这个时间阻塞等待文件事件:
numevents = aeApiPoll(eventLoop, tvp);
aeApiPoll返回后会循环到达的文件事件,根据文件事件类型,调用不同的函数处理事件:
每次事件循环都会检查eventLoop的stop属性,如果未被设置为true,继续执行下次事件循环。