【Redis技术进阶之路】「原理分析系列开篇」揭秘分析客户端和服务端网络通信交互实现(客户端篇)

news2024/11/9 5:14:44

揭秘高效存储模型与数据结构底层实现

  • 【专栏简介】
    • 【技术大纲】
    • 【专栏目标】
    • 【目标人群】
      • 1. Redis爱好者与社区成员
      • 2. 后端开发和系统架构师
      • 3. 计算机专业的本科生及研究生
  • 客户端和服务器
    • Redis服务器
      • IO多路复用
        • RedisClient结构
      • 客户端属性分析
        • 套接字描述符
        • 客户端的分类
          • 伪客户端(fake client)
          • 两大关键场景中运用伪客户端
          • 普通客户端(normal client)
            • CLIENT list
            • CLIENT SETNAME
            • CLIENT Flag

【专栏简介】

随着数据需求的迅猛增长,持久化和数据查询技术的重要性日益凸显。关系型数据库已不再是唯一选择,数据的处理方式正变得日益多样化。在众多新兴的解决方案与工具中,Redis凭借其独特的优势脱颖而出。

【技术大纲】

为何Redis备受瞩目?原因在于其学习曲线平缓,短时间内便能对Redis有初步了解。同时,Redis在处理特定问题时展现出卓越的通用性,专注于其擅长的领域。深入了解Redis后,您将能够明确哪些任务适合由Redis承担,哪些则不适宜。这一经验对开发人员来说是一笔宝贵的财富。
在这里插入图片描述

在这个专栏中,我们将专注于Redis的6.2版本进行深入分析和介绍。Redis 6.2不仅是我个人特别偏爱的一个版本,而且在实际应用中也被广泛认为是稳定性和性能表现都相当出色的版本

【专栏目标】

本专栏深入浅出地传授Redis的基础知识,旨在助力读者掌握其核心概念与技能。深入剖析了Redis的大多数功能以及全部多机功能的实现原理,详细展示了这些功能的核心数据结构和关键算法思想。读者将能够快速且有效地理解Redis的内部构造和运作机制,这些知识将助力读者更好地运用Redis,提升其使用效率。

将聚焦于Redis的五大数据结构,深入剖析各种数据建模方法,并分享关键的管理细节与调试技巧。

【目标人群】

Redis技术进阶之路专栏:目标人群与受众对象,对于希望深入了解Redis实现原理底层细节的人群

1. Redis爱好者与社区成员

Redis技术有浓厚兴趣,经常参与社区讨论,希望深入研究Redis内部机制、性能优化和扩展性的读者。

2. 后端开发和系统架构师

在日常工作中经常使用Redis作为数据存储和缓存工具,他们在项目中需要利用Redis进行数据存储、缓存、消息队列等操作时,此专栏将为他们提供有力的技术支撑。

3. 计算机专业的本科生及研究生

对于学习计算机科学、软件工程、数据分析等相关专业的在校学生,以及对Redis技术感兴趣的教育工作者,此专栏可以作为他们的学习资料和教学参考。

无论是初学者还是资深专家,无论是从业者还是学生,只要对Redis技术感兴趣并希望深入了解其原理和实践,都是此专栏的目标人群和受众对象

让我们携手踏上学习Redis的旅程,探索其无尽的可能性!


客户端和服务器

Redis服务器

Redis服务器构成了一个典型的一对多服务模型:
在这里插入图片描述
在此模型中,单个服务器能够同时与多个客户端建立网络连接。每个客户端均具备向服务器发送命令请求的能力,而服务器则负责接收并妥善处理这些来自客户端的命令请求,随后向相应的客户端返回命令执行的结果。

IO多路复用

采纳了基于I/O多路复用技术的文件事件处理器,以此实现单线程单进程模式下的命令请求处理,同时维持与众多客户端的网络通信。

针对每一个与服务器建立连接的客户端,服务器都会为其创建对应的RedisClient结构(即客户端状态)。此结构全面记录了客户端的当前状态信息。
在这里插入图片描述
结构体模型如下所示:

struct redisServer
//...
//一个链表,保存了所有客户端状态
list *clients:
//...

