当前位置: 首页 > news >正文

redis命令执行过程

在这里插入图片描述

  1. redis服务器如何解析客户端请求数据
    1. 从连接中获取客户端

    2. 开启I/O线程,读取并解析请求数据(RESP协议)

    3. 若当前读取的是超大参数(大于32KB),则需要保证查询缓冲区只有当前参数数据

    4. 更新单词读取数据量峰值,扩容查询缓冲区,使其可用内存不小于读取字节数,再从socket读取数据

    5. 如果客户端是主节点客户端,还需要更新主从机制方面的属性

    6. 处理读取数据

      1. 请求数据类型未确认,代表当前解析的是一个新的命令请求,需要判断请求类型
      2. 从请求数据解析命令参数,若读取完全则执行命令,否则TCP拆包,继续读取该请求剩余数据
        1. 读取当前命令所有参数
        2. 若参数为一个超大参数,需清除缓冲区内其他参数,确保缓冲区只有当前参数,并对缓冲区扩容,确保其能容纳当前命令参数
        3. 若当前缓冲区字符串长度小于当前命令参数长度,则说明命令参数并没有读取完成,退出,等待下次继续读取剩余数据
        4. 若读取数据是一个超大参数,则直接使用查询缓冲区创建一个redisObject作为参数,并申请新的内存作为查询缓冲区
        5. 若读取数据不是超大参数,则复制查询缓冲区数据并创建一个redisObject作为参数
        6. 读取完执行命令

      因为redis使用的epoll条件触发模式,所以未读取完数据时,系统会发信号给redis继续读取,直到读取完redis才会执行命令。

  2. 服务器如何返回响应数据
    1. 响应数据通常小于16KB,若大于16KB需要申请新的内存块。
    2. 按照RESP协议处理数据
    3. 先尝试写入缓冲区,写不下,申请新的内存
    4. 将回复缓冲区数据写入TCP发送缓冲区
      1. 遍历需要回复的客户端
      2. 将client回复缓冲区内容写入到TCP缓冲区
      3. 如果client回复缓冲区还有数据,则说明数据太多,无法一次性发送给TCP缓冲区,这时需要注册WRITEABLE文件事件回调函数,等待TCP缓冲区可写后,继续写入数据。
  3. 服务器执行命令过程
    redis启动的时候,会加载命令和命令记录到内存中(命令字典)
    1. 触发Module Filter,Module优先级很高
    2. 针对quit命令处理,给client添加退出标志,然后退出 (退出优先级也很高)
    3. 使用命令,从命令字典中查找对应的redisCommand,并检查参数是否满足命令要求
    4. 拒绝执行命令场景
      1. 客户端身份验证未通过
      2. 客户端没有权限执行该命令
      3. 如果该服务运行再cluster模式下,当前节点并不是该命令的健的存储节点,返回数据通知客户端真正的请求节点
      4. 若服务器设置了最大内存,在淘汰数据失败的情况下,会拒绝执行命令
      5. 服务器是主节点持久化出现错误会拒绝执行命令
      6. 主从节点断开连接,拒绝查询命令
      7. 服务器正在加载数据
      8. 服务器处于lua脚本超时状态
    5. 如果当前client处于事务上下文中,那么除EXEC\DISCARD\MULTI\WATCH以外的命令都会加入到事务队列中,否则执行命令。
    6. 发送命令信息给监控模式下的客户端
    7. 命令执行前,重置传播控制标志,这些标志只在命令执行过程中开启,因为执行命令是递归调用,所以执行前要先清除
    8. 执行命令处理的逻辑
      1. 命令处理完后,要求尽快关闭客户端
      2. 如果当前正在加载数据并且当前命令执行是lua脚本,则清除慢日志,命令统计这两个客户端标志,该命令既不输出到慢日志也不添加到命令统计之中
      3. 如果当前客户端时lua脚本伪装的客户端,需要将该客户端的标志转移到真实客户端中
      4. 记录慢日志并统计命令信息
    9. 将命令记录到AOF文件或复制到从服务器中
    10. 命令执行器会清除client的传播控制标志,如果cilent本就有这些标志,又会重新赋值
    11. 需额外传播的命令,这里将它记录到AOF或复制到从服务器中
    12. 若执行的是一个查询命令,redis会记住该命令,若后续查询的健发生变化会通知客户端(这是redis新增的tracking机制)
    13. 命令执行完之后操作
      1. 若客户端是主节点客户端,并且客户端不处于事务上下文中,则更新client.reploff,该属性记录当前服务器已同步命令偏移量,用于主从同步
      2. 重置客户端,这个过程不会清除client回复缓冲区
      3. 若客户端时主节点客户端,则将命令复制到当前服务器的从节点

http://www.mrgr.cn/news/295.html

相关文章:

  • 手机操作技巧:如何进入锁定的Android手机
  • nvm与node安装
  • RabbitMQ 双机系统偶尔丢失消息问题排查
  • 简单记录:两台服务器如何超快速互传文件/文件夹
  • 使用electron-vite创建桌面应用
  • python绘制电路图
  • 【LVGL9学习笔记-2.添加百问网demo至工程模板】
  • 宝马销量崩了,不卷价格就卷铺盖
  • 浅谈企业数字化转型的认知、价值及策略
  • 24/8/17算法笔记 AC算法
  • [STM32]如何正确的安装和配置keil?(详细)
  • STM32标准库学习笔记-4.定时器中断
  • 希尔排序 java
  • 用爬虫玩转石墨文档
  • 初探 Rust 语言与环境搭建
  • 【myz_tools】Python库 myz_tools:Python算法及文档自动化生成工具
  • 常用的数据结构有哪些?
  • pywebview 入门
  • 生物药物分离与纯化技术pdf文件分享
  • arm 的寄存器概述(8)