Redis底层核心对象RedisObject源码分析

文章目录

    • 1. redis底层数据结构
    • 2. 插入KV底层源码流程分析

1. redis底层数据结构

redis 6数据结构和底层数据结构的关系
在这里插入图片描述

String类型本质是SDS动态字符串,即redis层面的数据结构底层会有对应的数据结构实现,上面是redis 6之前的实现

redis 7数据结构和底层数据结构的关系

在这里插入图片描述

Redis 7和6之间的关系就是压缩列表不见了,然后引入了listpack这个数据结构(紧凑列表)。

redis 7新特性:

在这里插入图片描述
在这里插入图片描述

2. 插入KV底层源码流程分析

例如我们插入下面一对kv

set hello word

在这里插入图片描述

可以看到hello的类型是String

我们看一下key的底层编码

object encoding hello

在这里插入图片描述

为什么key是String类型,底层却在操作一个什么embstr类型?

set hello word,因为redis是kv键值对的数据库,每个键值对都会有一个dictEntry,里面指向了key和value的指针,next指向下一个dictEntry,key是字符串,但是redis没有直接使用C的字符数组来表示字符串,而是存储在redis自定义SDS中。value既不是直接作为字符串存储,也不是存储在SDS中,而是存储在redisObject中,实际上常用五种数据类型的任意一种,都是通过redisObject来存储的。

在这里插入图片描述

struct redisObject {//对象的类型unsigned type:4;//具体的数据结构unsigned encoding:4;//最近最少使用,用于内存淘汰unsigned lru:LRU_BITS; /* LRU time (relative to global lru_clock) or* LFU data (least significant 8 bits frequency* and most significant 16 bits access time). */* ////引用计数,用于c的垃圾回收int refcount;//真正指向value的实际数据结构void *ptr;
};

为了便于操作,redis采用了redisObject结构来统一五种不同的数据类型,这样所有的数据类型都可以以相同的形式在函数之间传递,而不使用特定的类型结构。同时,为了识别不同的数据类型,redisObject定义了type和encoding字段对不同的数据类型加以区别。简单来说,redisObject就是String、hash、list、set、zset的父类(但是c中没有类的说法,因为它是面向结构的编程语言),可以在函数间隐藏具体的类型信息,所以作者抽象redisObject结构来达到目的。

在这里插入图片描述

type:表示value具体的数据类型

encoding:表示该类型的物理编码,同一种数据结构就有多种不同的编码,如上面的embstr就是字符串的一种编码方式(String的编码方式有3种:int、emstr和raw)

#define OBJ_ENCODING_RAW 0     /* Raw representation */
#define OBJ_ENCODING_INT 1     /* Encoded as integer */
#define OBJ_ENCODING_HT 2      /* Encoded as hash table */
#define OBJ_ENCODING_ZIPMAP 3  /* No longer used: old hash encoding. */
#define OBJ_ENCODING_LINKEDLIST 4 /* No longer used: old list encoding. */
#define OBJ_ENCODING_ZIPLIST 5 /* No longer used: old list/hash/zset encoding. */
#define OBJ_ENCODING_INTSET 6  /* Encoded as intset */
#define OBJ_ENCODING_SKIPLIST 7  /* Encoded as skiplist */
#define OBJ_ENCODING_EMBSTR 8  /* Embedded sds string encoding */
#define OBJ_ENCODING_QUICKLIST 9 /* Encoded as linked list of listpacks */
#define OBJ_ENCODING_STREAM 10 /* Encoded as a radix tree of listpacks */
#define OBJ_ENCODING_LISTPACK 11 /* Encoded as a listpack */

lru:表示当内存超限时采用lru算法清除内存中的对象

refcount:表示对象的引用计数(有点类似JVM中垃圾收集的引用计数法)

ptr:指向value真正底层的数据结构

  • 各个类型的数据结构和编码映射的定义