通过遍历clients链表,Redis服务器能够灵活应对各种场景。例如,当需要执行一项影响所有客户端的操作时,服务器可以简单地遍历链表,对每个客户端的状态结构执行相应的操作逻辑。
在这里插入图片描述
同样,当需要查找并操作某个特定客户端时,服务器也可以利用链表提供的遍历机制,结合客户端的唯一标识符或其他属性,高效地定位到目标客户端的状态结构。

RedisClient结构

Redis服务器中的clients属性设计为一个精心组织的链表结构,这一设计巧妙地维护了所有当前与服务器建立连接的客户端的状态信息。

具体而言,每当有客户端成功连接到Redis服务器时,其对应的状态结构(通常包含客户端的多种属性,如连接信息、当前命令执行状态、缓冲区状态等)就会被添加到clients链表中。这一动态维护的链表确保了服务器能够高效地遍历所有连接的客户端,无论是为了执行诸如广播消息、资源回收等批量操作,还是为了快速响应针对特定客户端的查询或管理需求。
在这里插入图片描述

  • 客户端套接字标识符(Socket Descriptor):唯一标识客户端与服务器之间建立的连接通道,确保数据传输的准确性与安全性。

  • 客户端唯一名称标识(Client Identifier):用于在服务器内部或日志中唯一区分不同客户端,便于监控与管理。

  • 客户端标志位集合(Flag Values):用于表示客户端的当前状态、权限等属性,如是否已认证、是否处于订阅模式等。

  • 数据库引用与编号(Database Pointer & Index):客户端当前操作所指向的数据库实例及其索引编号,确保数据操作的正确性与隔离性。

  • 命令执行上下文(Command Execution Context):包含待执行命令详情(如命令类型)、命令参数列表、参数数量统计,以及直接指向实现该命令函数的指针,确保命令的精确执行与快速调度。

  • 缓冲区机制(Input & Output Buffers):客户端的输入缓冲区用于暂存来自客户端的数据,而输出缓冲区则用于存储服务器准备发送给客户端的响应数据,优化数据传输效率。

  • 复制状态与数据结构(Replication Status & Structures):存储客户端参与复制过程的状态信息及相关数据结构,支持主从同步、故障转移等高级功能。

  • 阻塞命令支持结构(Blocking Command Structures):特别针对如BRPOP、BLPOP等列表阻塞命令,设计专用数据结构以管理等待列表项可用的客户端,实现高效的事件驱动机制。

  • 事务与WATCH机制(Transaction & WATCH Structures):记录客户端事务执行的当前状态,包括已入队命令、WATCH监控的键等,确保事务的原子性与一致性。

  • 发布/订阅机制的数据结构(Pub/Sub Structures):支持客户端参与发布与订阅消息的功能,包含订阅的频道列表、消息队列等,实现实时消息传递与广播。

  • 认证状态标志(Authentication Status Flag):标记客户端是否已通过身份验证,控制对敏感操作与数据的访问权限。

  • 时间戳与缓冲区监控(Timestamps & Buffer Size Monitoring)“”:记录客户端的创建时间、最后一次与服务器通信的时间点,以及输出缓冲区大小超出预设软性限制的具体时刻,用于性能监控与资源调配。

客户端属性分析

客户端状态所蕴含的属性可划分为两大范畴:

  • 普遍适用的属性:跨越了不同功能场景,构成了客户端操作的基本框架,无论客户端执行何种任务,这些属性均不可或缺;
  • 功能特定的属性:紧密关联于特定的操作或命令执行,如数据库操作涉及的dbdictid属性、事务处理中的mstate属性,以及WATCH命令执行期间所需的watched keys属性等,这些属性为特定功能提供了必要的支持与保障。
套接字描述符

客户端状态的 fd(File )属性扮演着至关重要的角色,它精确无误地记录了当前客户端所使用的套接字描述符。

typedef struct redisclient
	int fd;
} redisclient;

描述符不仅是客户端与服务器之间通信桥梁的核心标识,也是系统层面进行数据传输、连接管理以及资源分配的关键依据。通过fd属性,Redis服务器能够高效地识别并操作与特定客户端相关联的网络连接,确保数据流的稳定传输与命令响应的及时性。

客户端的分类

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

伪客户端(fake client)
  • 伪客户端其fd(文件描述符)属性被特别设定为-1,这一设计巧妙地反映了伪客户端的独特性质与用途。

伪客户端不直接参与网络通信,其处理的命令请求源自于AOF(Append Only File)持久化文件的重放过程或Lua脚本的执行环境,因此无需建立和维护套接字连接,自然也就无需分配和记录标准的套接字描述符。

