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:空闲时间

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Terrace联合创始人兼CEO Jesse Beller确认出席Hack.Summit() 2024区块链开发者大会

在科技创新的浪潮中,区块链技术以其独特的去中心化、透明性和安全性,正逐渐成为引领未来发展的重要力量。在这样的背景下,备受瞩目的Hack.Summit() 2024区块链开发者大会即将于4月9日至10日在香港数码港盛大举行。本次大会的亮点之一&#xf…

程序员春招攻略:金三银四的求职智慧与机遇

文章目录 程序员的金三银四求职宝典方向一:面试技巧分享自我介绍的艺术技术问题的回答策略团队协作经验的有效展示压力面试的应对结束语的巧妙运用 方向二:面试题解析数据结构与算法题系统设计题编程题 方向三:公司文化解读腾讯(T…

软件设计不是CRUD(14):低耦合模块设计理论——行为抽象与设计模式(上)

是不是看到“设计模式”四个字,各位读者就觉得后续内容要开始讲一些假大空的内容了?各位读者是不是有这样的感受,就是单纯讲设计模式的内容,网络上能找到很多资料,但是看过这些资料后读者很难将设计模式运用到实际的工作中。甚至出现了一种声音:设计模式是没有用的,应用…

机试:最大子序列的和

问题描述: 算法思想: 若第(i-1)个序列的小于0,则第i个序列的最大值为nums[i]; 若第(i-1)个序列的小于0,则第i个序列的最大值为max(i-1) nums[i]; 如果max(i-1)>0,max(i)max(i-1)Nums(i) 如果max(i-1)<0,max(i)Nums(i)代码示例: #include <bits/stdc.h> //该算法…

ULTRAL SCALE FPGA TRANSCEIVER速率

CPLL支持2-6.25速率 QPLL支持速率 实际使用CPLL最高可以超过这个&#xff0c;QPLL最低也可以低于这个&#xff0c;xilinx留的阈量还是比较大。

蓝桥杯真题讲解:子矩阵(二维滑动窗口)

蓝桥杯真题讲解&#xff1a;子矩阵&#xff08;二维滑动窗口&#xff09; 一、视频讲解二、正解代码 一、视频讲解 蓝桥杯真题讲解&#xff1a;子矩阵&#xff08;二维滑动窗口&#xff09; 二、正解代码 //二维单调队列 #include<bits/stdc.h> #define endl \n #def…

C# 视频转图片

在 C# 中将视频转换为图像可以使用 FFmpeg 库。下面是一个示例代码来完成这个任务&#xff1a; using System; using System.Diagnostics;class Program {static void Main(string[] args){string inputFile "input_video.mp4"; // 输入的视频文件路径string outpu…

2024.3.12

1. 要求&#xff1a;自己封装一个矩形类(Rect)&#xff0c;拥有私有属性:宽度(width)、高度(height)&#xff0c; 定义公有成员函数: 初始化函数:void init(int w, int h) 更改宽度的函数:set_w(int w) 更改高度的函数:set_h(int h) 输出该矩形的周长和面积函数:void sho…

在VMvare中虚拟机安装centos7和初始设置

下载镜像 阿里云的镜像站&#xff1a;https://mirrors.aliyun.com/centos/7/isos/x86_64/ 创建虚拟机过程 虚拟机创建过程比较简单&#xff0c;以下在VMvare16中进行安装 点击左上角&#xff0c;文件-新建虚拟机&#xff1a; 选择典型 选择刚刚下载好的镜像 输入虚拟机…

Python笔记:函数

Python函数定义规则&#xff1a; 函数代码块以def关键词开头&#xff0c;后接函数标识符名称和圆括号()。任何传入参数和自变量必须放在圆括号中间&#xff0c;圆括号之间可以用于定义参数。return [表达式] 结束函数&#xff0c;选择性地返回一个值给调用方&#xff0c;不带表…

【问题解决】VMWare虚拟机主IP地址:网络信息不可用

在今天想用man命令查看相关函数的帮助时&#xff0c;突然发现自己的XShell连接不上虚拟机&#xff0c;通过在终端使用ifconfig命令也只查看得到本地回环&#xff0c;虽然最近常遇到这个问题&#xff0c;但一般通过重启虚拟机就能得以解决。 不过这次重启也不奏效了&#xff0c…

《vtk9 book》 官方web版 第3章 - 计算机图形基础 (3 / 5)

3.8 演员几何 我们已经看到了光照属性如何控制演员的外观&#xff0c;以及相机如何结合变换矩阵将演员投影到图像平面上。剩下的是定义演员的几何形状&#xff0c;以及如何将其定位在世界坐标系中。 建模 计算机图形学研究中的一个重要主题是建模或表示物体的几何形状。…

初阶数据结构之---堆的应用(堆排序和topk问题)

引言 上篇博客讲到了堆是什么&#xff0c;以及堆的基本创建和实现&#xff0c;这次我们再来对堆这个数据结构更进一步的深入&#xff0c;将讲到的内容包括&#xff1a;向下调整建堆&#xff0c;建堆的复杂度计算&#xff0c;堆排序和topk问题。话不多说&#xff0c;开启我们今…

Matlab 2022a 安装教程 附安装包

链接&#xff1a;https://pan.baidu.com/s/10Aotpk-oDqNULXvzNWEZ9w?pwdff12 提取码&#xff1a;ff12 安装教程 1.鼠标右击【MatlabR2022a(64bit)】压缩包选择【解压到 MatlabR2022a(64bit)】。 2.打开解压后的文件夹&#xff0c;鼠标右击【R2022a window】选择【装载】。…

成都爱尔林江院长解析巩膜镜是什么?它适合哪些人群

巩膜镜&#xff0c;全称为硬性透氧性巩膜接触镜&#xff0c;它有着特殊设计&#xff0c;大直径镜片像桥梁一样呈拱形覆盖角膜及角巩膜缘&#xff0c;从角膜上方横跨而过完全无接触、无任何机械性摩擦&#xff0c;最终贴合于巩膜。 巩膜镜的作用原理 光学成像&#xff1a; 配戴…

苍穹外卖中新增员工的功能是如何实现的?再复习下项目结构

一、Common、Pojo、Server分别都是干啥的&#xff1f; 在一个典型的Java应用程序中&#xff0c;通常会使用模块化的方式来组织代码&#xff0c;以提高代码的可维护性和可扩展性。常见的模块包括Common模块、POJO模块和Server模块&#xff0c;它们通常各自负责不同的功能。 Com…

rt-thread组件之audio组件(结合mp3player包使用)

前言 继上一篇RT-Thread组件之Audio框架i2s驱动的编写的编写&#xff0c;应用层使用rt-thread软件包里面的wavplayer组件以及 rt-thread组件之audio组件(结合wavplayer包使用)的文章本篇使用的是 mp3player软件包&#xff0c;与wavplayer设计框架基本上是一样的&#xff0c;只…

网络工程师——2024自学

一、怎样从零开始学习网络工程师 当今社会&#xff0c;人人离不开网络。整个IT互联网行业&#xff0c;最好入门的&#xff0c;网络工程师算是一个了。 什么是网络工程师呢&#xff0c;简单来说&#xff0c;就是互联网从设计、建设到运行和维护&#xff0c;都需要网络工程师来…

GIS瓦片3-WMTS瓦片

介绍 WMTS( Web Map Tile Service)切片地图Web服务&#xff08;OpenGIS Web Map Tile Service&#xff09;当前最新版本是1.0.0。WMTS标准定义了一些操作&#xff0c;这些操作允许用户访问切片地图。WMTS可能是OGC首个支持RESTful访问的服务标准。 WMTS提供了一种采用预定义图…

软考72-上午题-【面向对象技术2-UML】-UML中的图3

一、状态图 1-1、状态图的定义 状态图&#xff0c;展现了一个状态机&#xff0c;由&#xff1a;状态、转换、事件和活动组成&#xff0c;是系统的动态视图。 活动(动作) 可以在状态内执行也可以在状态转换(迁移) 时执行。 状态图强调&#xff1a;行为的事件顺序。 1-2、状态图…