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启动成功。