两大关键场景中运用伪客户端
  1. AOF文件恢复过程中,伪客户端作为中介,负责读取AOF文件中的命令并逐一执行,从而恢复数据库至特定时间点的状态,确保了数据的持久性与一致性。

  2. Lua脚本执行期间,伪客户端被用于执行脚本内嵌的Redis命令,实现了脚本对数据库的原子性操作,避免了脚本执行期间数据状态的不一致性。

普通客户端(normal client)

通过套接字与Redis服务器进行交互,它们的fd属性值被赋予了一个大于-1的整数,该值代表了客户端套接字在服务器端的唯一标识符。确保了每个普通客户端都能通过其特定的套接字描述符与服务器进行独立且高效的通信。

由于操作系统和TCP/IP协议的限制,合法的套接字描述符不能为-1,因此,这一设计原则不仅符合技术规范,也强化了Redis服务器在并发处理多个客户端请求时的稳定性和可靠性。

CLIENT list

CLIENT list使得能够详尽地检索到当前所有活跃地连接到服务器的普通客户端列表。此命令的执行结果中,特别值得注意的是d域,它扮演着至关重要的角色,揭示了服务器为各客户端连接所分配的唯一套接字描述符(Socket Descriptor)。

redis>CLIENT list
addr=127,0,0,1:53428 fd=6 name= age=1242 id1e=0 ...
addr=127,0,0.1:53469 fd=7 name= age=6 id1e=4 ...

通过深入分析CLIENT list命令的输出,我们不仅能够清晰地看到哪些客户端当前正在与服务器建立连接,还能够借助套接字描述符这一关键指标,进一步探讨连接的管理与优化策略。套接字描述符作为操作系统中用于标识和追踪网络连接的唯一标识符,其值的分配与管理直接关联到服务器的连接处理效率和稳定性。

CLIENT SETNAME

通过运用CLIENT SETNAME指令,用户可以为其Redis客户端分配一个唯一且具描述性的名称,此举显著增强了客户端在服务器端的识别度与可管理性,使得每个客户端的身份变得一目了然,便于追踪与维护。

redis>CLIENT list
addr=127.0.0.1:53428 fd=6 name=message_queue age=2093 idle=0 ...
addr=127.0.0.1:53469 fd=7 name=user_relationship age=855 idle=2...

在此场景中,首先映入眼帘的是名为message_queue的客户端,其命名直观地指向了其核心功能——管理并处理消息队列。这一命名策略不仅便于理解,也预示着该客户端负责高效地调度、传递与存储消息,确保信息流通的顺畅无阻。

紧接着,我们注意到另一个精心命名的客户端:user_relationship。从这个名字中,我们可以合理推测,该客户端专注于用户关系的维护与管理,包括但不限于用户之间的连接、权限设定、以及关系数据的存储与查询。

typedef struct redisclient
//...
robj *name;
}redisclient;

若客户端未主动通过配置来标识自身,则其状态中的name属性将默认指向一个NULL指针,这表示该客户端当前处于未命名状态。反之,一旦客户端通过相应机制设定了自身名称,name属性则会转而指向一个专门存储该名称的字符串对象。
在这里插入图片描述
这一设计确保了每个已命名的客户端都能通过其name属性快速访问到其专属的名称信息,既提高了信息的可访问性,也增强了系统的灵活性与可扩展性。

CLIENT Flag

通过flags属性,系统能够灵活地根据客户端的不同角色和实时状态来执行相应的操作逻辑、资源分配或是访问权限控制,从而确保系统的高效运行与安全性。

typedef struct redisclient
	int flags;
} redisclient;

flags属性的值可以是单个标志:

flags = <flag>

也可以是多个标志的二进制或,比如:

flags=<flag1> | <flag2> 
  • 主从复制架构中的角色标识:在Redis的主从复制机制中,角色是动态且相互依存的。主服务器在执行复制任务时,相对于从服务器而言,扮演了客户端的角色;反之,从服务器在主服务器的视角下,亦被视为客户端。为明确区分这两种角色,我们引入了REDIS_MASTER_CLIENT和REDIS_SLAVE_CLIENT常量。

  • Lua脚本执行环境的客户端标识:为了支持在Redis环境中高效执行Lua脚本,系统引入了REDIS_LUA_SCRIPT_CLIENT这一特殊标志。此标志标识的客户端并非传统意义上的网络连接客户端,而是一种虚拟或内部使用的“伪客户端”,专门负责处理Lua脚本中嵌入的Redis命令。

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

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

