Redis中的客户端(一)

news2024/10/2 6:31:50

客户端

概述

Redis服务器是典型的一对多服务器程序:一个服务器可以与多个客户端建立网络连接,每个客户端可以向服务器发送命令请求,而服务器则接收并处理客户端发送的命令请求,并向客户端返回命令回复。通过使用由IO多路复用技术实现的文件事件管理器,Redis服务器使用单线程单进程的方式来处理命令请求,并与多个客户端进行网络通信。对于每个与服务器进行连接的客户端,服务器都为这些客户端建立了相应的redis.h/redisClient结构(客户端状态),这个结构保存了客户端当前的状态信息,以及执行相关功能时需要用到的数据结构,其中包括:

  • 1.客户端的套接字描述符
  • 2.客户端的名字
  • 3.客户端的标志值(falg)
  • 4.指向客户端正在使用的数据库的指针,以及该数据库的号码
  • 5.客户端当前要执行的命令、命令的参数、命令参数的个数、以及指向命令实现函数的指针
  • 6.客户端的输入缓冲区和输出缓冲区
  • 7.客户端的复制状态信息,以及进行复制所需的数据结构
  • 8.客户端执行BRPOP、BLPOP等列表阻塞命令时使用的数据结构
  • 9.客户端的事务状态。以及执行WATCH命令时用到的数据结构
  • 10.客户端执行发布与订阅功能时用到的数据结构
  • 11.客户端的身份验证标志
  • 12.客户端的创建事件,客户端和服务器最后一次通信的时间,以及客户端的输出缓冲区大小超出软性限制(soft limit)的时间
    Redis服务器状态结构的clients属性是一个链表,这个链表保存了所有与服务器连接的客户端的状态结构,对客户端执行批量操作,或者查找某个指定的客户端,都可以通过遍历clients链表来完成:
struct redisServer {
 // ...
 
 // 一个链表,保存了所有客户端状态
 list *clients;
 
 // ...
}

例子

  • 举个例子,如图展示了一个与三个客户端进行连接的服务器
    在这里插入图片描述
  • 如图展示了这个服务器的clients链表的样子在这里插入图片描述

客户端属性

客户端状态包含的属性可以分为两类:

  • 1.一类是比较通用的属性,这些属性很少与特定功能相关,无论客户端执行的是什么工作,它们都要用到这些属性
  • 2.另外一类是和特定功能相关的属性,比如操作数据库时需要用到的db属性和dictid属性,执行事务时需要用到的mstate属性,以及执行WATCH命令时需要用到的watched_keys属性等等。

套接字描述符

客户端状态的fd属性记录了客户端正在使用的套接字描述符:

typedef struct redisClient {
 // ...
 int fd;
 // ...
}redisClient;

根据客户端类型的不同,fd属性的值可以是-1或者大于-1的整数:

  • 1.伪客户端(fake client)的fd属性为-1:伪客户端处理的命令请求来源于AOF文件或者Lua脚本,而不是网络,所以这种客户端不需要套接字连接,自然也不需要记录套接字描述符。目前Redis服务器会在两个地方用到伪客户端,一个用于载入AOF我呢见并还原数据库状态,而另一个则
    用于执行Lua脚本中包含的Redis命令
  • 2.普通客户端的fd属性的值大于-1的整数:普通客户端使用套接字来与服务器进行通信,所以服务器会用fd属性来记录客户端套接字的描述符。因为合法的套接字描述符不能是-1,所以普通客户端的套接字描述符的值必然是大于-1的整数

执行CLIENT list命令可以列出目前所有连接到服务器的普通客户端,命令输出中的fd域显示了服务器连接客户端所使用的套接字描述符:

127.0.0.1:6379> client list
id=4 addr=127.0.0.1:61899 fd=9 name= age=27 idle=22 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=client
id=5 addr=127.0.0.1:61921 fd=10 name= age=9 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=client

名字

在默认情况下,一个连接到服务器的客户端是没有名字的。
比如在下面展示的CLIENT list命令示例中,两个客户端的name域都是空白的:

127.0.0.1:6379> client list
id=4 addr=127.0.0.1:61899 fd=9 name= age=27 idle=22 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=client
id=5 addr=127.0.0.1:61921 fd=10 name= age=9 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=client

使用CLIENT setname 命令可以为客户端设置一个名字,让客户端的身份变得更清晰。

127.0.0.1:6379> CLIENT setname testName1
OK
127.0.0.1:6379> client list
id=4 addr=127.0.0.1:61899 fd=9 name=testName1 age=439 idle=6 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=client
id=5 addr=127.0.0.1:61921 fd=10 name= age=421 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=client

其中第一个客户端的名字设置为了testName1,第二个客户端没有进行设置。客户端的名字记录在客户端状态的name属性里面:

