Redis 启动流程全解析(server.c 到 main 函数)
启动一个 Redis 实例看起来很简单,redis-server 一敲就完了。但你有没有想过,从按下回车到 Redis 开始接受连接,中间发生了什么? 这篇文章从 server.c 的 main 函数开始,一步步拆解 Redis 的启动流程。 先看 main 函数的全貌 main 函数在 server.c 的第 4000 行附近,核心流程可以概括为: 初始化基础库 → 加载配置 → 初始化服...

Source: DEV Community
启动一个 Redis 实例看起来很简单,redis-server 一敲就完了。但你有没有想过,从按下回车到 Redis 开始接受连接,中间发生了什么? 这篇文章从 server.c 的 main 函数开始,一步步拆解 Redis 的启动流程。 先看 main 函数的全貌 main 函数在 server.c 的第 4000 行附近,核心流程可以概括为: 初始化基础库 → 加载配置 → 初始化服务器 → 加载数据 → 进入事件循环 代码骨架是这样的: int main(int argc, char **argv) { // 1. 基础初始化 initServerConfig(); moduleInitModulesSystem(); // Sentinel 模式初始化(如果是) if (server.sentinel_mode) { initSentinelConfig(); initSentinel(); } // 2. 加载配置文件和命令行参数 resetServerSaveParams(); loadServerConfig(configfile, options); // 3. 以守护进程方式运行(如果配置了) if (background) daemonize(); // 4. 初始化服务器 initServer(); // 5. 从磁盘加载数据 loadDataFromDisk(); // 6. 进入事件循环 aeMain(server.el); return 0; } 下面逐个展开。 第一步:基础初始化 main 函数开头做了一些必须先做的初始化: setlocale(LC_COLLATE,""); tzset(); // 时区初始化 zmalloc_set_oom_handler(redisOutOfMemoryHandler); // 内存不足处理 srand(time(NULL)^getpid()); // 随机种子 gettimeofday(&tv,NULL); // 生成哈希种子,用于字典的哈希函数 char hashseed[16]; getRandomHexChars(hashseed,sizeof(hashseed)); dictSetHashFunctionSeed((uint8_t*)hashseed); 这些操作和 Redis