redis 复制笔记 - 2019.09

牧云@^-^@ 提交于 2019-11-30 03:26:44
  1. redisClient 中有输入输出缓冲区
    • 输入缓冲区:命令处理器将用户输入的命令写入客户端输入缓冲区,该缓冲区可动态扩展,但最大不能超过 1G,否则服务器将关闭客户端;
    • 输出缓冲区:命令执行器将命令执行生成的回复写入输出缓冲区,并关联回复响应处理器,待客户端产生可写事件时,回复响应处理器将输出缓冲区的内容发送给客户端,并清空输出缓冲区;
    • 输入缓冲区的内容被解析后,生成命令、参数等信息,存入redisClient中的argv数组,并记录数组长度,以待后续命令检查及执行;
  2. 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次,就执行一次指定代码);
  3. 服务器初始化
    • 创建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;
    • 简单描述初始化过程:
      • 初始化服务器状态;
      • 载入服务器配置;
      • 初始化服务器数据结构;
      • 还原数据库状态;
      • 执行事件循环;
  4. 事件轮询:
    • 获取到达时间最近的时间事件,假设是t事件;
    • 获取t事件到达时间,若已到达(负数),置为0,做为获取文件事件的等待时间,设该时间为n;
    • 以n为等待时间获取文件事件(有事件立即返回,无事件等待,直到有事件或超时);
    • 若获取到文件事件,执行;
    • 检查并执行所有已到达的时间事件(单机只有serverCron?)
    • 重复这个过程;
  5. redis应用:
    • main:初始化,然后调用aeMain;
    • aeMain:死循环,调用aeProcessEvents
    • aeProcessEvents:处理文件事件及时间事件(过程见上述:事件轮询);

一些结构:

redisServer

redisClient

redisDb

redisObject

redisCommand


执行命令时,如果客户端正在订阅频道或模式,那么服务器将只接受发布订阅相关的命令,其它命令会被拒绝; 因此,哨兵既要订阅消息,又要发出命令,需要建立两个 连接 到服务器;

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!