typedef struct redisClient {
 // ...
 robj *name;
 // ...
}redisClient

如果客户端没有为自己设置名字,那么相应客户端状态的name属性指向NULL指针,相反地,如果客户端为自己设置了名字,那么name
属性将指向一个字符串对象,而该对象就保存着客户端的名字。

例子
  • 举个例子。如图展示了一个客户端状态示例,根据name属性显示,
    客户端的名字为"testName1"在这里插入图片描述

标志

客户端的标志属性flags记录了客户端的角色(role),以及客户端目前所处的状态:

typedef struct redisClient {
 // ...
 int flags;
 // ...
}redisClient

flags属性的值可以是单个标志:flags = < flag >,
也可以是多个标志的二进制或,比如:flags = < flag1 > | < flag2 > | …
每个标志使用一个常量表示,一部分标志记录了客户端的角色:

  • 1.在主从服务器进行复制操作时,主服务器会称为从服务器的客户端,而从服务器也会成为主服务器的客户端。REDIS_MASTER标志表示客户端代表的是一个主服务器,REDIS_SLAVE标志客户端代表的是一个从服务器。
  • 2.REDIS_PRE_PSYNC标志表示kk而护短代表的是一个版本低于Redis2.8的从服务器,主服务器不能使用PYSNC命令与这个从服务器进行同步,这个标志只能在REDIS_SLAVE标志处于打开状态时使用
  • 3.REDIS_LUA_CLIENT标识表示客户端是专门用于处理Lua脚本里面包含的Redis的伪客户端。

而另一部分标志则记录了客户端目前所处的状态:

  • 1.REDIS_MONITOR标志表示客户端正在执行MONITOR命令
  • 2.REDIS_UNIX_SOCKET标志表示服务器使用UNIX套接字来连接客户端
  • 3.REDIS_BLOCKED标志表示客户端正在被BRPOP、BLPOP等命令阻塞
  • 4.REDIS_UNBLOCKED标志表示客户端已经从REDIS_BLOCKED标志所表示的阻塞状态中脱离出来,不再阻塞。REDIS_UNBLOCKED标志只能在REDIS_BLOCKED标志已经打开的情况下使用
  • 5.REDIS_MULTI标志表示客户端正在执行事务
  • 6.REDIS_DIRTY_CAS标志表示事务使用WATCH命令监视的数据库键已经被修改了
  • 7.REDIS_DIRTY_EXEC标志表示事务在命令入队时出现了错误,以上两个标志都表示事务的安全性已经被破坏,只要这两个标记中的任意一个被打开,EXEC命令必然会执行失败。这两个标志只能在客户端打开了REDIS_MULTI标志的情况下使用
  • 8.REDIS_CLOSE_ASAP标志表示客户端的输出缓冲区大小超出了服务器允许的范围,服务器会在下一次执行serverCron函数时关闭这个客户端,以免服务器的稳定性受到这个客户端影响。积存在输出缓冲区中的所有内容会直接被释放,不会返回给客户端。
  • 9.REDIS_CLOSE_AFTER_REPLY标志表示有用户对这个客户端执行了CLIENT KILL命令,或者客户端发送给服务器的命令请求中包含了错误的协议内容。服务器会将客户端积存z在输出缓冲区中的所有内容发送给客户端,然后关闭客户端
  • 10.REDIS_FORCE_AOF标志强制服务器将当前执行的命令写入到AOF文件里面,REDIS_FORCE_REPL标志强制主服务器将当前执行的命令复制给所有从服务器。执行PUBSUB命令会使客户端打开REDIS_FORCE_AOF标志,执行SCRIPT LOAD命令会使客户端打开REDIS_FORCE_AOF标志和REDIS_FORCE_REPL标志
  • 11.在主从服务器进行命令传播期间,从服务器需要向主服务器发送REPLICATION ACK命令,在发送这个命令之前,从服务器必须打开主服务器对应的客户端的REDIS_MASTER_FORCE_REPLY标志,否则发送操作会被拒绝执行
PUBSUB命令和SCRIPT LOAD命令的特殊性

通常情况下,Redis只会将那些对数据库进行了修改的命令写入到AOF文件,并复制到各个从服务器。如果一个命令没有对数据库j进行任何修改,那么它就会被认为是只读命令,这个命令不会被写入到AOF
文件,也不会被复制到从服务器。以上规则适用于绝大部分Redis命令,但PUBSUB命令和SCRIPT LOAD命令是其中的例外。PUBSUB命令虽然没有修改数据库,但PUBSUB命令向频道的所有订阅者发送消息
这一行为带有副作用,接收到消息的所有客户端的状态都会因为这个命令而改变。因此,服务器需要使用REDIS_FORCE_AOF标志,强制将这个命令写入AOF文件,这样在将来载入AOF文件时,服务器就可以再次
执行相同的PUBSUB命令,并产生相同的副作用。SCIRPT LOAD命令的情况与PUBSUB命令类似:虽然SCRIPT LOAD命令没有修改数据库,但它修改了服务器状态,所以它是一个带有副作用的命令,服务器
需要使用REDIS_FORCE_AOF标志,强制将这个命令写入AOF文件,使得将来在载入AOF文件时,服务器可以产生相同的副作用。另外,为了让主服务器和从服务器都可以正确地载入SCRIPT LOAD命令指定的脚本,
服务器需要使用REDIS_FORCE_REPL标志,强制将SCIRPT LOAD命令复制给所有从服务器

