Redis客户端命令到服务器底层对象机制的完整流程?什么是Redis对象机制?为什么要有Redis对象机制?

Redis客户端命令到服务器底层对象机制的完整流程

复制代码
客户端 → RESP协议封装 → TCP传输 → 服务器事件循环 → 协议解析 → 命令表查找 → 对象机制 → 动态编码 → 数据结构操作 → 响应编码 → 网络回传 

Redis客户端命令到服务器底层对象机制的完整流程可分为协议封装、命令解析、多态执行、内存操作四个阶段。以下是结合RESP协议规范、对象机制和命令处理源码的详细流程分析:

一、客户端命令发送阶段

  1. 命令序列化

    客户端将用户输入的指令(如HSET user:1 name "Alice")按RESP协议编码为二进制格式。例如:

    bash 复制代码
    *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表示后续字符串长度。

  2. 网络传输

    通过TCP套接字将序列化后的数据发送至Redis服务器。客户端可能使用连接池管理多个连接,支持超时重连机制。

二、服务器协议解析阶段

  1. 读取输入缓冲区

    服务器通过I/O多路复用检测到可读事件后,将协议数据存入客户端状态client的输入缓冲区querybuf,最大限制1GB(超限关闭连接)。

  2. 参数解析

    按RESP协议解码,分割出命令参数存入argv数组。例如解析出["HSET","user:1","name","Alice"],参数个数存入argc

  3. 命令表查找

    根据argv[0](命令名)在全局命令字典commandTable中查找对应的redisCommand结构,验证权限、参数个数等。例如HSET对应实现函数hsetCommand

三、对象机制与多态执行阶段

  1. 键对象检索

    在数据库字典中查找键user:1对应的redisObject

    c 复制代码
    robj *keyobj = lookupKeyWrite(c->db, c->argv[1]);

    若不存在则创建新对象,类型由命令决定(此处为OBJ_HASH)。

  2. 类型与编码检查

    • 验证redisObject.type是否匹配命令要求(如哈希命令需OBJ_HASH类型)。
    • 根据当前redisObject.encoding选择底层数据结构操作函数(如ziplisthashtable)。
  3. 动态编码转换

    若数据特征触发阈值(如哈希元素超过hash-max-ziplist-entries),执行编码转换:

    c 复制代码
    if (hashTypeLength(o) > server.hash_max_ziplist_entries)
        hashTypeConvert(o, OBJ_ENCODING_HT);

    此过程涉及数据迁移和旧结构内存释放。

  4. 执行底层操作

    调用编码对应的函数操作数据结构。例如哈希表使用dictReplace插入键值对:

    c 复制代码
    dictEntry *de = dictAddRaw(dict, field, &existing);
    dictSetVal(dict, de, value);

四、响应返回与内存管理

  1. 结果写入输出缓冲区

    操作结果按RESP协议编码后存入客户端bufreply链表。例如返回":1\r\n"表示成功插入1个元素。

  2. 内存回收与共享

    • 通过refcount引用计数自动回收无引用对象。
    • 小整数等共享对象直接复用,减少内存分配。
  3. 数据同步

    若开启AOF或主从复制,将命令追加到AOF缓冲区或发送给从节点。

什么是Redis对象机制?为什么要有Redis对象机制?

Redis对象机制是其实现多态数据结构和高效内存管理的核心设计,通过统一的对象模型(redisObject)封装了所有数据类型,对外提供一致的接口,同时支持多种底层编码的动态切换。

一、为什么需要对象机制?

  1. 统一接口与多态支持

    • Redis支持5种基础数据类型(字符串、列表、哈希、集合、有序集合),每种类型可能有多种底层实现(如哈希表可用ziplisthashtable)。对象机制通过redisObject统一封装,使得命令处理时无需关心具体实现,只需根据类型和编码调用对应函数,实现多态性。
  2. 灵活优化内存与性能

    • 根据数据特征动态选择最优编码。例如:
      • 小规模哈希使用ziplist节省内存,大规模时切换为hashtable提升操作效率。
      • 字符串根据长度选择intembstrraw编码,减少内存碎片。
  3. 内存管理与共享对象

    • 通过引用计数(refcount)自动回收无引用对象,避免内存泄漏。
    • 预创建常用共享对象(如0-9999的整数),减少重复分配,节省内存。
  4. 类型检查与安全

    • 执行命令前检查redisObjecttype属性,防止对错误类型执行操作(如对字符串执行列表命令)。

