文章目录
目录
前言
主要介绍redis的客户端和服务器结构。
一、客户端
- 概括
- Redis一个服务器进程对应多个客户端进程,服务器进程维持一个clients链表,每个redisClient链表节点存着连接的客户端信息
- redisClient节点内容
- 套接字描述符fd
也叫文件描述符,因为文件事件是对套接字操作的抽象,根据套接字的状态不同,产生不同的文件事件,交给I/O多路复用程序分派给不同的事件处理函数处理- 伪客户端:fd=-1
- 载入AOF文件时通过伪客户端执行所有记录的写命令:载入开始时创建,载入结束后关闭
- Lua脚本的redis命令:服务器初始化创建,服务器关闭后关闭
- 普通客户端:fd>-1
- 伪客户端:fd=-1
- 名字name
- 标志flags:记录客户端角色和状态
- 输入缓冲区querybuf:存客户端发来的命令
- 命令与命令参数argv+argc:解析querybuf后,由argv存命令和命令参数+argc存命令参数个数
- 命令的实现函数cmd
- 根据argv里的命令,在命令表里找到对应的redisCommand,redisCommand存了命令实现函数,redisClient中的cmd指向该redisCommand,结合argv和argc完成命令的执行
- 输出缓冲区buf+bufpos / reply
- 存命令回复
- 固定大小:16KB的buf存小的回复,bufpos记录buf使用掉多少内存
- 可变大小:reply用链表来连接命令回复
- 客户端输出缓冲区使用大小到达硬限制时会关闭该客户端,长时间超过软限制时也会关闭该客户端
- 身份验证authenticated:身份验证功能开启时,0表示未通过验证,1表示通过验证可以接受客户端请求
- 时间:ctime客户端创建时间、lastinteraction客户端与服务端上一次交互时间、obuf-soft-limit-reach-time客户端输出缓冲区到达软性限制的时间
- 套接字描述符fd
- 客户端关闭的情况
- 网络连接关闭
- 发送的命令请求不符合协议规范
- 空转时间过长
- 输出缓冲区超过限制
- 成为CLIENT KILL命令的目标
二、服务器
- 一个命令执行的完整过程
- 命令-->客户端-->服务器-->套接字可读产生文件事件-->I/O复用程序分派给命令接受处理器-->命令写入客户端请求缓冲-->命令解析得到argv+argc-->命令执行器开始执行命令-->根据argv到命令表找到rediscommand命令实现函数-->命令执行前置处理-->调用命令实现函数-->后置处理-->命令回复存在客户端输出缓冲区-->客户端套接字可写-->将命令回复写给客户端
- ServerCron函数
- 周期性时间事件,每隔100ms执行一次,管理服务器资源,保持服务器良好运转
- 具体功能
- 更新服务器时间缓存无需每次都系统调用查时间、更新LRU时钟计算某个键值的空转时间、更新服务器每秒执行命令次数、更新服务器内存峰值
- 处理SIGTERM信号:收到SIGTERM信号时在关闭服务器前要先进行RDB持久化操作
- 管理客户端资源:关闭连接超时的客户端、释放过大输入缓冲区、关闭输出缓冲区超出限制的异步客户端
- 管理数据库资源:按照定期删除+惰性删除策略清除过期键
- 检查持久化操作运行状态
- 服务器没有执行持久化操作-->是否有延迟BGREWRITEAOF命令(BGSAVE和BGREWRITEAOF不能一起执行,BGSAVE在执行的话会延迟BGREWRITEAOF,BGREWRITEAOF在执行取消BGSAVE)-->有则执行延迟的BGREWRITEAOF-->没有则检查save选项(900-1/300-10/60-10000)是否触发BGSAVE-->有则执行BGSAVE-->无则检查AOF文件是否超过指定大小(64G)-->有则执行BGREWRITEAOF-->无则不变做任何动作
- AOF缓冲区内容写入AOF文件
- 更新cronloops计数器的值:记录ServerCron函数执行的次数,在主从复制时实现每执行N次ServerCron函数就执行一次指定代码
- 服务器初始化
- 按照默认值初始化服务器状态initServerConfig
- 按配置选项覆盖默认值
- 初始化服务器数据结构initServer
- 还原数据库状态(有AOF文件载入AOF文件,没有AOF文件载入RDB文件)
- 开始执行事件循环(客户端连接请求、客户端命令请求、命令回复、ServerCron时间事件)