【Redis-04】Redis命令在客户端与服务器之间的执行流程

 Redis本质上是一个数据结构服务器,支持键值对类型存储的内存管理系统,可以用作数据库、缓存和消息中间件,在我日常的开发中,基本上使用redis作为缓存中间件。

 在Redis中有两个重要的角色,一个是服务器server,一个是客户端client,他们是一对多的关系,服务器会保存每个与之相连接的客户端的状态信息。本文会从这两个角色,分析客户端和服务器中一些比较重要的属性结构,以及一个命令从客户端发送到服务器接受、处理并返回的实现原理。

1.Server服务器

 Redis服务器启动后,需要经过一些列的初始化及配置的设置,之后就可以接收客户端的命令请求,进行相关操作了,那么服务器初始化的整个过程,主要包含以下几步

  1. 初始化服务器的状态参数:这里主要是创建redisServer这个结构体的实例变量server,并为server中的属性赋值,以存储服务器的状态,但是这里设置的都是一些简单的整数或者字符串等等,比如服务器的运行id,端口号,持久化的触发条件等等,较为复杂的结构不会在这里设置,这一步通过 initServerConfig函数处理。
  2. 载入用户配置项:这一步会载入用户通过命令参数或者配置文件设置的服务器状态信息,对server变量中的相关属性进行修改。
  3. 初始化服务器数据结构:这一步会执行除第一步之外相对复杂的数据结构,如server.clients链表、db数组、server.lua客户端等等,之所以与第一步分开,是因为这一步的结构体的创建可能与第二步用户配置的参数有关,这一步会通过initServer函数处理。经过此步之后,会执行两个重要的步骤,一是服务端创建监听套接字,并关联应答事件处理器,等待客户端的连接;二是开始执行serverCron这个时间事件函数。
  4. 还原数据库状态:载入AOF或者RDB持久化的目标文件,如果AOF持久化开启,服务器使用AOF文件还原数据库的状态,否则使用RDB的持久化文件还原。
  5. 执行事件循环:这里是开始执行主函数中的文件事件和时间事件函数。redis主函数一旦开始执行后,会找要最近一次需要执行的时间事件,计算当前时间与这个时间事件的时差,在这个时间段内会阻塞等待文件事件,并关联事件处理器去处理,由于命令函数处理时间长短无法确定,所以时间事件的实际处理时间,通常会比它本身设定的执行时间会稍微晚一些。
    在这里插入图片描述

2.Client客户端

2.1 客户端创建

 客户端首次创建,连接到服务器之后,会向服务器发送命令,并得到相应的结果和回复。在redis中,客户端可以分为三种类型:一种是负责执行Lua脚本的伪客户端,一种是用来加载aof文件的伪客户端,还有一种就是通过网络连接的普通客户端。

 对于通过网络与redis服务器连接的普通客户端和lua脚本的客户端,服务器都会创建相对应的client 结构,用于记录他们的状态信息,我们先看下客户端在redisServer结构中是如何保存的:

struct redisServer {...// 存放普通客户端的列表list *clients;			/* List of active clients */// 存放lua脚本客户端client *lua_client;   	/* The "fake client" to query Redis from Lua */...
};

 看这段源码,redisServer是表示redis服务器的结构,在这其中clients是一个链表,链表中每个节点代表与之连接的客户端client,新增加的客户端会添加到列表的末尾。而lua_client指针指向了代表lua脚本的伪客户端(fake client: 伪造的客户端)。
在这里插入图片描述

2.2 客户端状态

 通过以上,我们了解到clients链表中每个节点都代表一个客户端client,那么在redis中,client会保存客户端(这里指的是普通的网络客户端)的哪些状态信息呢,看如下源码:

typedef struct client {...// fd是每个客户端连接的标识int fd;                 /* Client socket. */// 这个记录的是客户端的名称,默认没有名称robj *name;             /* As set by CLIENT SETNAME. */// 记录了客户端的角色和相关状态int flags;              /* Client flags: CLIENT_* macros. */// 客户端状态的输入缓冲区,保存客户端的命令请求sds querybuf;           /* Buffer we use to accumulate client queries. */// 下面这两个是解析出来的命令和参数int argc;               /* Num of arguments of current command. */robj **argv;            /* Arguments of current command. */// 一个是根据argv[0]解析出来的命令,一个是最后一次执行的命令struct redisCommand *cmd, *lastcmd;  /* Last command executed. */// 下面两个是输出缓冲区(固定缓冲区大小)int bufpos;char buf[PROTO_REPLY_CHUNK_BYTES];// 下面这个是可变缓冲区,链表,节点是字符串对象list *reply;            /* List of reply objects to send to the client */// 身份验证标识int authenticated;      /* When requirepass is non-NULL. */...
} client;

 客户端状态包含但不限于以下信息:

  • fd 属性表示客户端套接字描述符,取值:-1表示伪客户端(Lua客户端),普通客户端的值≥0;
  • name 指针指向sds的字符串对象,表示客户端名称,默认客户端是没有名称的,可以使用client setname命令设置;
  • flags 属性用于表示客户端角色及目前的状态,角色信息如主服务器或者从服务器,或者伪客户端,状态信息比如当前客户端正处于阻塞状态、执行事务的状态、aof强制写入的状态等。
  • querybuf 属性是输入缓冲区,用于保存客户端发送的命令,是一个sds的对象结构,用redis命令协议的方式保存,大小不能超过1GB;
  • argv+argc 两个属性,用于对客户端命令进行解析后保存,argv属性是一个数组,每一项都是字符串对象,保存命令及命令的参数,argv[0]始终保存要执行的命令,argc属性记录了argv数组的长度。
  • cmd 指针是解析argv[0]得到的命令实现函数,通过查询redis命令表获得的,使用redisCommand结构保存。
  • buf和reply 表示输出缓冲区,输出缓冲区包含固定大小和可变大小的缓冲区,buf是固定的,reply是可变的。简短的内容回复一般保存在buf中,而较长的字符串或者链表等结构保存在reply中。
  • authenticated 表示身份验证标识,0是未通过,1表示通过,只有服务器开启了身份认证功能时才会使用。
  • 和时间有关的属性:
    • ctime 这个记录了客户端创建的时间戳
    • lastinteraction 这个记录了客户端和服务器最后一次交互的时间(互相发送命令),用来记录客户端的空转时长。

 以上部分信息可以通过命令client list查询,获取的就是当前服务端所有正在连接的客户端信息。

2.3 客户端断开

  • 用来加载aof文件的伪客户端,redis服务器启动之初创建,在完成aof文件的载入后关闭;
  • 负责执行Lua脚本的伪客户端,在redis服务器启动后整个生命周期都是存在的,直到服务器停止运行;
  • 通过网络连接的普通客户端,服务器会给此类客户端创建文件事件的处理器,并保存每个客户端的状态。客户端在遇到几种情况后会关闭,比如网络断开、发送了不合格协议的命令请求,空转时间超时,输入/输出缓冲区超出限制等等,生命周期也随之结束。

 以上就是客户端整个生命周期的状态描述,下面我们来看一下,一个命令从客户端发送,到服务器执行后返回,整个过程都执行了哪些操作。

3 命令执行过程

 一个命令从发送到处理并回复的过程,客户端和服务器都执行了很多操作。简单来看,就是客户端发送命令,如get key;服务器接收命令,并转化成相关函数操作,得到结果,然后发送给客户端;客户端接收数据并呈现给用户。在这一个流程中,具体包含哪些细节呢?

  1. 用户在客户端输入命令,客户端对命令进行协议转换,并发送给服务器;
  2. 服务器通过监听套接字,获取命令协议内容,存储到当前客户端的输入缓冲区。
  3. 对命令解析,分别存放到argv属性(命令+参数)和argc(argv数组长度)中。
  4. 根据argv[0]在命令表中查找对应的实现命令,并存放到当前客户端的cmd属性中。
  5. 执行命令前的状态检查,包含cmd指针是否有实现、客户端是否进行了身份验证,是否进行最大内存校验等等,确保命令执行的安全和可行性。
  6. 调用cmd指向的命令实现函数,执行操作,获得回复数据后存储到当前客户端的输出缓冲区里面。
  7. 关联客户端套接字的命令回复处理器,将数据返回,并清空客户端输出缓冲区。
  8. 客户端接收到协议格式的命令回复后,对结果进行转换,并打印成用户可读的形式。

