redis源码阅读1-----redis的启动过程
redis版本:6.2.6
为了调试方便,配置文件绝大部分保持一致,只修改如下:
daemonize no。
关闭后台运行。这会影响debug,因为在server.c/6312行会进入daemonize(),然后执行setsid(),这样会导致debug退出。
然后将断点打在server.c/6157行。开始debug。
另外server相关的结构体都在server.h/1146行
最初始的几个函数主要用于设置时区,设置字符,设置地域,设置随机种子等,主要调用如下函数:
#ifdef INIT_SETPROCTITLE_REPLACEMENT
spt_init(argc, argv);
#endif
setlocale(LC_COLLATE,"");
tzset(); /* Populates 'timezone' global. */
zmalloc_set_oom_handler(redisOutOfMemoryHandler);
srand(time(NULL)^getpid());
srandom(time(NULL)^getpid());
gettimeofday(&tv,NULL);
init_genrand64(((long long) tv.tv_sec * 1000000 + tv.tv_usec) ^ getpid());
crc64_init();
umask(server.umask = umask(0777));
uint8_t hashseed[16];
getRandomBytes(hashseed,sizeof(hashseed));
dictSetHashFunctionSeed(hashseed);
然后如果你开启了哨兵模式,那么会通过如下函数进行检查:
server.sentinel_mode = checkForSentinelMode(argc,argv);
哨兵模式如果开启,那么会单独于redis单实例进行初始化和检查。因为哨兵模式比起单实例的配置会有所不同。
这其中最主要的函数为initSentinelConfig和initSentinel。
然后开始最重要的参数检查
initServerConfig();
这部分主要调用 initConfigValues();函数。
随后会对tls和module进行初始化。
ACLInit(); /* The ACL subsystem must be initialized ASAP because the
basic networking code and client creation depends on it. */
moduleInitModulesSystem();
tlsInit();
然后会重新检查一遍哨兵模式:
if (server.sentinel_mode) {
initSentinelConfig();
initSentinel();
}
然后开始检查aof和rdb:
if (strstr(argv[0],"redis-check-rdb") != NULL)
redis_check_rdb_main(argc,argv,NULL);
else if (strstr(argv[0],"redis-check-aof") != NULL)
redis_check_aof_main(argc,argv);
然后如果argc>=2,那么会重新检查一下命令行参数。没有太多意义,就不贴函数了。
不过在这个if最后,会加载参数和再一次检查是否开启哨兵模式,如下:
loadServerConfig(server.configfile, config_from_stdin, options);
if (server.sentinel_mode) loadSentinelConfigFromQueue();
当然如果argc<2,那么随后来的还是检查哨兵模式:
if (server.sentinel_mode) sentinelCheckConfigFile();
然后检查redis的supervised和backgroud。生产上daemonize肯定设置的yes,不过正如前文所说,为了调试方便,此处我们设置为no。
server.supervised = redisIsSupervised(server.supervised_mode);
int background = server.daemonize && !server.supervised;
if (background) daemonize();
最后就开始初始化服务,设置PID文件,检查tcp连接。
readOOMScoreAdj();
initServer();
if (background || server.pidfile) createPidFile();
if (server.set_proc_title) redisSetProcTitle(NULL);
redisAsciiArt();
checkTcpBacklogSettings();
然后如果你开启了aof或者rdb,那么还会加载数据
loadDataFromDisk();
最后redis检查下部分参数,没有问题user就能进行连接。
随后进入ae事件监听,redis启动成功。

浙公网安备 33010602011771号