这一节,我们研究的目光聚焦在redis服务器的启动过程。具体研究启动过程做了哪些工作。

启动redis命令:src/redis-server redis.conf
30408:C 13 Jan 2021 17:29:52.662 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
30408:C 13 Jan 2021 17:29:52.662 # Redis version=5.0.4, bits=64, commit=00000000, modified=0, pid=30408, just started
30408:C 13 Jan 2021 17:29:52.662 # Configuration loaded 第二步 加载配置_._                                                  _.-``__ ''-._                                             _.-``    `.  `_.  ''-._           Redis 5.0.4 (00000000/0) 64 bit.-`` .-```.  ```/    _.,_ ''-._                                   (    '      ,       .-`  | `,    )     Running in standalone mode|`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379   redis服务器的端口号|    `-._   `._    /     _.-'    |     PID: 30408    redis的进程号`-._    `-._  `-./  _.-'    _.-'                                   |`-._`-._    `-.__.-'    _.-'_.-'|                                  |    `-._`-._        _.-'_.-'    |           http://redis.io        `-._    `-._`-.__.-'_.-'    _.-'                                   |`-._`-._    `-.__.-'    _.-'_.-'|                                  |    `-._`-._        _.-'_.-'    |                                  `-._    `-._`-.__.-'_.-'    _.-'                                   `-._    `-.__.-'    _.-'                                       `-._        _.-'                                           `-.__.-'                                               30408:M 13 Jan 2021 17:29:52.664 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
30408:M 13 Jan 2021 17:29:52.664 # Server initialized  第三步 执行initServer函数,初始化服务器的数据结构
30408:M 13 Jan 2021 17:29:52.664 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
30408:M 13 Jan 2021 17:29:52.664 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
30408:M 13 Jan 2021 17:29:52.664 * DB loaded from disk: 0.000 seconds  第四步操作结束后,会打印
30408:M 13 Jan 2021 17:29:52.664 * Ready to accept connections 第五步操作结束后,会打印      

第一步:创建一个redisServer的实例变量,并且为实例中的各种变量设置默认值。(本质就是调用initServerConfig函数)

initServerConfig函数的工作有:

1、设置服务器的运行id

2、设置服务器的默认运行频率

3、设置服务器的默认配置文件路径

4、设置服务器的运行架构

5、设置服务器的默认端口号

6、设置RDB持久化条件和AOF持久化条件

7、初始化服务器的LRU时钟

8、创建命令表(但没创建server.clients链表等其他数据结构)

第二步:载入配置选项,就是加入redis.cong文件或者命令参数,用来替换第一步设置的默认值。

30408:C 13 Jan 2021 17:29:52.662 # Configuration loaded