4 图示

 综上,使用流程图来表示以上客户端与服务器的加载过程,以及命令的实现流程,如下图:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/234392.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Adding Conditional Control to Text-to-Image Diffusion Models——【论文笔记】

本文发表于ICCV2023 论文地址:ICCV 2023 Open Access Repository (thecvf.com) 官方实现代码:lllyasviel/ControlNet: Let us control diffusion models! (github.com) Abstract 论文提出了一种神经网络架构ControlNet,可以将空间条件控制添加到大型…

性能分析与调优: Linux 监测工具的数据来源

目录 一、实验 1.环境 2. proc目录 3. sys目录 4.netlink 5.tracepoint 6.kprobes 7. uprobes 二、问题 1.systemd如何查看启动时间 2.CentOS与Ubuntu如何安装bpftrace 3.snap有哪些常用的命令 4.snap如何安装store 5.如何列出使用bpftrace的OpenJDK USDT探针 一…

显示管理磁盘分区 fdisk

显示管理磁盘分区 fdisk fdisk是用于检查一个磁盘上分区信息最通用的命令。 fdisk可以显示分区信息及一些细节信息,比如文件系统类型等。 设备的名称通常是/dev/sda、/dev/sdb 等。 对于以前的设备有可能还存在设备名为 /dev/hd* (IDE)的设备,这个设…

回顾2023编程之旅

一、前言 看在给了我一个博客专家的份上就继续写写博客,实事求是的讲如果是工作之余去总结csdn写写技术博客,还想混个专家什么的,真的是精力不够。因为里面的灌水的实在太多,比不过的,写这个玩意必须得淡泊名利才能悠然…

【PostgreSQL在线创建索引(CIC)功能的锁分析以及使用注意】

前一篇文章提到了普通创建索引会阻塞DML操作 PostgreSQL创建索引的锁分析和使用注意 而PostgreSQL里可以使用create index concurrently 在线创建索引(CIC)功能,降低创建索引在表上申请的锁的级别,ShareUpdateExclusiveLock级别的锁和RowExclusiveLock…

烟花燃放如何管控?智能分析网关V4烟火检测保障烟火安全

一、方案背景 随着元旦佳节的热潮退去,春节也即将来临,在众多传统的中国节日里,烟花与烧纸祭祀都是必不可少的,一方面表达了人们对节日的庆祝的期许,另一方面也是一种对故者思念的寄托。烟花爆竹的燃放不仅存在着巨大的…

Git将本地项目上传到Gitee仓库

1.右键点击文件,点击Git Bash Here,进入git窗口 2.初始化本地仓库 git init3.将本地仓库与远程仓库建立连接 git remote add origin 远程仓库地址远程仓库地址在gitee仓库复制即可 4.将远程仓库的文件拉到本地仓库中 git pull origin master5.将本地文件全部上传…

多模态推荐系统综述:二、特征交互 Fusion

二、Fusion 融合不同的多模态信息,与bridge相比,融合更关注项目之间的多模态内部关系。 它可以灵活地融合不同权重和焦点的多模态信息。 注意机制是应用最为广泛的特征融合。 2.1 粗粒度注意力。 一些模型应用注意力机制在粗粒度级别融合来自多种模式…

使用openssl 生成pfx格式证书时报错:unable to load certificates

问题现象包如下: 之前在centos上使用openssl部署证书服务器以及颁发证书的时候遇到的问题,在进行个人证书生成之后需要形成pfx格式证书,结果过程中报错了。网上类似资料比较少,做个记录。 生成pfx格式证书的命令: o…

c++实现支持动态扩容的栈(stack)