例子
  • 举个flags属性的例子:
# 客户端是一个主服务器
REDIS_MASTER
# 客户端正在被列表命令阻塞
REDIS_BLOCKED
# 客户端正在执行事务,但事务的安全性已被破坏
REDIS_MULTI | REDIS_DIRTY_CAS
# 客户端是一个从服务器,并且版本低于Redis2.8
REDIS_SLAVE | REDIS_PRE_PSYNC
# 这是专门用于执行Lua脚本包含的Redis命令的伪客户端
# 它强制服务器将当前的命令写入AOF文件,并复制给从服务器
REDIS_LUA_CLIENT | REDIS_FORCE_AOF | REDIS_FORCE_REPL

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LeetCode:1319. 连通网络的操作次数(并查集 Java)

目录 1319. 连通网络的操作次数 题目描述&#xff1a; 实现代码与解析&#xff1a; 并查集 原理思路&#xff1a; 1319. 连通网络的操作次数 题目描述&#xff1a; 用以太网线缆将 n 台计算机连接成一个网络&#xff0c;计算机的编号从 0 到 n-1。线缆用 connections 表示…

JAVA面试大全之JVM和调休篇

目录 1、类加载机制 1.1、类加载的生命周期&#xff1f; 1.2、类加载器的层次? 1.3、Class.forName()和ClassLoader.loadClass()区别? 1.4、JVM有哪些类加载机制&#xff1f; 2、内存结构 2.1、说说JVM内存整体的结构&#xff1f;线程私有还是共享的&#xff1f; 2.2…

.NET高级面试指南专题二十三【 B+ 树作为索引有什么优势】

B 树作为索引有许多优势&#xff0c;这些优势使其成为许多数据库管理系统中首选的索引结构之一。以下是 B 树作为索引的一些主要优势&#xff1a; 高效的查询性能&#xff1a;B 树是一种平衡树结构&#xff0c;具有良好的平衡性和高度平衡的性质&#xff0c;这使得在 B 树上进行…

JaveSE—IO流详解:对象输入输出流(序列化及反序列化)

一. 基础理论知识 &#x1f4cc;怎么理解对象输入输出流 &#xff1f; ○ 把java中的对象输出到文件中&#xff0c;从文件中把对象输入到程序中. &#x1f4cc;为什么要这样做(目的) &#xff1f; 当我们创建一个对象时, 如new Student( "小张",20 ); 数据存储在…

[AIGC] MySQL存储引擎详解

MySQL 是一种颇受欢迎的开源关系型数据库系统&#xff0c;它的强大功能、灵活性和开放性赢得了用户们的广泛赞誉。在 MySQL 中&#xff0c;有一项特别重要的技术就是存储引擎。在本文中&#xff0c;我们将详细介绍什么是存储引擎&#xff0c;以及MySQL中常见的一些存储引擎。 文…

对AOP的理解

目录 一、为何需要AOP&#xff1f;1、从实际需求出发2、现有的技术能解决吗&#xff1f;3、AOP可以解决 二、如何实现AOP&#xff1f;1、基本使用2、更推荐的做法2.1 “基本使用”存在的隐患2.2 最佳实践2.2.1 参考Transactional&#xff08;通过AOP实现事务管理&#xff09;2.…

C++零基础入门学习视频课程

教程介绍 本专题主要讲解C基础入门学习&#xff0c;所以不会涉及很深入的语法和机制。但会让你整体多面的了解和学习C的核心内容&#xff0c;快速学习使用C&#xff0c;我们的目标是先宏观整体把握&#xff0c;在深入各个击破&#xff01; 学习地址 链接&#xff1a;https:/…

力扣Lc22--- 459. 重复的子字符串(java版)-2024年3月27日

1.题目描述 2.知识点 &#xff08;1&#xff09; 在Java中&#xff0c;.repeat(i) 是一个字符串方法&#xff0c;用于将原始字符串重复 i 次。 例如&#xff0c;对于字符串 “ab”&#xff0c;使用 .repeat(3) 将会返回 “ababab”。 public class RepeatExample {public s…

速看!MC-CCPIT第二十二届中国国际冶金工业展览会