相关文章

【二十五】【QT开发应用】无边窗窗口鼠标拖动窗口移动,重写mousePressEvent,mouseMoveEvent函数

在 Qt 中&#xff0c;可以通过在自定义的类中重载 mousePressEvent 和 mouseMoveEvent 函数来捕获鼠标按下和移动事件&#xff0c;以便实现例如拖动窗口等功能。 mousePressEvent 和 mouseMoveEvent分别是鼠标按下事件和鼠标移动事件。这两个函数是QT中本身就存在的函数&#…

prithvi WxC气象模型

NASA发布了prithvi WxC气象模型发布 Prithvi是NASA开源的模型&#xff0c;被誉为全球最大的开源地理空间大模型。昨天晚上逛X平台&#xff0c;我看到Prithvi模型又来了新成员&#xff1a;prithvi WxC。 NASA和IBM创建了一个基于MERRA-2数据的天气和气候AI基础模型—Prithvi Wx…

C++ :借助栈完成二叉树的非递归遍历

二叉树的传统访问分为&#xff1a;前序、中序、后序、层序。 其中前三者是递归访问&#xff0c;但是递归是有缺陷的&#xff0c;树太深就会栈溢出。 因此本文我们思考如何使用非递归的方法来完成遍历。 1. 前序遍历 要迭代⾮递归实现⼆叉树前序遍历&#xff0c;⾸先还是要借…

【计算机组成原理】实验一:运算器输入锁存器数据写实验

目录 实验要求 实验目的 主要集成电路芯片及其逻辑功能 实验原理 实验内容及步骤 实验内容 思考题 实验要求 利用CP226实验箱上的K16&#xff5e;K23二进制拨动开关作为DBUS数据输入端&#xff0c;其它开关作为控制信号的输入端&#xff0c;将通过K16&#xff5e;K23设定…

无人经济已经 next level 了吗?

01 从无人售货机开始… 晚上 11 点下班回到小区&#xff0c;顺便去驿站取个快递&#xff0c;走进驿站发现四周空无一人&#xff0c;把快递放在机器上滴一声就可以走人了。走的时候在旁边的无人超市里拿一袋方便面&#xff0c;当做加班的安慰……发现了吗&#xff0c;无人门店…

ret2dl_resolve

前言&#xff1a; ret2dl_resolve 是一种利用漏洞进行攻击的技术&#xff0c;主要针对使用动态链接库的程序。它的核心原理是利用程序的重定位机制&#xff0c;通过构造特定的函数返回地址&#xff0c;来劫持控制流并执行攻击者选择的代码。以下是对 ret2dl_resolve 原理的详细…

谷歌地图 | Navigation SDK 重磅发布!为你的 App 注入导航新体验

9月17日&#xff0c;Google 地图正式发布 Navigation SDK for Android 和 iOS&#xff01;借助 Navigation SDK&#xff0c;开发者们现在可以更轻松地为用户打造定制化的导航体验&#xff0c;提升用户满意度&#xff0c;增强用户粘性。无论是界面风格、路线规划还是实时交通信息…

城市酷选:如何四年做到3000亿销售额 会员超500w

城市酷选&#xff0c;这一融合了线上线下消费的会员制社交电商平台&#xff0c;正以其独特的运营模式在市场中崭露头角。该平台不仅汇聚了超过600万的会员与60万商家&#xff0c;更实现了年交易额的百亿突破&#xff0c;彰显了其强大的市场影响力和消费者吸引力。 创新排队免单…

C#基础(14)冒泡排序

前言 其实到上一节结构体我们就已经将c#的基础知识点大概讲完&#xff0c;接下来我们会讲解一些关于算法相关的东西。 我们一样来问一下gpt吧&#xff1a; Q:解释算法 A: 算法是一组有序的逻辑步骤&#xff0c;用于解决特定问题或执行特定任务。它可以是一个计算过程、一个…

FileLink跨网文件传输 | 跨越网络边界的利器,文件传输不再受限