第三步:初始化服务器的数据结构:比如server.clients链表,server.db数组,server.slowlog。现在才初始化数据结构的原因是,服务器必须先载入配置选项后,才进行初始化数据结构,否则的话,就要重新修改数据结构了。(本质就是调用了InitServer函数),除了创建数据结构,还要设置进程信号处理器(就是用来检测服务器的退出信号,当执行完initServer函数后,就会打印redis的logo,版本信息等)

               _._                                                  _.-``__ ''-._                                             _.-``    `.  `_.  ''-._           Redis 5.0.4 (00000000/0) 64 bit.-`` .-```.  ```/    _.,_ ''-._                                   (    '      ,       .-`  | `,    )     Running in standalone mode|`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379   redis服务器的端口号|    `-._   `._    /     _.-'    |     PID: 30408    redis的进程号`-._    `-._  `-./  _.-'    _.-'                                   |`-._`-._    `-.__.-'    _.-'_.-'|                                  |    `-._`-._        _.-'_.-'    |           http://redis.io        `-._    `-._`-.__.-'_.-'    _.-'                                   |`-._`-._    `-.__.-'    _.-'_.-'|                                  |    `-._`-._        _.-'_.-'    |                                  `-._    `-._`-.__.-'_.-'    _.-'                                   `-._    `-.__.-'    _.-'                                       `-._        _.-'                                           `-.__.-'                                               30408:M 13 Jan 2021 17:29:52.664 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
30408:M 13 Jan 2021 17:29:52.664 # Server initialized

第四步:还原数据库状态。就是加载RDB文件或AOF文件,进行还原数据库的状态。加载的机制是:首先先加载aof文件,有aof文件,加载完后就结束加载流程。没AOF文件,那就去加载RDB文件。加载完RDB文件,就结束加载流程。还原数据库状态后,黑窗口会打印以下这段信息:

30408:M 13 Jan 2021 17:29:52.664 * DB loaded from disk: 0.000 seconds

第五步:执行事件循环,就是进入执行流程了,可以接受客户端的连接和请求了。黑窗口会打印一下这段信息:

30408:M 13 Jan 2021 17:29:52.664 * Ready to accept connections

接下来我们对照redis的server.c源码里面的main函数进行分析:

具体源码文件链接:https://github.com/redis/redis/blob/5.0/src/server.c

int main(int argc, char **argv) {第一步:省略很多代码...initServerConfig();第二步:省略很多代码...loadServerConfig(server.configfile, config_from_stdin, options);第三步:省略很多代码...initServer();第四步:省略很多代码...loadDataFromDisk();serverLog(LL_NOTICE,"DB loaded from disk: %.3f seconds",(float)(ustime()-start)/1000000);第五步:省略很多代码...serverLog(LL_NOTICE,"Ready to accept connections");
}

接下来看具体每一个函数的代码:

initServerConfig();

void initServerConfig(void) {int j;pthread_mutex_init(&server.next_client_id_mutex,NULL);pthread_mutex_init(&server.lruclock_mutex,NULL);pthread_mutex_init(&server.unixtime_mutex,NULL);updateCachedTime(1);getRandomHexChars(server.runid,CONFIG_RUN_ID_SIZE);server.runid[CONFIG_RUN_ID_SIZE] = '0';  //运行idchangeReplicationId();clearReplicationId2();server.timezone = getTimeZone(); /* Initialized by tzset(). */  时间server.configfile = NULL;server.executable = NULL;server.hz = server.config_hz = CONFIG_DEFAULT_HZ; 默认频率,这个用来控制serverCron函数,每秒执行的次数server.dynamic_hz = CONFIG_DEFAULT_DYNAMIC_HZ;server.arch_bits = (sizeof(long) == 8) ? 64 : 32;server.port = CONFIG_DEFAULT_SERVER_PORT; 端口server.tcp_backlog = CONFIG_DEFAULT_TCP_BACKLOG;server.bindaddr_count = 0;...省略很多代码,真的超级无敌多,但都是初始化默认值}

initServer()

void initServer(void) {int j;signal(SIGHUP, SIG_IGN);signal(SIGPIPE, SIG_IGN);setupSignalHandlers();if (server.syslog_enabled) {openlog(server.syslog_ident, LOG_PID | LOG_NDELAY | LOG_NOWAIT,server.syslog_facility);}server.hz = server.config_hz;   频率server.pid = getpid();   进程idserver.current_client = NULL;server.fixed_time_expire = 0;server.clients = listCreate();server.clients_index = raxNew();server.clients_to_close = listCreate();server.slaves = listCreate();server.monitors = listCreate();server.clients_pending_write = listCreate();server.slaveseldb = -1; /* Force to emit the first SELECT command. */server.unblocked_clients = listCreate();server.ready_keys = listCreate();server.clients_waiting_acks = listCreate();server.get_ack_from_slaves = 0;server.clients_paused = 0;server.system_memory_size = zmalloc_get_memory_size();...省略很多代码}

loadDataFromDisk

void loadDataFromDisk(void) {long long start = ustime();if (server.aof_state == AOF_ON) {  首先,判断AOF是否开启,如果开启,就尝试加载AOF文件if (loadAppendOnlyFile(server.aof_filename) == C_OK)serverLog(LL_NOTICE,"DB loaded from append only file: %.3f seconds",(float)(ustime()-start)/1000000);} else {rdbSaveInfo rsi = RDB_SAVE_INFO_INIT;  加载RDB文件if (rdbLoad(server.rdb_filename,&rsi) == C_OK) {serverLog(LL_NOTICE,"DB loaded from disk: %.3f seconds",(float)(ustime()-start)/1000000);   这个就是打印出来的日志/* Restore the replication ID / offset from the RDB file. */if ((server.masterhost ||(server.cluster_enabled &&nodeIsSlave(server.cluster->myself))) &&rsi.repl_id_is_set &&rsi.repl_offset != -1 &&/* Note that older implementations may save a repl_stream_db* of -1 inside the RDB file in a wrong way, see more* information in function rdbPopulateSaveInfo. */rsi.repl_stream_db != -1){memcpy(server.replid,rsi.repl_id,sizeof(server.replid));server.master_repl_offset = rsi.repl_offset;/* If we are a slave, create a cached master from this* information, in order to allow partial resynchronizations* with masters. */replicationCacheMasterUsingMyself();selectDb(server.cached_master,rsi.repl_stream_db);}} else if (errno != ENOENT) {serverLog(LL_WARNING,"Fatal error loading the DB: %s. Exiting.",strerror(errno));exit(1);}}
}

总结,上述对照着redis的源代码,来深入了解了Redis服务器的启动过程,具体的细节,都可以在代码中找到。

1、赋值初始值;

2、加载配置文件;

3、创建数据结构;

4、还原数据库数据;

5、等待事件发生。

下一篇文章,介绍reids的执行过程及其细节。

公众号:大头菜技术

redis-server启动但进程里没有_Redis——服务器的启动过程相关推荐

  1. windows安装linux无法启动服务,Windows系统下Apache服务器无法启动的问题解决

    关于apache无法启动主要是80端口的问题,下面我们来看一下关于端口被占的处理办法 解决方案:1:在dos下运行netstat -ano 2:在xampp control panel中点setup打 ...

  2. 一个服务器启动2套mysql_一台服务器上启动两个mysql实例

    一台服务器上启动两个mysql实例 操作环境:centos6.8 有时由于服务器硬件资源紧张,而又需要新增mysql服务.这时我们可以采取在一台服务器上部署两个mysql实例,来解决. 1.创建新的m ...

  3. 启动金蝶显示服务器未启动失败,金蝶云平台加密服务器未启动

    金蝶云平台加密服务器未启动 内容精选 换一换 外部镜像文件在从原平台导出前,没有按照"Windows操作系统的镜像文件限制"的要求完成初始化操作,推荐您使用弹性云服务器完成相关配置 ...

  4. springboot 启动 退出_springboot怎么停止掉服务器 我启动了springboot,但是我修改了程序,我怎么重启啊...

    展开全部 可以以通过HTTP发送shutdown信号的方式停止服务器. 具体步骤如下: 1. 在pom.xml中引入actuator依赖e68a8462616964757a686964616f3133 ...

  5. 架设KMS服务器流程启动加载方法

    架设KMS服务器流程 启动加载方法 架设KMS服务器流程--启动加载方法 以下操作 root 一.准备Centos服务器CentOS-8.4.2105 1.下载http://mirrors.163.c ...

  6. 查看redis进程_redis安装(启动三种方式)

    一.安装redis 第 1 步:下载redis安装包 [root@hadoop105 redis]# wget http://download.redis.io/releases/redis-4.0. ...

  7. Redis 错误1067:进程意外终止,Redis不能启动,Redis启动不了

    Redis 错误1067:进程意外终止,Redis不能启动,Redis启动不了 >>>>>>>>>>>>>>> ...

  8. redis在容器里连接不上_Redis服务器被劫持风波,服务器相关知识共享学习

    俗话说安全猛于虎,之前多多少少有所小体会:这次的上线Redis服务器被劫严重影响了开发测试和线上环境,在解决的过程也对安全方面了解了很多:总结了这次过程的排查流程以及采取的相应测试,在此与大家共享. ...

  9. redis server服务端启动流程分析(一)

    1.server.c main()服务启动的入口 下面是redis启动的入口程序server.c,简单列了主程序中比较关键的一些点. ## server.c int main(int argc, ch ...

最新文章

  1. Oracle 存储过程定义和优点及与函数区别
  2. alpine linux 简介(面向安全应用的发行版)apk
  3. 【Kotlin】Kotlin 构造函数 ( 主构造函数 | 主构造函数声明属性 | init 初始化代码块 | 次构造函数 | 构造函数委托 | 调用构造函数创建实例对象 )
  4. 膜拜大丹(结论+二元环)
  5. CCIE-LAB-第十六篇-NAT+OSPF下发默认路由+校验配置(模块一结束篇章)
  6. java partialfunction,scala中方法和函数的区别
  7. HTTP Error 500.19 – Internal Server Error – 0x80070021 (IIS 8.5)
  8. SVN源码服务器搭建-详细教程(我的收藏)
  9. 怎样完美卸载IE8浏览器
  10. sox免安装直接使用
  11. Unity Webgl内嵌网页页面
  12. 有关振动试验夹具的问题
  13. 9 ,zk 架构模型
  14. linux系统查询服务器型号,Linux系统查看服务器型号
  15. 【J】BeanCreationException: Error creating bean with name 'shiroFilter' defined in class path resource
  16. 2021华为软件精英挑战赛(杭厦第20名)
  17. [ 物联网篇 ] 11 - NXP i.MX8M Mini 集成Mender OTA解决方案
  18. C语言买金鱼问题答案,发现一条品相不错的小金鱼,可惜炸鳞了,购买金鱼如何判断疾病?...
  19. matlab逆变换法产生随机数_信号处理——生成给定分布随机数
  20. Centos8重启网卡的问题

热门文章

  1. Java第一个程序Helloworld
  2. LeetCode-链表-206. 反转链表
  3. Key Components and Internals of Spring Boot Framework--转
  4. Keepalived 使用指南
  5. 特征选择(feature_selection)
  6. 【采用】【风控体系】携程基于大数据分析的实时风控体系
  7. 评分卡模型剖析之一(woe、IV、ROC、信息熵)
  8. 腾讯内部人士爆与老干妈合作多个环节有漏洞 却没人察觉
  9. 水氢发动机在南阳下线,市委书记点赞!
  10. 单片机large模式_对单片机存储分配新的认识