当你启动 Redis 的时候,Redis 做了什么

本文转载自:http://www.hoohack.me/2018/05/26/read-redis-src-how-server-start 点击下面阅读原文即可进入

假设 Redis 安装在了 /usr/local/ 目录下,那么启动 Redis 是通过执行 /usr/local/bin/redis-server -c xxx.conf 的方式执行。 redis-server 是一个通过编译 server.c 文件生成的程序,因此想了解redis是怎么启动的,应该从 server.c/main 函数入手。

具体代码可见:server.c https://github.com/hoohack/read-redis-src/blob/master/redis-4.0/src/server.c

阅读 main 函数,可以知道,整个启动大致分为五个步骤:初始化 server 结构体、从配置文件夹在加载参数、初始化服务器、载入持久化文件、开始监听事件。

redis 用 redisServer 结构体来保存服务器的属性和信息,在 server.c 文件中,定义了一个全局服务器变量:

1struct redisServer server;

另外,还定义了一个 redis 命令表,表里包含了命令以及命令对应的函数:

1struct redisCommand redisCommandTable;

在main函数里,redis 先调用 initServerConfig 函数初始化 server 结构体。

初始化server结构体

main 函数调用 initServerConfig 函数为 server 的属性设置一些默认值,比如:

  • 服务器的运行ID

  • redis使用的默认端口号,是在server.h定义的CONFIG_DEFAULT_SERVER_PORT = 6379

  • LRU时钟

  • 主从备份相关参数

  • 命令表

  • 慢查询参数

接着会保存当前执行的路径和参数,为之后的服务器重启使用相同的参数做准备:

1server.executable = getAbsolutePath(argv[0]);
2server.exec_argv = zmalloc(sizeof(char*)*(argc+1));
3server.exec_argv[argc] = NULL;
4for (j = 0; j < argc; j++) server.exec_argv[j] = zstrdup(argv[j]);

从配置文件加载参数

redis 的启动参数有很多,其中一个是指定配置文件。初始化 server 结构体后,大部分的属性都会设置到结构体了,但是有部分参数可以通过配置文件重现设置,比如 redis 的端口号。

初始化完 server 结构体后,函数会判断是否有指定配置文件,如果有,调用loadServerConfig 函数,从配置文件加载相关的配置,把配置文件对应的参数设置到server 结构体。

读取配置文件加载参数的流程如下:

  • 分割参数项

  • 跳过空行和注释行

  • 逐项检查,如果参数合法,设置配置值到server属性

至此,redisServer 大部分属性已经设置好,server 还有很多数据结构没有初始化,initServer 函数就继续接下来的初始化工作。

初始化服务器数据结构

main函数会调用initServer函数初始化服务器状态,比如:

  • 进程ID

  • 客户端链表

  • 从库链表

  • 为常用值创建共享对象

  • 初始化事件循环器

  • 打开TCP开始监听套接字

  • 创建服务器的数据库,并初始化内部状态

  • 为serverCron定时器创建时间事件定时器

  • 如果开启了AOF,打开AOF文件,之后恢复数据时需要用到

  • 初始化慢查询日志模块

  • 初始化后台IO模块

载入持久化文件,还原数据库

初始化完服务器的状态后,服务器已经处于一个可启动状态,因为redis有持久化特性,服务器还需要加载相应的文件来还原之前数据库的数据。 判断Redis当前开启了哪种模式,如果是AOF,则通过AOF还原数据库的数据,否则,载入RDB文件,通过RDB文件还原数据库的数据。

开始监听事件

main函数会设置beforeSleep和afterSleep回调函数,然后调用aeMain函数启动事件循环器,开始监听事件。aeMain函数是一个死循环,不断的监听新请求的到来。

 1/*
2 * server启动后,main函数的最终步骤,不断地调用beforesleep和aeProcessEvents
3 */

4void aeMain(aeEventLoop *eventLoop) {
5    eventLoop->stop = 0;
6    while (!eventLoop->stop) {
7        if (eventLoop->beforesleep != NULL)
8            eventLoop->beforesleep(eventLoop);
9        aeProcessEvents(eventLoop, AE_ALL_EVENTS|AE_CALL_AFTER_SLEEP);
10    }
11}

综上所述,服务器整个启动简化流程图如下:

猜你喜欢

欢迎关注本公众号:iteblog_hadoop:

0、回复 电子书 获取 本站所有可下载的电子书

1、Apache Spark 统一内存管理模型详解

2、HDFS 副本存放磁盘选择策略详解

3、盘点2017年晋升为Apache TLP的大数据相关项目

4、干货 | 深入理解 Spark Structured Streaming

5、Apache Spark 黑名单(Blacklist)机制介绍

6、Kafka分区分配策略(Partition Assignment Strategy)

7、Spark SQL 你需要知道的十件事

8、干货 | Apache Spark 2.0 作业优化技巧

9、[干货]大规模数据处理的演变(2003-2017)

10、干货 | 如何使用功能强大的 Apache Flink SQL

11、更多大数据文章欢迎访问https://www.iteblog.com及本公众号(iteblog_hadoop) 12、Flink中文文档:http://flink.iteblog.com 13、Carbondata 中文文档 http://carbondata.iteblog.com

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果使用 Redis 配置文件启动 Redis 服务器失败,可能有以下一些原因: 1. 配置文件路径错误:确认指定的配置文件路径是否正确,并且 Redis 服务器有足够的权限读取该文件。 2. 配置文件格式错误:检查配置文件是否符合 Redis 的要求。可以使用 `redis-check-aof` 和 `redis-check-rdb` 命令检查 AOF 和 RDB 文件的格式是否正确。或者,可以使用 `redis-server /path/to/redis.conf --test` 命令测试配置文件是否正确,并输出错误信息。 3. 网络端口被占用:如果 Redis 服务器使用的网络端口被其他进程占用,Redis 服务器将无法启动。可以使用 `lsof -i :6379` 命令查看是否有其他进程正在使用 Redis 默认端口 6379。 4. 内存不足:如果 Redis 服务器使用的内存超出了系统可用内存范围,则 Redis 服务器将无法启动。可以使用 `dmesg` 命令查看系统日志以获取更多信息。 5. Redis 配置文件错误:如果 Redis 配置文件中存在语法错误或配置问题,Redis 服务器将无法启动。可以检查配置文件中的选项是否正确,并根据需要进行更改。 6. Redis 二进制文件错误:如果 Redis 二进制文件损坏或不完整,Redis 服务器将无法启动。可以使用 `redis-check-rdb` 命令检查 RDB 文件是否正确,并使用 `redis-check-aof` 命令检查 AOF 文件是否正确。如果二进制文件损坏,可以尝试重新安装 Redis 服务器。 如果以上方法都无法解决问题,请检查 Redis 日志文件以获取更多信息,并在 Redis 官方社区求助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值