redis启动分析

http://ordinary.iteye.com/blog/1097457

从本篇文章开始(命名为Redis分析系列),将会通过分析Redis的源代码(以Redis 2.2.0 RC1为准),来对它的内部实现做一些探讨。本文主要介绍Redis启动加载过程,总体上可以分为如下几步:

1. 初始化全局服务器配置

2. 加载配置文件(如果指定了配置文件,否则使用默认配置)

3. 初始化服务器

4. 加载数据库

5. 网络监听

整个启动加载过程如下图所示:

下面对于上图中的各个步骤一些介绍,有些部分(如数据库加载、网络监听)会在后面单独用一篇文章详细说明。

初始化全局服务器配置

初始化全局服务器配置通过initServerConfig()函数完成,主要是初始化server变量,它是一个redisServer的结构类型:

struct redisServer server;

初始化的内容包括下面几个方面:

1. 网络监听相关,如绑定地址,TCP端口等 
2. 虚拟内存相关,如swap文件、page大小等 
3. 保存机制,多长时间内有多少次更新才进行保存 
4. 复制相关,如是否是slave,master地址、端口 
5. Hash相关设置 
6. 初始化命令表

如其中的保存机制中,服务器初始化策略为:

// 1小时内1次更新
appendServerSaveParams(60*60,1);

// 5分钟内100次更新
appendServerSaveParams(300,100);

// 1分钟内10000次更新
appendServerSaveParams(60,10000);

如果在启动服务器时,指定了配置文件,则会在下面的“加载配置文件”步骤中,根据配置文件内容,更改其中的某些服务器配置。

加载配置文件

如果指定了配置文件,Redis使用loadServerConfig()函数加载配置文件,整个过程没什么可以说的,无非是使用标准I/O库打开配置文件,循环读取每一行然后覆盖上一步进行的默认配置。

这里有一点需要注意的是,下载Redis后代码包中有一个默认配置文件,如果启动Redis服务器时,不指定配置文件,Redis不会使用这个默认文件的配置,而是使用上一步“初始化全局服务器配置”中的配置。在默认配置文件中提供的配置项与上一步默认初始化的配置有些事不一样的,所以如果没有指定配置文件,千万不能认为Redis的行为会按照默认配置文件进行,最典型的一个例子,在默认配置文件中的数据保存策略是:

# 15分钟内1次更新
save 900 1

# 5分钟内100次更新
save 300 10

# 1分钟内10000次更新
save 60 10000

而默认初始化的全局配置中数据保存策略:

// 1小时内1次更新
appendServerSaveParams(60*60,1);

// 5分钟内100次更新
appendServerSaveParams(300,100);

// 1分钟内10000次更新
appendServerSaveParams(60,10000);

初始化服务器

初始化服务器的工作在initServer()函数中,主要是完成前面未完成的工作,继续对server变量初始化,如设置信号处理、创建clients、slaves列表,创建Pub/Sub通道列表,同时还会创建共享对象:

shared.crlf = createObject(REDIS_STRING,sdsnew("\r\n"));
shared.ok = createObject(REDIS_STRING,sdsnew("+OK\r\n"));
shared.err = createObject(REDIS_STRING,sdsnew("-ERR\r\n"));
shared.emptybulk = createObject(REDIS_STRING,sdsnew("$0\r\n\r\n"));

最后,如果启用了虚拟内存机制,还需要初始化虚拟内存相关,如Thread I/O等。

加载数据库

在完成了上面的所有的初始化工作之后,Redis开始加载数据到内存中,如果启用了appendonly了(不知道这个参数做什么的,请先看配置文件篇),则Redis从appendfile加载数据,否则就从dbfile加载数据。

1. 从appendfile中加载数据:loadAppendOnlyFile()函数

在此之前,我们先来看一下appendfile里面保存了什么,如我执行了下面两条命令(记得在配置文件中开启appendonly):

redis> SET mykey001 myvalue001
OK
redis> GET mykey001
"myvalue001"

使用cat命令查看appendonly.aof文件内容:

$ cat appendonly.aof
*2
$6
SELECT
$1
0
*3
$3
SET
$8
mykey001
$10
myvalue001

嗯,相信大家都能看明白(看不明白的请先看这篇文章),在appendonly.aof文件中保存的正是从客户端发过来的请求命令,还可以看到对于GET命令,并没有保存。既然appendonly.aof中保存了所有写入数据的请求命令,那么在加载数据的时候只要重新执行一遍这些命令即可。

事实上Redis也正是这么做的,在开始加载之前暂时关闭appendonly,然后Redis创建一个假的Redis客户端:

server.appendonly = 0;

fakeClient = createFakeClient();
startLoading(fp);

然后读取appendonly.aof文件中的命令,在假的Redis客户端上下文中执行,同时服务器也不对该客户端做任何应答:

fakeClient->argc = argc;
fakeClient->argv = argv;
cmd->proc(fakeClient);

/* The fake client should not have a reply */
redisAssert(fakeClient->bufpos == 0 && listLength(fakeClient->reply) == 0);

