文章转载自:http://redisbook.readthedocs.io/en/latest/internal/redis.html
从启动 Redis 服务器,到服务器可以接受外来客户端的网络连接这段时间,Redis 需要执行一系列初始化操作。
整个初始化过程可以分为以下六个步骤:
redis.h/redisServer结构记录了和服务器相关的所有数据,这个结构主要包含以下信息:
上述过程只包含=Redis服务器单机信息,不包含sentinel,cluster等功能。
当 server 变量的初始化完成之后,程序进入服务器初始化的下一步:读入配置文件。
在初始化服务器的上一步中,程序为server变量(也即是服务器状态)的各个属性设置了默
认值,但这些默认值有时候并不是最合适的:
- 用户可能想使用 AOF 持久化,而不是默认的 RDB 持久化。
- 用户可能想用其他端口来运行Redis,以避免端口冲突。
- 用户可能不想使用默认的16个数据库,而是分配更多或更少数量的数据库。
- 用户可能想对默认的内存限制措施和回收策略做调整。
Redis默认以daemon进程的方式运行。
当服务器初始化进行到这一步时,程序将创建 daemon 进程来运行 Redis ,并创建相应的 pid文件。
在这一步,初始化程序完成两件事:
在这一步,程序完成的主要动作如下:
完成这一步之后,服务器打印出 Redis 的 ASCII LOGO 、服务器版本等信息,表示所有功能
模块已经就绪,可以等待被使用了:
虽然所有功能已经就绪,但这时服务器的数据库还是一片空白,程序还需要将服务器上一次执
行时记录的数据载入到当前服务器中,服务器的初始化才算真正完成。
在这一步,程序需要将持久化在 RDB 或者 AOF 文件里的数据,载入到服务器进程里面。
如果服务器有启用AOF功能的话,那么使用AOF文件来还原数据;
否则,程序使用RDB文件来还原数据。
当执行完这一步时,服务器打印出一段载入完成信息:
[6717] 22 Feb 11:59:14.830 * DB loaded from disk: 0.068 seconds
到了这一步,服务器的初始化已经完成,程序打开事件循环,开始接受客户端连接。
以下是初始化完成之后,服务器状态和各个模块之间的关系图:
当客户端连上服务器之后,客户端就可以向服务器发送命令请求了。
从客户端发送命令请求,到命令被服务器处理、并将结果返回客户端,整个过程有以下步骤:
假设现在客户端 C1 是连接到服务器 S 的一个客户端;
当用户执行命令 SET YEAR 2013 时 过程:
*3\r\n$3\r\nSET\r\n$4\r\nYEAR\r\n$4\r\n2013\r\n"
redis 服务器是典型的一对多服务器程序:一个服务器可以和多个客户端建立网络连接,每个客户端可以向服务器发送命令请求,而服务器则接收并处理客户端发送的请求,并向客户端返回相应的信息。
redis 服务器通过使用 I/O 多路复用技术实现的文件处理系统,Redis 服务器使用单线程单进程的方式处理命令请求,并与多个客户端进行网络通信。
对于每一个与服务器进行连接的客户端,服务器都为这些客户端建立相应的 redis.h/redisClient 结构,这个结构保存了客户端当前的状态信息,以及执行相关功能时需要用到的数据结构。
Redis 通过监听一个 TCP 端口或者 Unix socket 的方式来接收来自客户端的连接,当一个连接建立后,Redis 内部会进行以下一些操作:
首先,客户端 socket 会被设置为非阻塞模式,因为 Redis 在网络事件处理上采用的是非阻塞多路复用模型。
然后为这个 socket 设置 TCP_NODELAY 属性,禁用 Nagle 算法
然后创建一个可读的文件事件用于监听这个客户端 socket 的数据发送
当 Redis 服务器完成初始化之后,它就准备好可以接受外来客户端的连接了。
当一个客户端通过套接字函数 connect 到服务器时,服务器执行以下步骤:
完成这三步之后,服务器就可以等待客户端发来命令请求了。
Redis 以多路复用的方式来处理多个客户端,为了让多个客户端之间独立分开、不互相干扰,
服务器为每个已连接客户端维持一个 redisClient 结构,从而单独保存该客户端的状态信息。
redisClient 结构主要包含以下信息:
注意:上面列出的客户端结构信息不包含复制相关属性;
• 服务器经过初始化之后,才能开始接受命令。
• 服务器初始化可以分为六个步骤:
1. 初始化服务器全局状态。
2. 载入配置文件。
3. 创建 daemon 进程。
4. 初始化服务器功能模块。
5. 载入数据。
6. 开始事件循环。
• 服务器为每个已连接的客户端维持一个客户端结构,这个结构保存了这个客户端的所有
状态信息。
• 客户端向服务器发送命令,服务器接受命令然后将命令传给命令执行器,执行器执行给
定命令的实现函数,执行完成之后,将结果保存在缓存,最后回传给客户端。