在当今数字化时代&#xff0c;企业与个人对文件传输的需求不断增长&#xff0c;尤其是在跨网环境中。传统的文件传输方式常常受到网络带宽、传输速度和安全性的限制&#xff0c;给用户带来了诸多不便。FileLink 的出现&#xff0c;为这一难题提供了完美解决方案&#xff0c;让文…

理解Web3:去中心化互联网的基础概念

随着科技的不断进步&#xff0c;互联网的形态也在不断演变。从最初的静态网页&#xff08;Web1&#xff09;到动态的社交网络&#xff08;Web2&#xff09;&#xff0c;如今我们正步入一个新的阶段——Web3。这一新兴概念不仅代表了一种技术革新&#xff0c;更是一种互联网使用…

RocketMQ简介与应用场景

简介 RocketMQ是一个由阿里巴巴开源并捐献给Apache的分布式消息中间件&#xff0c;具有高吞吐、低延迟、海量消息堆积等特点&#xff0c;广泛应用于各种分布式系统和大规模数据处理场景。 核心特征 1、高吞吐与低延迟&#xff1a;RocketMQ支持极高的消息吞吐量和极低的消息延…

优思学院|ABC成本方法与精益管理

传统企业计算成本主要基于直接费用。其次的间接费用只需根据某项标准&#xff08;作业时间等&#xff09;&#xff0c;粗略地将费用分配给各种产品即可。 近来&#xff0c;生产线自动化与间接业务高度复杂化&#xff0c;间接费用在制造成本中的比重越来越高&#xff0c;传统的…

netty编程之那么多的网络框架为啥非选你?

写在前面 java nio框架不止一种&#xff0c;为啥非选netty&#xff1f;本文来看下。 1&#xff1a;正文 网络io框架&#xff0c;除了netty外&#xff0c;还有mina&#xff0c;sun grizzly&#xff0c;cindy等&#xff0c;为啥独选netty。 mina netty和mina作者同属一人&…

【计算机视觉】YoloV8-训练与测试教程

✨ Blog’s 主页: 白乐天_ξ( ✿&#xff1e;◡❛) &#x1f308; 个人Motto&#xff1a;他强任他强&#xff0c;清风拂山冈&#xff01; &#x1f4ab; 欢迎来到我的学习笔记&#xff01; 制作数据集 Labelme 数据集 数据集选用自己标注的&#xff0c;可参考以下&#xff1a…

用ArcMap实现可视域分析

在 ArcToolbox>>3D Analyst>>可见性>>视域&#xff0c;输入值如图所示&#xff1a; 设置完成后点击确认&#xff0c;生成可视域分析图层 Viewshe1&#xff0c;由内容列表 可见&#xff0c;红色为不可见&#xff0c;绿色为可见。 改变观察点的高度&#xff1a…

pycharm下载selenium等软件包时提示下载超时

1.问题描述 我今天在pycharm运行刚写的自动化脚本时&#xff0c;提示selenium模块未导入&#xff08;自动到导入&#xff09;&#xff0c;鼠标移动到【from selenium import webdriver]的selenium时&#xff0c;显示【未存在文档】 2 解决办法 文件--设置--项目&#xff1a;当前…

企业智能培训新方案,高效打造金牌员工

标品市场竞争激烈&#xff0c;小微企业因长期专注于非标业务或者偏定制化路线&#xff0c;在团队专业能力与大型企业间存在显著差距。专业人才短缺、培养成本高企、培训滞后、效果难测、资源不均、考核标准不一及知识转化率低等问题&#xff0c;成为其业务转型的绊脚石。 如何高…

红外热成像应用场景!

1. 电力行业 设备故障检测&#xff1a;红外热成像仪能够检测电气设备&#xff08;如变压器、电线接头&#xff09;的过热现象&#xff0c;及时发现并定位故障点&#xff0c;预防火灾等安全事故的发生。 水电站查漏&#xff1a;在水电站中&#xff0c;红外热成像仪可用于快速查…

windows自带的录屏功能好用吗?这4款录屏工具也是不错的选择。

因为现在很多人都会有录屏需求&#xff0c;所以平常使用的一些设备当中会有自带的录屏功能。比如windows10系统下只要按下键盘上的 “WinG” 键&#xff0c;就可打开录屏功能。但是录制的时长会有限制&#xff0c;并且录屏功能会有些限制。如果对录屏有更多的需求&#xff0c;可…