// object.c文件中
char *strEncoding(int encoding) {switch(encoding) {case OBJ_ENCODING_RAW: return "raw";case OBJ_ENCODING_INT: return "int";case OBJ_ENCODING_HT: return "hashtable";case OBJ_ENCODING_QUICKLIST: return "quicklist";case OBJ_ENCODING_LISTPACK: return "listpack";case OBJ_ENCODING_INTSET: return "intset";case OBJ_ENCODING_SKIPLIST: return "skiplist";case OBJ_ENCODING_EMBSTR: return "embstr";case OBJ_ENCODING_STREAM: return "stream";default: return "unknown";}
}

我们再看一个set hello word,然后我们使用Debug Object key,这是redis的一个调试命令,它不应该被客户端使用。我们直接使用回报错

在这里插入图片描述
我们需要修改配置开启本地调试,可以使用修改redis的配置文件来设置这个选项:

在这里插入图片描述

在这里插入图片描述

  • value at:内存地址
  • refcount:引用次数
  • encoding:物理编码
  • serializedlength:序列化后的长度(注意这里的长度是序列化后的长度,保存为rdb文件时使用了该算法,不是真正存储在内存中的大小),会对字符串做一些可能的压缩以便底层优化
  • lru:记录最近使用的时间戳
  • lru_seconds_idle:空闲时间

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

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

相关文章

关于Nginx服务器配置及性能优化的20道高级面试题

1. 请解释Nginx服务器的工作原理。 Nginx服务器以高性能、稳定性和低资源消耗而著称,其工作原理主要涉及其多进程架构、反向代理功能以及模块组成。具体来看: 多进程架构:Nginx采用一个master进程和多个worker进程的架构。Master进程主要负…

Linux应用程序对异步通知的处理

一. 简介 前面几篇文章学习了 Linux异步通知机制,以及Linux驱动对异步通知部分涉及的内容。文章地址如下: Linux异步通知简介-CSDN博客 Linux驱动中的异步通知机制:信号处理方法-CSDN博客 本文来学习Linux应用程序对异步通知的处理。 二…

[MYSQL数据库]--表的增删查改和字段类型

前言 作者:小蜗牛向前冲 名言:我可以接受失败,但我不能接受放弃 如果觉的博主的文章还不错的话,还请点赞,收藏,关注👀支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、表的增…

高数立体几何笔记

上个学期立体几何章节的一点笔记,很潦草,但重点内容基本都有复习到 Page1:介绍了向量的模、夹角、单位向量、投影投影向量、方向角、点乘、叉乘、混合积的基本运算和性质Page2: 回顾了高中所学的平面直线的多种表示方法以及距离的计算方法&…

Go语言必知必会100问题-21 切片初始化方法及最佳实践

切片初始化 切片使用内置的make函数进行初始化,初始化需要提供两个参数,分别是切片的长度和容量(可选)。如果这两个参数设置的不合理,会使得后续对切片的操作非常低效。下面来看看怎么设置这两个参数是合适的。 假设我们要实现一个转换函数…

【工作实践-07】uniapp关于单位rpx坑

问题:在浏览器页面退出登录按钮上“退出登录”字样消失,而在手机端页面正常;通过查看浏览器页面的HTML代码,发现有“退出登录”这几个字,只不过由于样式问题,这几个字被挤到看不见了。 样式代码中有一行为&#xff1a…

Midjourney绘图欣赏系列(十一)

Midjourney介绍 Midjourney 是生成式人工智能的一个很好的例子,它根据文本提示创建图像。它与 Dall-E 和 Stable Diffusion 一起成为最流行的 AI 艺术创作工具之一。与竞争对手不同,Midjourney 是自筹资金且闭源的,因此确切了解其幕后内容尚不…

Linux常见指令总结

ls:显示当前目录下文件列表 常用的命令行参数: -l 显示更多的文件属性 -a 显示所有的文件/目录(包括隐藏的) -d 只显示目录 ps:参数可以叠加使用。 例如:ls -la 显示所有文件…

wait 和 notify方法

目录 1.1 wait()方法 wait 做的事情: wait 结束等待的条件: 1.2 notify()方法 1.3notifyAll方法 1.4wait()和sleep()对比 由于线程之间是抢占式执行的, 因此线程之间执行的先后顺序难以预知. 但是实际开发中有时候我们希望合理的协调多个线程之间的执行先后顺序. 完成这个协调…