1.在栈容量满时自动扩容: 支持自动扩容栈实现: // // myStack.hpp // algo_demo // // Created by Hacker X on 2024/1/9. //#ifndef myStack_hpp #define myStack_hpp #include <stdio.h> #include <string.h> //栈实现 //1.入栈 //2.出栈 //3.空栈 //4.满栈 …

git安装

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 例如&#xff1a;…

Java后端开发——Mybatis实验

文章目录 Java后端开发——Mybatis实验一、MyBatis入门程序1.创建工程2.引入相关依赖3.数据库准备4.编写数据库连接信息配置文件5.创建POJO实体6.编写核心配置文件和映射文件 二、MyBatis案例&#xff1a;员工管理系统1.在mybatis数据库中创建employee表2.创建持久化类Employee…

忆阻器芯片STELLAR权重更新算法(清华大学吴华强课题组)

参考文献&#xff08;清华大学吴华强课题组&#xff09; Zhang, Wenbin, et al. “Edge learning using a fully integrated neuro-inspired memristor chip.” Science 381.6663 (2023): 1205-1211. STELLAR更新算法原理 在权值更新阶段&#xff0c;只需根据输入、输出和误差…

python数据可视化之折线图案例讲解

学习完python基础知识点&#xff0c;终于来到了新的模块——数据可视化。 我理解的数据可视化是对大量的数据进行分析以更直观的形式展现出来。 今天我们用python数据可视化来实现一个2023年三大购物平台销售额比重的折线图。 准备工作&#xff1a;我们需要下载用于生成图表的第…

Hyperledger Fabric 自动发现网络信息 discover 工具使用

客户端要往 Fabric 网络中发送请求&#xff0c;首先需要知道网络的相关信息&#xff0c;如网络中成员组织信息、背书节点的地址、链码安装信息等。 在 Fabric v1.2.0 版本之前&#xff0c;这些信息需要调用者手动指定&#xff0c;容易出错&#xff1b;另外&#xff0c;当网络中…

Centos7 手动更改系统时间

文章目录 1.更改系统时间2.写入系统时间3.查看是否写入成功 1.更改系统时间 date -s "2017-12-18 09:40:00"2.写入系统时间 hwclock -w3.查看是否写入成功 timedatectl

RT-Thread:SPI万能驱动 SFUD 驱动Flash W25Q64,通过 STM32CubeMX 配置 STM32 SPI 驱动

关键词&#xff1a;SFUD,FLASH,W25Q64&#xff0c;W25Q128&#xff0c;STM32F407 说明&#xff1a;RT-Thread 系统 使用 SPI万能驱动 SFUD 驱动 Flash W25Q64&#xff0c;通过 STM32CubeMX 配置 STM32 SPI 驱动。 提示&#xff1a;SFUD添加后的存储位置 1.打开RT-Thread Sett…

497 蓝桥杯 成绩分析 简单

497 蓝桥杯 成绩分析 简单 //C风格解法1&#xff0c;*max_element&#xff08;&#xff09;与*min_element&#xff08;&#xff09;求最值 //时间复杂度O(n)&#xff0c;通过率100% #include <bits/stdc.h> using namespace std;using ll long long; const int N 1e4 …

线扫相机品牌汇总(国外+国内)

线扫相机品牌汇总(国外+国内) 行者 ​ 热爱生活 22 人赞同了该文章 线扫相机也叫做线阵相机,和面阵相机一样,都是重要的工业相机。 线扫相机正如其名字那样,拍照时像扫描一样,相机和被拍照物体有相对匀速运动。 Perhaps the most common example of line scan imagin…

谷粒商城项目|微服务架构的一些与思考解决跨域问题

1.微服务架构的组成每部分的作用 2.还有其他的微服务架构模式吗 3.微服务服务交互的方式 1&#xff09;grpc 2&#xff09;rest api 4.微服务网关与API网关&#xff1f; 5.注册中心比较&#xff08;Nacos与Eureka&#xff09; Nacos Nacos 是阿里巴巴开源的项目&#xff0c;N…