Redis客户端命令到服务器底层对象机制的完整流程?什么是Redis对象机制?为什么要有Redis对象机制?
Redis客户端命令到服务器底层对象机制的完整流程
客户端 → RESP协议封装 → TCP传输 → 服务器事件循环 → 协议解析 → 命令表查找 → 对象机制 → 动态编码 → 数据结构操作 → 响应编码 → 网络回传
Redis客户端命令到服务器底层对象机制的完整流程可分为协议封装、命令解析、多态执行、内存操作四个阶段。以下是结合RESP协议规范、对象机制和命令处理源码的详细流程分析:
一、客户端命令发送阶段
-
命令序列化
客户端将用户输入的指令(如HSET user:1 name "Alice")按RESP协议编码为二进制格式。例如:*4\r\n$4\r\nHSET\r\n$6\r\nuser:1\r\n$4\r\nname\r\n$5\r\nAlice\r\n其中
*4表示4个参数段,$n表示后续字符串长度。 -
网络传输
通过TCP套接字将序列化后的数据发送至Redis服务器。客户端可能使用连接池管理多个连接,支持超时重连机制。
二、服务器协议解析阶段
-
读取输入缓冲区
服务器通过I/O多路复用检测到可读事件后,将协议数据存入客户端状态client的输入缓冲区querybuf,最大限制1GB(超限关闭连接)。 -
参数解析
按RESP协议解码,分割出命令参数存入argv数组。例如解析出["HSET","user:1","name","Alice"],参数个数存入argc。 -
命令表查找
根据argv[0](命令名)在全局命令字典commandTable中查找对应的redisCommand结构,验证权限、参数个数等。例如HSET对应实现函数hsetCommand。
三、对象机制与多态执行阶段
-
键对象检索
在数据库字典中查找键user:1对应的redisObject:robj *keyobj = lookupKeyWrite(c->db, c->argv[1]);若不存在则创建新对象,类型由命令决定(此处为
OBJ_HASH)。 -
类型与编码检查
- 验证
redisObject.type是否匹配命令要求(如哈希命令需OBJ_HASH类型)。 - 根据当前
redisObject.encoding选择底层数据结构操作函数(如ziplist或hashtable)。
- 验证
-
动态编码转换
若数据特征触发阈值(如哈希元素超过hash-max-ziplist-entries),执行编码转换:if (hashTypeLength(o) > server.hash_max_ziplist_entries)hashTypeConvert(o, OBJ_ENCODING_HT);此过程涉及数据迁移和旧结构内存释放。
-
执行底层操作
调用编码对应的函数操作数据结构。例如哈希表使用dictReplace插入键值对:dictEntry *de = dictAddRaw(dict, field, &existing); dictSetVal(dict, de, value);
四、响应返回与内存管理
-
结果写入输出缓冲区
操作结果按RESP协议编码后存入客户端buf或reply链表。例如返回":1\r\n"表示成功插入1个元素。 -
内存回收与共享
- 通过
refcount引用计数自动回收无引用对象。 - 小整数等共享对象直接复用,减少内存分配。
- 通过
-
数据同步
若开启AOF或主从复制,将命令追加到AOF缓冲区或发送给从节点。
什么是Redis对象机制?为什么要有Redis对象机制?
Redis对象机制是其实现多态数据结构和高效内存管理的核心设计,通过统一的对象模型(redisObject)封装了所有数据类型,对外提供一致的接口,同时支持多种底层编码的动态切换。
一、为什么需要对象机制?
-
统一接口与多态支持
- Redis支持5种基础数据类型(字符串、列表、哈希、集合、有序集合),每种类型可能有多种底层实现(如哈希表可用
ziplist或hashtable)。对象机制通过redisObject统一封装,使得命令处理时无需关心具体实现,只需根据类型和编码调用对应函数,实现多态性。
- Redis支持5种基础数据类型(字符串、列表、哈希、集合、有序集合),每种类型可能有多种底层实现(如哈希表可用
-
灵活优化内存与性能
- 根据数据特征动态选择最优编码。例如:
- 小规模哈希使用
ziplist节省内存,大规模时切换为hashtable提升操作效率。 - 字符串根据长度选择
int、embstr或raw编码,减少内存碎片。
- 小规模哈希使用
- 根据数据特征动态选择最优编码。例如:
-
内存管理与共享对象
- 通过引用计数(
refcount)自动回收无引用对象,避免内存泄漏。 - 预创建常用共享对象(如0-9999的整数),减少重复分配,节省内存。
- 通过引用计数(
-
类型检查与安全
- 执行命令前检查
redisObject的type属性,防止对错误类型执行操作(如对字符串执行列表命令)。
- 执行命令前检查
二、对象机制的核心:redisObject结构
typedef struct redisObject {unsigned type:4; // 数据类型(如OBJ_STRING)unsigned encoding:4; // 编码方式(如OBJ_ENCODING_INT)unsigned lru:24; // 最近访问时间(用于LRU淘汰)int refcount; // 引用计数 void *ptr; // 指向实际数据结构的指针
} robj;
-
关键属性解析
type(4位):标识数据类型,包括OBJ_STRING、OBJ_LIST等5种。encoding(4位):决定底层数据结构,如ziplist、skiplist等11种编码方式。ptr:指向具体数据结构(如SDS字符串、quicklist列表)的内存地址。refcount:引用计数,为0时触发内存回收;>1时表示共享对象。lru:记录对象最后一次被访问的时间,用于内存淘汰策略(如maxmemory配置)。
-
编码方式与底层结构
数据类型 可能的编码方式 适用场景 字符串(String) int、embstr、raw整数值、短字符串(≤44B)、长字符串 列表(List) quicklist所有列表操作 哈希(Hash) ziplist、hashtable小哈希(字段少且值小)、大哈希 集合(Set) intset、hashtable整数集合、混合类型集合 有序集合(ZSet) ziplist、skiplist+dict小规模有序集合、大规模需范围查询
三、对象机制的工作流程
-
创建对象
- 根据数据类型和内容选择初始编码,如字符串若为整数则用
int编码。
- 根据数据类型和内容选择初始编码,如字符串若为整数则用
-
执行命令
- 检查
type是否匹配命令要求(如LPOP需OBJ_LIST类型)。 - 根据
encoding选择底层数据结构的处理函数(如ziplist或hashtable的插入逻辑)。
- 检查
-
动态编码转换
- 数据变化触发编码切换。例如哈希字段数超过
hash-max-ziplist-entries时,从ziplist转为hashtable。
- 数据变化触发编码切换。例如哈希字段数超过
-
内存回收与共享
- 引用计数归零时,释放
ptr指向的数据结构内存。 - 预创建的共享对象(如小整数)被多个键共享,减少重复创建。
- 引用计数归零时,释放
四、示例:字符串对象的多编码实现
int编码:存储整数值(如SET key 100),直接复用ptr指针存储数值。embstr编码:短字符串(≤44字节)连续存储redisObject和SDS,减少内存分配次数。raw编码:长字符串使用独立分配的SDS结构,支持动态扩容。
相关文章:
Redis客户端命令到服务器底层对象机制的完整流程?什么是Redis对象机制?为什么要有Redis对象机制?
Redis客户端命令到服务器底层对象机制的完整流程 客户端 → RESP协议封装 → TCP传输 → 服务器事件循环 → 协议解析 → 命令表查找 → 对象机制 → 动态编码 → 数据结构操作 → 响应编码 → 网络回传 Redis客户端命令到服务器底层对象机制的完整流程可分为协议封装、命令解…...
Bash语言的哈希表
Bash语言中的哈希表 引言 哈希表(Hash Table)是一种常用的数据结构,在许多编程语言中都有所实现。在 Bash 脚本中,虽然没有直接的哈希表类型,但我们可以利用关联数组(associative array)来实现…...
OpenCV--图像边缘检测
在计算机视觉和图像处理领域,边缘检测是极为关键的技术。边缘作为图像中像素值发生急剧变化的区域,承载了图像的重要结构信息,在物体识别、图像分割、目标跟踪等众多应用场景中发挥着核心作用。OpenCV 作为强大的计算机视觉库,提供…...
深度探索:策略学习与神经网络在强化学习中的应用
深度探索:策略学习与神经网络在强化学习中的应用 策略学习(Policy-Based Reinforcement Learning)一、策略函数1.1 策略函数输出的例子 二、使用神经网络来近似策略函数:Policy Network ,策略网络2.1 策略网络运行的例子2.2需要的几个概念2.3神经网络近似…...
ModuleNotFoundError: No module named ‘pandas‘
在使用Python绘制散点图表的时候,运行程序报错,如图: 报错显示Python 环境中可能没有安装 pandas 库,执行pip list命令查看,果然没有安装pandas 库,如图: 执行命令:python -m pip in…...
配环境的经验
pip install -e . 该命令用于以“编辑模式”(也称为开发模式)安装当前目录下的 Python 包,比如包含有 setup.py、setup.cfg 或 pyproject.toml 文件的项目-e 是 --editable 的简写。以编辑模式安装时,pip 会在你的 Python 环境中创…...
解决 Kubernetes 中容器 `CrashLoopBackOff` 问题的实战经验
在 Kubernetes 集群中,容器状态为 CrashLoopBackOff 通常意味着容器启动失败,并且 Kubernetes 正在不断尝试重启它。这种状态表明容器内可能存在严重错误,如应用异常、依赖服务不可用、配置错误等。本文将分享一次实际排障过程,并…...
hive/doris查询表的创建和更新时间
hive查询表的创建和更新时间: SELECT d.NAME AS database_name, t.TBL_NAME AS table_name, FROM_UNIXTIME(t.CREATE_TIME) AS create_time, FROM_UNIXTIME(tp.PARAM_VALUE) AS last_ddl_time FROM metastore.TBLS t JOIN metastore.DBS d ON t.DB_ID d.DB_ID JOIN…...
springboot中使用async实现异步编程
目录 1.说明 2.实现原理 3.示例 4.总结 1.说明 Async 是 Spring 框架提供的一个注解,用于标记方法为异步执行。被标记的方法将在调用时立即返回,而实际的方法执行将在单独的线程中进行。 Async 注解有一个可选属性:指定要使用的特定线程…...
【教程】MacBook 安装 VSCode 并连接远程服务器
目录 需求步骤问题处理 需求 在 Mac 上安装 VSCode,并连接跳板机和服务器。 步骤 Step1:从VSCode官网(https://code.visualstudio.com/download)下载安装包: Step2:下载完成之后,直接双击就能…...
初识 Three.js:开启你的 Web 3D 世界 ✨
3D 技术已经不再是游戏引擎的专属,随着浏览器技术的发展,我们完全可以在网页上实现令人惊艳的 3D 效果。而 Three.js,作为 WebGL 的封装库,让 Web 3D 的大门向更多开发者敞开了。 这是我开启这个 Three.js 专栏的第一篇文章&…...
基于大模型的病态窦房结综合征预测及治疗方案研究报告
目录 一、引言 1.1 研究背景与目的 1.2 研究意义 二、病态窦房结综合征概述 2.1 定义与病因 2.2 临床表现与分型 2.3 诊断方法 三、大模型在病态窦房结综合征预测中的应用 3.1 大模型介绍 3.2 数据收集与预处理 3.3 模型训练与优化 四、术前预测与准备 4.1 风险预…...
在 Ubuntu 下通过 Docker 部署 PSQL 服务器的详细技术博客
今天,需要部署一个密码管理器,突然要用到PSQL的服务器,所以就把部署的过程记录下来。 鉴于最近囊中羞涩,故此次部署实验使用三丰云的免费服务器配置,配置是为1 核 CPU、1G 内存和 5M 带宽,足够了。 以下是…...
【FAQ】HarmonyOS SDK 闭源开放能力 —Account Kit(3)
1.问题描述: PC场景,青少年模式系统API不支持吗? 解决方案: PC场景,青少年模式系统API不支持,另外文档上的几个API也不支持。 2.问题描述: 华为一键登录 Beta7本地运行到手机可以拿到匿名手…...
地图与图层操作
地图文档本质上就是存储在磁盘上的地图,包括地理数据、图名、图例等一系列要素,当完成地图制作、图层要素标注及符号显示设置后,可以将其作为图层文件保存到磁盘中,在一个图层文件中,包括了定义如何在地图上描述地理数…...
starrocks split函数和trino split函数差异性
在trino419和starrocks3.2.8中分别执行下面这两条sql,出来的结果是不一样的 select split(,,,)[1] as t1 select coalesce(split(,,&#...
LeetCode算法题(Go语言实现)_33
题目 给定一个二叉树 root ,返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 一、代码实现 func maxDepth(root *TreeNode) int {// 递归法(后序遍历)if root nil {return 0}leftDepth : maxDepth(r…...
go程序启动工具——cobra
以下是将“为什么很多 Go 程序启动都是用 Cobra”的内容转换为 Markdown 格式的文档: 为什么很多 Go 程序启动都是用 Cobra 在 Go 编程生态中,Cobra 是一个非常流行的命令行工具库,许多 Go 程序选择使用它来构建启动逻辑和命令行接口&#…...
Unet网络的Pytorch实现和matlab实现
文章目录 一、Unet网络简介1.1 输入图像1.2 编码器部分(Contracting Path)1.3 解码器部分(Expanding Path)1.4 最后一层(输出)1.5 跳跃连接(Skip Connections) 二、Unet网络的Pytorc…...
【合新通信】相控阵雷达RFoF方案的应用
一、相控阵雷达为何需要RFoF? 核心需求驱动 分布式部署:相控阵雷达(AESA/PESA)的T/R模块需分散布局(如舰载雷达阵面、卫星载荷),传统同轴电缆导致重量和损耗剧增。高频段挑战:X/Ku/…...
关于点卷积
🧠 什么是点卷积? 点卷积(Pointwise Convolution) 是一种特殊类型的卷积操作,其基本特点是卷积核的大小为 1 1 1 \times 1 11。与传统的卷积操作(如 3 3 3 \times 3 33 或 5 5 5 \times 5 55 卷积核…...
原理图输出网表及调入
一、输出网表操作步骤 (1)选中.dsn文件,选者N或进入tools下拉列表选择Creat Netlists (2)导出网表后的文件 二、网表的导入 (1)执行菜单命令“File-Import-Logic/netlist”,将原理…...
python基础12 模块/库的引用
在软件的设计中,经常提及到解耦的概念,即模块和模块之间的功能尽可能独立,减少不必要的关联。所以在实际项目中,我们经常会将一个工程拆解成很多不同的功能模块,以实现更优的设计并满足团队开发的要求。 有了模块的概…...
TDengine JAVA 语言连接器
简介 本节简介 TDengine 最重要且使用最多的连接器, 本节内容是以教科书式方式列出对外提供的接口及功能及使用过程中要注意的技术细节,大家可以收藏起来做为今后开发 TDengine 的参考资料。 taos-jdbcdriver 是 TDengine 的官方 Java 语言连接器,Java…...
【NLP 55、实践 ⑬ LoRA完成NER任务】
目录 一、数据文件 二、模型配置文件 config.py 三、数据加载文件 loader.py 1.导入文件和类的定义 2.初始化 3.数据加载方法 代码运行流程 4.文本编码 / 解码方法 ① encode_sentence(): ② decode(): 代码运行流程 ③ padding(): 代码…...
【蓝桥杯】Python大学A组第十五届省赛
1.填空题 1.1.拼正方形 问题描述 小蓝正在玩拼图游戏,他有个的方块和个的方块,他需要从中挑出一些来拼出一个正方形。 比如用个和个的方块可以拼出一个的正方形;用个的方块可以拼出一个的正方形。 请问小蓝能拼成的最大的正方形的边长为多少。 import math # 2*2的个数 a =…...
小球反弹(蓝桥杯C语言)
有一长方形,长为 343720343720 单位长度,宽为 233333233333 单位长度。在其内部左上角顶点有一小球 (无视其体积),其初速度如图所示且保持运动速率不变,分解到长宽两个方向上的速率之比为 dx:dy15:17dx:dy15:17。小球碰到长方形的…...
Redis底层数据结构?编码与底层数据结构的映射?
Redis底层数据结构 一、简单动态字符串(SDS) 结构: struct sdshdr {int len; // 已使用字节长度 int free; // 未使用字节长度 char buf[]; // 字节数组(兼容C字符串) };特点: 二进制安全&#…...
linux环境下的硬盘分区格式化工具介绍 fdisk,gdisk,parted,cfdisk,cgdisk,sfdisk,gparted 笔记250407
linux环境下的硬盘分区格式化工具介绍 fdisk,gdisk,parted,cfdisk,cgdisk,sfdisk,gparted 笔记250407 以下是 Linux 系统中常用的 硬盘分区与格式化工具,涵盖命令行和图形界面工具,按功能分类整理: 一、分区管理工具 1. 命令行工具 工具功能…...
HarmonyOS-ArkUI Ability进阶系列-UIAbility与各类Context
UIAbility及相关类关系 一个模块编译的时候会出一个HAP包, 每一个HAP包在运行时都对应一个AbilityStage。 AbilityStage持有一个AbilityStageContext一个APP, 有时候会有很多个HAP包, 至少一个。 一个APP运行时,对应的是我们的App…...