利用matlab处理netcdf文件中time变量的格式转换问题

我们通常读取的科研数据具有时间维度,因而通常用于数据运算的时候,最常使用的是(2003.567)等双精度格式的年份。本专栏提供了一个将nc文件中提供的时间变量的年-月-日转成-年。但是nc文件提供的time变量通常是以下两种格式&#x…

C语言入门学习 --- 2.分支与循环语句

第二章分支与循环语句 2.分支与循环语句 分支语句 ifswitch 循环语句 whiledo whilefor goto语句 2.1分支语句(选择结构) 2.1.1 什么是选择? 例:如果你努力,也许会成功。如果你不努力,你永远不会成功。这就是选择 2.1.2 if语句…

重学SpringBoot3-日志Logging

更多SpringBoot3内容请关注我的专栏:《SpringBoot3》 期待您的点赞👍收藏⭐评论✍ 重学SpringBoot3-日志Logging 引言默认日志配置日志门面如何实现默认配置 自定义日志配置日志级别日志分组日志格式日志输出自定义 Logback 配置切换日志框架 日志使用方…

数据结构 - 链表 (四)

这篇博客将介绍带头循环的双向链表,实现链表的头部插入/删除,尾部插入/删除,查找,以及任意位置的插入删除。 1.结构 带头循环的双向链表的结构如下图所示,一个结点内部包含数据,以及分别指向前一个以及后…

LabVIEW质谱仪开发与升级

LabVIEW质谱仪开发与升级 随着科技的发展和实验要求的提高,传统基于VB的质谱仪系统已经无法满足当前的高精度和高效率需求。这些系统通常存在着功能不全和操作复杂的问题,影响了科研和生产的进度。为了解决这些问题,开发了一套基于LabVIEW开…

`PF_NETLINK` 是用于与内核通信的Socket族之一

PF_NETLINK 是用于与内核通信的Socket族之一。在Linux系统中,Netlink是一种用于内核与用户空间进程之间通信的机制,而PF_NETLINK Socket族则用于创建与Netlink通信相关的Socket。通过Netlink Socket,用户空间程序可以与内核进行双向通信&…

16. C++标准库

C标准库兼容C语言标准函数库,可以在C标准库中直接使用C语言标准函数库文件,同时C标准库增加了自己的源代码文件,新增文件使用C编写,多数代码放在std命名空间中,所以连接C标准库文件后还需要 using namespace std;。 【…

Python算法题集_搜索旋转排序数组

Python算法题集_搜索旋转排序数组 题33:搜索旋转排序数组1. 示例说明2. 题目解析- 题意分解- 优化思路- 测量工具 3. 代码展开1) 标准求解【二分法区间判断】2) 改进版一【二分找分界标准二分法】3) 改进版二【递归实现二分法】 4. 最优算法5. 相关资源 本文为Pytho…

Qt使用Q_DECLARE_INTERFACE Q_INTERFACES宏实现接口类使用qobject_cast进行类型转换

在写抽象类或者接口的时候&#xff0c;肯定是不能继承QObject的 但是又想使用qobject_cast进行类型转换&#xff0c;使用以下办法就能实现 #ifndef FACTORYINTERFACE_H__ #define FACTORYINTERFACE_H__ #include <QObject> class FactoryInterface{ public:FactoryInterf…

【C++进阶】C++多态概念详解

C多态概念详解 一&#xff0c;多态概念二&#xff0c;多态的定义2.1 多态构成的条件2.2 什么是虚函数2.3 虚函数的重写2.3.1 虚函数重写的特例2.3.2 override和final 2.4 重载和重写&#xff08;覆盖&#xff09;和重定义&#xff08;隐藏&#xff09;的区别 三&#xff0c;抽象…

salesforce Multi-Line Layout中公式字段不能显示吗

在Salesforce的多行布局中&#xff0c;公式字段是可以显示的。但是&#xff0c;有一些限制和注意事项&#xff1a; 默认情况下&#xff0c;公式字段可能不会显示&#xff1a; 公式字段在多行布局中默认是不包含的。您可能需要手动编辑多行布局&#xff0c;将公式字段添加到布局…