METALLURGY CHINA 2024 MC-CCPIT第二十二届中国国际冶金工业展览会 ——冶金装备品牌展示区 主办单位&#xff1a;中国钢铁工业协会 中国国际贸易促进委员会冶金行业分会 承办单位&#xff1a;冶金工业国际交流合作中心 地 点&#xff1a;上海新国际博览中心 时 间&am…

高阶SQL语句(二)

一 子查询 也被称作内查询或者嵌套查询&#xff0c;是指在一个查询语句里面还嵌套着另一个查询语 句。子查询语句 是先于主查询语句被执行的&#xff0c;其结果作为外层的条件返回给主查询进行下一 步的查询过滤。 ①子语句可以与主语句所查询的表相同&#xff0c;也可以是不…

2024年目前阿里云服务器一个月收费价格表多少钱?

阿里云服务器一个月多少钱&#xff1f;最便宜5元1个月。阿里云轻量应用服务器2核2G3M配置61元一年&#xff0c;折合5元一个月&#xff0c;2核4G服务器30元3个月&#xff0c;2核2G3M带宽服务器99元12个月&#xff0c;轻量应用服务器2核4G4M带宽165元12个月&#xff0c;4核16G服务…

一文彻底搞懂MySQL中事务的五种分类

文章目录 1. 什么是事务2. 事务的分类3. 事务的详解 1. 什么是事务 事务是指作为单个逻辑工作单元执行的一系列操作&#xff0c;这些操作要么全部成功完成&#xff0c;要么全部失败回滚&#xff0c;从而保证数据库操作一致性和完整性的重要机制&#xff0c;它确保了数据库在并…

程序员提效 x10 的必备开源“神器”

工欲善其事&#xff0c;必先利其器。我们每个人的电脑中都会有一些爱不释手的工具软件。 转Linux 桌面2年了&#xff0c;期间尝试过各种各样“神奇”的开源工具&#xff0c;作为一个开源软件爱好者&#xff0c;这里给大家推荐几个这些年工作、学习、生活中常用、跨平台、免费的…

【MySQL】简述SQLの通用语法及4种基本语句介绍(DDL/DML/DQL/DCL)

前言 大家好吖&#xff0c;欢迎来到 YY 滴MySQL系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C Linux的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY的…

CenOS安装yum(超详细)

专栏文章索引&#xff1a;Linux 目录 1.检查yum源是否安装 2.卸载yum源 3.去网站下载yum源&#xff0c;至少需要下载3个 4.安装&#xff08;不要出现其他后缀名为rpm的文件&#xff09; 1.检查yum源是否安装 rpm -qa|grep yum 2.卸载yum源 查看一下是否成功删除 3.去网站下…

esp32CAM环境搭建(arduino+MicroPython+thonny+固件)

arduino ide 开发工具 arduino版本&#xff1a;1.8.19 arduino ide 中文设置&#xff1a;​ file >> preferences >> ​ arduino IDE 获取 ESP32 开发环境&#xff1a;打开 Arduino IDE &#xff0c;找到 文件>首选项 ,将 ESP32 的配置链接填入附加开发板管理网…

【Linux】进程地址空间详解

前言 在我们学习C语言或者C时肯定都听过老师讲过地址的概念而且老师肯定还会讲栈区、堆区等区域的概念&#xff0c;那么这个地址是指的物理内存地址吗&#xff1f;这里这些区域又是如何划分的呢&#xff1f; 我们在使用C语言的malloc或者C的new函数开辟空间时&#xff0c;开辟…

基于 Linux 的更新版 MaxPatrol VM 可扫描 Windows

&#x1f47e; MaxPatrol VM 2.1 是俄罗斯唯一一款可以安装在 Linux 上并以审计和五重测试模式扫描 Windows 主机&#xff08;甚至是旧版本&#xff09;的漏洞管理产品。 让我们告诉你更新后的 MaxPatrol VM 还有哪些有用的功能&#xff1a; 1. 由于采用了新的数据存储模式&a…

【Canvas与艺术】模拟八一电影制片厂电影片头效果

【缘起】 八一厂每部电影前都有其专有开头&#xff0c;如&#xff1a;https://www.ixigua.com/6799821997258834440?logTag2eacce76401e13f9efe7 这个片头可以用canvas模拟下来。 【关键点】 线型放射状粒子系统的运作。 立体感五角星的绘制。 【图例】 【代码】 <!D…

如何模拟在丢包情况下的传输测试(以镭速为例)

在现代社会&#xff0c;网络通信的可靠性和效率是数据传输的关键因素。网络通信中的丢包问题&#xff0c;作为一种普遍存在的现象&#xff0c;可能对数据传输的完整性和效率产生重大影响。本文的目的是探讨在存在丢包的网络环境中&#xff0c;如何通过模拟测试来评估和改进一款…