当前位置: 首页 > article >正文

Redis学习笔记:数据结构

Redis的对象

Redis对象包含字符串对象、列表对象、哈希对象、集合对象和有序集合对象这五种类型的对象,针对不同的使用场景,为对象设置多种不同的数据结构实现,从而优化对象在不同场景下的使用效率。

除此之外,Redis的对象系统还实现了基于引用计数技术的内存回收机制,当程序不再使用某个对象的时候,这个对象所占用的内存就会被自动释放;另外,Redis还通过引用计数技术实现了对象共享机制,这一机制可以在适当的条件下,通过让多个数据库键共享同一个对象来节约内存。

实现

Redis中的每个对象都由一个redisObject结构表示,该结构中和保存数据有关的三个属性分别是type属性、encoding属性和ptr属性:

typedef struct redisObject{
    //  类型
    unsigned type:4;
    //  编码
    unsigned encoding:4;
    //  指向底层实现数据结构的指针
    void *ptr;
    //  ...
} robj;

type:对象的type属性记录了对象的类型,对于Redis数据库保存的键值对来说,键总是一个字符串对象,而值则可以是字符串对象、列表对象、哈希对象、集合对象或者有序集合对象的其中一种。

encoding:通过encoding属性来设定对象所使用的编码,而不是为特定类型的对象关联一种固定的编码,极大地提升了Redis的灵活性和效率,因为Redis可以根据不同的使用场景来为一个对象设置不同的编码,从而优化对象在某一场景下的效率。

ptr:对象的ptr指针指向对象的底层实现数据结构,而这些数据结构由对象的encoding属性决定。encoding属性记录了对象所使用的编码,也即是说这个对象使用了什么数据结构作为对象的底层实现。

以下是Redis对象不同编码时对应的数据结构,以及使用的场景:

对象

编码

数据结构

使用场景

字符串对象

int

long类型

long字符串

字符串对象

embstr

embstr类型的简单动态字符串(SDS)

32字节以内短字符串

字符串对象

raw

简单动态字符串(SDS)

大于32字节的字符串

列表对象

ziplist

压缩列表

列表项少且元素短

列表对象

linkedlist

双端链表

列表项多或元素长

哈希对象

ziplist

压缩列表

键值对少且元素短

哈希对象

hashtable

字典

键值对多或元素长

集合对象

intset

整数集合

元素都是整数且不超过512个

集合对象

hashtable

字典

元素不都是整数或超过512个

有序集合对象

ziplist

压缩列表

元素少且短

有序集合对象

skiplist

跳跃表+字典

元素多或长

embstr编码是专门用于保存短字符串的一种优化编码方式,这种编码和raw编码一样,都使用redisObject结构和sdshdr结构来表示字符串对象,但raw编码会调用两次内存分配函数来分别创建redisObject结构和sdshdr结构,而embstr编码则通过调用一次内存分配函数来分配一块连续的空间。由于内存中找到一块小的连续空间更容易,所有embstr编码更适合保存短字符串。embstr编码的优势是字符串对象的创建或清理时,内存分配或释放函数只需调用一次,而且连续的内存空间能够更好地利用缓存带来的优势。

可以通过TYPE命令查看键对应的值对象的类型,OBJECT ENCODING命令查看值对象的编码。

编码转换

随着对象增删改的操作的进行,当对象满足编码转换的条件时,Redis会进行编码转换,修改底层的数据结构,以适应新的环境,一般这种转换只会由优化类型转换为通用类型,而不会反过来,比如:int或embstr转换为raw,ziplist转换为linkedlist等。编码转换的条件可以通过参数修改。

内存回收

因为C语言并不具备自动内存回收功能,所以Redis在自己的对象系统中构建了一个引用计数技术实现的内存回收机制,通过这一机制,程序可以通过跟踪对象的引用计数信息,在适当的时候自动释放对象并进行内存回收。

对象共享

对象的引用计数属性还带有对象共享的作用。Redis会在初始化服务器时,创建值为0到9999的字符串对象,当需要用到这些对象时,会将对将被共享的值对象的引用计数加一,而不是新创建对象。Redis只会共享整数字符串对象,因为判断其它对象是否相等的成本更高。

对象的空转时长

对象的空转时长是指对象有多久没被访问,对象会记录自己的最后一次被访问的时间,这个时间可以用于计算对象的空转时间。服务器内存不足时空转时间较长的对像会被优先释放。

参考

《Redis设计与实现》


http://www.kler.cn/news/354505.html

相关文章:

  • Linux中安装 mongodb ,很详细
  • 2024年Python最受欢迎桑基图
  • 【LeetCode每日一题】——523.连续的子数组和
  • Qt入门教程:创建我的第一个小程序
  • 【YOLOv11】使用yolov11训练自己的数据集 /验证 /推理 /导出模型/ ONNX模型的使用
  • 【服装识别】Python+卷积神经网络算法+人工智能+深度学习+算法模型训练+Django网页界面+TensorFlow
  • JavaScript 第18章:安全性
  • 前端学习---(1)HTML
  • 如何使用C#实现Padim算法的训练和推理
  • 结构型-适配器模式
  • map和set的模拟实现
  • this指针—静态成员—单例模式
  • Spring AI Java程序员的AI之Spring AI(三)RAG实战
  • 排序算法上——插入,希尔,选择,堆排序
  • PTA L1系列题解(C语言)(L1_065 -- L1_072)
  • 无源雷达的直达波抑制--自适应信号算法
  • 软考-软件设计师(9)-C语言基础语法总结复习-针对简答题C语言代码填空
  • pnpm 和 npm
  • 如何分离人声和背景音乐?精准音频分离,提升你的作品质量
  • 前端容易错的题2