- redisClient 中有输入输出缓冲区
- 输入缓冲区:命令处理器将用户输入的命令写入客户端输入缓冲区,该缓冲区可动态扩展,但最大不能超过 1G,不然服务器将关闭客户端;
- 输出缓冲区:命令执行器将命令执行生成的回复写入输出缓冲区,并关联回复响应处理器,待客户端产生可写事件时,回复响应处理器将输出缓冲区的内容发送给客户端,并清空输出缓冲区;
- 输入缓冲区的内容被解析后,生成命令、参数等信息,存入redisClient中的argv数组,并记录数组长度,以待后续命令检查及执行;
- serverCron(时间事件,默认每隔100ms执行一次):
- 更新服务器时间:unixtime/mstime(s/ms),默认100ms;
- 更新lru_time:默认10s;
- 更新服务器每秒执行命令数(大概值,取1ms次数乘以1000为一次样本,默认取16次样本平均值);
- 处理sigterm信号(不带参数的kill):redisServer.asap状态,serverCron每次执行,都将检测该标识,为1时,将关闭服务器,且关闭前将进行持久化操做;
- 管理客户端资源:每次serverCron都执行,释放过时客户端及清理客户端输入缓冲区;
- 管理数据库资源:每次都调用databaseCron,随机处理一部分数据的过时键,并在须要时,对字典(键空间)进行收宿操做;
- bgrewriteaof:redisServer.aof_rewrite_scheduled,BGSAVE期间,若收到bgrewriteaof命令,将修改此标识,延时到serverCron执行期间执行此命令;
- 检查子进程持久化操做的运行状态,以判断是否须要执行后续操做(替换rdb文件或者重写的aof文件等等),若无持久化状态,则检查是否知足持久化条件,进行持久化,或者aof重写;
- 将aof缓冲区中的内容写入aof文件(开启aof且缓冲区有数据),并按配置判断是否须要调用同步指令;
- 关闭异步客户端(输出缓冲区大小超过限制);
- 增长cronLoops计数值,该计数记录了serverCron执行次数(目前该计数惟一做用:在复制模块中实现,serverCron函数每执行N次,就执行一次指定代码);
- 服务器初始化
- 建立redisServer实例变量server;
- 调用initServerConfig,设置server默认值,并建立命令表;
- 载入配置项,并使用配置的值替换server中的默认值;
- 调用initServer函数,为建立相关数据结构分配内存,并按需设置或关联初始化值等,并进行一些设置:
- 数据结构:
- server.cliens 链表
- server.db 数组
- server.pubsub_channels 字典,用于保存频道订阅信息;
- server.pubsub_patterns 链表,保存模式订阅信息;
- server.lua 用于执行lua脚本的lua环境;
- server.slowlog 用于保存慢查询日志;
- 设置:
- 为服务器设置进程信号处理器;
- 建立共享对象(如服务器经常使用的"OK"等字符串常量,其中有表示整数1-10000的字符串对象);
- 打开服务器的监听端口,并为监听套接字关联【链接应答处理器】;
- 为serverCro函数件建立时间事件;
- 若AOF持久化功能打开,打开现有的AOF文件,若不存在,建立一个新的,为AOF写入作准备;
- 初始化服务器上后台IO(BIO)模块,
- initServer执行完后,打印redis图标及支行模式、服务器版本、端口号、PID等信息;
- 还原数据库状态:载入RDB或AOF文件(若启用AOF,就用AOF,不然用RDB),还原数据;
- 执行事件循环;
- 日志:xxx The server is now ready to accept connections on port 6379;
- 简单描述初始化过程:
- 初始化服务器状态;
- 载入服务器配置;
- 初始化服务器数据结构;
- 还原数据库状态;
- 执行事件循环;
- 事件轮询:
- 获取到达时间最近的时间事件,假设是t事件;
- 获取t事件到达时间,若已到达(负数),置为0,作为获取文件事件的等待时间,设该时间为n;
- 以n为等待时间获取文件事件(有事件当即返回,无事件等待,直到有事件或超时);
- 若获取到文件事件,执行;
- 检查并执行全部已到达的时间事件(单机只有serverCron?)
- 重复这个过程;
- redis应用:
- main:初始化,而后调用aeMain;
- aeMain:死循环,调用aeProcessEvents
- aeProcessEvents:处理文件事件及时间事件(过程见上述:事件轮询);
一些结构:redis
redisServer数据库
redisClient数组
redisDb服务器
redisObject数据结构
redisCommand异步
执行命令时,若是客户端正在订阅频道或模式,那么服务器将只接受发布订阅相关的命令,其它命令会被拒绝; 所以,哨兵既要订阅消息,又要发出命令,须要创建两个 链接 到服务器;函数