如果加载过程中物理内存不够用,并且Redis开启了VM,则还需要处理swap操作,最后加载完成后重新设置appendonly标志。

2. 从dbfile中加载数据:rdbLoad()函数

如果Redis没有开启appendonly,就需要从数据库文件中加载数据到内存,基本步骤如下:

a. 处理SELECT命令,即选择数据库 
b. 读取key 
c. 读取value 
d. 检测key是否过期 
e. 添加新的对象到哈希表 
f. 设置过期时间(如果需要) 
g. 如果开启了VM,处理swap操作

网络监听

在完成了初始化配置和数据加载后,Redis启动监听。Redis的网络库没有使用libevent或者libev,而是作者自己实现的一个非常轻量级的库(主要实现在ae.c文件中),这部分内容在后面分析Redis的网络库的时候单独写篇文章。

通过本文,介绍了Redis的启动加载过程,希望对大家有所帮助。

时间: 2024-12-18 17:33:24

redis启动分析的相关文章

Elasticsearch+Logstash+Kinaba+Redis日志分析系统

一.简介 1.组成 ELK由Elasticsearch.Logstash和Kibana三部分组件组成: Elasticsearch是个开源分布式搜索引擎,它的特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful风格接口,多数据源,自动搜索负载等. Logstash是一个完全开源的工具,它可以对你的日志进行收集.分析,并将其存储供以后使用 kibana 是一个开源和免费的工具,它可以为 Logstash 和 ElasticSearch 提供的日志分析友好的 Web 界面,可

[转]Redis实现分析

Redis实现分析 浏览次数:1018次 KITERUNNER_T 2014年10月19日 字号: 大 中 小 分享到: QQ空间 新浪微博 腾讯微博 人人网 豆瓣网 开心网 更多 1 1 环境准备 从2.6.4版本为基础了解redis的设计与实现,首先搭建一个原始模型,以便根据这个模型分析其代码的设计与实现(当然,随着进一步对 redis细节的了解,肯定会对该模型进行调整,以便更适合分析其设计与实现细节).在对该版本有较深的了解后,跟随github代码库,追踪新功能添 加.bug/issue等

Redis入门到高可用(二)—— Redis启动及使用

1. 三种启动方式 ♦?  最简启动 ./redis-server 使用Redis默认配置进行启动; ♦?  动态参数启动 * redis-server --port 6380  更改端口为6380并启动 ♦?  配置文件启动 redis-server  configPath (将需要的配置写在配置文件中) 三种方式对比:    生产环境选择配置文件启动    单机多实例配置文件可以用端口区分开 2. Redis客户端连接 ./redis-cli  -h 127.0.0.1 -p 6379 Re

redis启动过程源码解析

redis整个程序的入口函数在server.c中的main函数,函数调用关系如下图1,调用顺序为从上到下,从左至右. 图1 redis启动函数调用图 main函数源码如下,1-55行根据配置文件和启动命令参数设置全局对象server ,57-59设置redis的服务器端为后台进程, initServer主要提前创建一些经常用到的对象用于节约内存,根据设置的ip地址和端口创建监听套接字用于客户端连接,并初始化时间事件,64行用于设置server->el ->beforesleep = befor

Tomcat启动分析(我们为什么要配置CATALINA_HOME环境变量)

原文:http://www.cnblogs.com/heshan664754022/archive/2013/03/27/2984357.html Tomcat启动分析(我们为什么要配置CATALINA_HOME环境变量) 用文本编辑工具打开用于启动Tomcat的批处理文件startup.bat,仔细阅读.在这个文件中,首先判断CATALINA_HOME环境变量是否为空,如果为空,就将当前目录设为CATALINA_HOME的值.接着判断当前目录下是否存在bin\catalina.bat,如果文件

redis启动管理脚本

亲测好用的redis启动管理脚本,如果使用需要根据自己安装的redis相关文件进行调整 我是源码安装的redis-3.0.5 安装路径/usr/local/redis 编辑创建脚本文件: vim /etc/init.d/redis #!/bin/sh # # chkconfig:   2345 85 15   # description: this script can manager the redis-server daemon #              Redis is a persi

redis启动

/usr/local/bin/redis-server /etc/redis.conf redis启动,布布扣,bubuko.com

Mysql的启动分析

一.Mysql启动配置文件的加载路径 # mysqldump --help| egrep -B2  "/etc/my.cnf" 或者 # mysqld --verbose --help |grep my.cnf Default options are read from the following files in the given order: /etc/my.cnf /etc/mysql/my.cnf /usr/local/mysql/etc/my.cnf ~/.my.cnf -

redis启动脚本

编写redis启动脚本 [[email protected] etc]# vi /etc/init.d/redis [[email protected] etc]# chmod 755 /etc/init.d/redis ########################### #chkconfig: 2345 10 90#description: Start and Stop redisPATH=/usr/local/bin:/sbin:/usr/bin:/bin     REDISPORT=6