二、对象机制的核心:redisObject结构

c 复制代码
typedef struct redisObject {
    unsigned type:4;      // 数据类型(如OBJ_STRING)
    unsigned encoding:4;  // 编码方式(如OBJ_ENCODING_INT)
    unsigned lru:24;      // 最近访问时间(用于LRU淘汰)
    int refcount;         // 引用计数 
    void *ptr;            // 指向实际数据结构的指针 
} robj;
  1. 关键属性解析

    • type(4位):标识数据类型,包括OBJ_STRINGOBJ_LIST等5种。
    • encoding(4位):决定底层数据结构,如ziplistskiplist等11种编码方式。
    • ptr:指向具体数据结构(如SDS字符串、quicklist列表)的内存地址。
    • refcount:引用计数,为0时触发内存回收;>1时表示共享对象。
    • lru:记录对象最后一次被访问的时间,用于内存淘汰策略(如maxmemory配置)。
  2. 编码方式与底层结构

    数据类型 可能的编码方式 适用场景
    字符串(String) intembstrraw 整数值、短字符串(≤44B)、长字符串
    列表(List) quicklist 所有列表操作
    哈希(Hash) ziplisthashtable 小哈希(字段少且值小)、大哈希
    集合(Set) intsethashtable 整数集合、混合类型集合
    有序集合(ZSet) ziplistskiplist+dict 小规模有序集合、大规模需范围查询

三、对象机制的工作流程

  1. 创建对象

    • 根据数据类型和内容选择初始编码,如字符串若为整数则用int编码。
  2. 执行命令

    • 检查type是否匹配命令要求(如LPOPOBJ_LIST类型)。
    • 根据encoding选择底层数据结构的处理函数(如ziplisthashtable的插入逻辑)。
  3. 动态编码转换

    • 数据变化触发编码切换。例如哈希字段数超过hash-max-ziplist-entries时,从ziplist转为hashtable
  4. 内存回收与共享

    • 引用计数归零时,释放ptr指向的数据结构内存。
    • 预创建的共享对象(如小整数)被多个键共享,减少重复创建。

四、示例:字符串对象的多编码实现

  • int编码:存储整数值(如SET key 100),直接复用ptr指针存储数值。
  • embstr编码:短字符串(≤44字节)连续存储redisObjectSDS,减少内存分配次数。
  • raw编码:长字符串使用独立分配的SDS结构,支持动态扩容。
相关推荐
gsfl2 小时前
Redis 缓存
数据库·redis·缓存
青草地溪水旁5 小时前
EPOLLONESHOT事件类型和ET模式有什么区别?
服务器·网络·c++·epoll
林开落L5 小时前
Linux 进程信号:从进阶特性到实战应用(下)
linux·运维·服务器·进程信号
初听于你6 小时前
缓存技术揭秘
java·运维·服务器·开发语言·spring·缓存
云手机掌柜7 小时前
技术深度解析:指纹云手机如何通过设备指纹隔离技术重塑多账号安全管理
大数据·服务器·安全·智能手机·矩阵·云计算
恒悦sunsite8 小时前
Ubuntu之apt安装ClickHouse数据库
数据库·clickhouse·ubuntu·列式存储·8123
奥尔特星云大使9 小时前
MySQL 慢查询日志slow query log
android·数据库·mysql·adb·慢日志·slow query log
来自宇宙的曹先生9 小时前
MySQL 存储引擎 API
数据库·mysql
间彧9 小时前
MySQL Performance Schema详解与实战应用
数据库
口嗨农民工9 小时前
win10默认搜索APP和window设置控制命板
linux·服务器·c语言