[微服务]redis数据结构

embedded/2025/1/15 5:43:29/

介绍

我们常用的Redis数据类型有5种,分别是:

  • String
  • List
  • Set
  • SortedSet
  • Hash

还有一些高级数据类型,比如Bitmap、HyperLogLog、GEO等,其底层都是基于上述5种基本数据类型。因此在Redis的源码中,其实只有5种数据类型。

RedisObject

不管是任何一种数据类型,最终都会封装为RedisObject格式,它是一种结构体,C语言中的一种结构,可以理解为Java中的类。

结构大概是这样的:

可以看到整个结构体中并不包含真实的数据,仅仅是对象头信息,内存占用的大小为4+4+24+32+64 = 128bit

也就是16字节,然后指针ptr指针指向的才是真实数据存储的内存地址。所以RedisObject的内存开销是很大的。

属性中的encoding就是当前对象底层采用的数据结构编码方式

Redis中会根据存储的数据类型不同,选择不同的编码方式,共包含12种不同类型:

Redis中会根据存储的数据类型不同,选择不同的编码方式。每种数据类型的使用的编码方式如下

SkipList

SkipList(跳表)首先是链表,但与传统链表相比有几点差异:

  • 元素按照升序排列存储
  • 节点可能包含多个指针,指针跨度不同。

传统链表只有指向前后元素的指针,因此只能顺序依次访问。如果查找的元素在链表中间,查询的效率会比较低。而SkipList则不同,它内部包含跨度不同的多级指针,可以让我们跳跃查找链表中间的元素,效率非常高。

其结构如图:

我们可以看到1号元素就有指向3、5、10的多个指针,查询时就可以跳跃查找。例如我们要找大小为14的元素,查找的流程是这样的:

  • 首先找元素1节点最高级指针,也就是4级指针,起始元素大小为1,指针跨度为9,可以判断出目标元素大小为10。由于14比10大,肯定要从10这个元素向下接着找。
  • 找到10这个元素,发现10这个元素的最高级指针跨度为5,判断出目标元素大小为15,大于14,需要判断下级指针
  • 10这个元素的2级指针跨度为3,判断出目标元素为13,小于14,因此要基于元素13接着找
  • 13这个元素最高级级指针跨度为2,判断出目标元素为15,比14大,需要判断下级指针。
  • 13的下级指针跨度为1,因此目标元素是14,刚好于目标一致,找到。

这种多级指针的查询方式就避免了传统链表的逐个遍历导致的查询效率下降问题。在对有序数据做随机查询和排序时效率非常高。

跳表的结构体如下:

typedef struct zskiplist {// 头尾节点指针struct zskiplistNode *header, *tail;// 节点数量unsigned long length;// 最大的索引层级int level;
} zskiplist;

可以看到SkipList主要属性是header和tail,也就是头尾指针,因此它是支持双向遍历的。

跳表中节点的结构体如下:

typedef struct zskiplistNode {sds ele; // 节点存储的字符串double score;// 节点分数,排序、查找用struct zskiplistNode *backward; // 前一个节点指针struct zskiplistLevel {struct zskiplistNode *forward; // 下一个节点指针unsigned long span; // 索引跨度} level[]; // 多级索引数组
} zskiplistNode;

每个节点中都包含ele和score两个属性,其中score是得分,也就是节点排序的依据。ele则是节点存储的字符串数据指针。

其内存结构如下:

SkipList的特点:

  1. 跳跃表是一个有序的双向鲢表
  2. 每个节点都可以包含多层指针,层数是1到32之间的随机数不同层指针到下一个节点的跨度不同,层级越高,跨度越大增删改查效率与红黑树基本一致,实现却更简单。
  3. 但空间复杂度更高

SortedSet

面试题:

Redis的SortedSet底层的数据结构是怎样的?

  1. 首先Sortedset需要能存储score和member值,而且要快捷的根据member查询score,因此底层有一个哈希表,以member为键,以score为value
  2. 其次Sortedset还需要能根据score排序,因此底层还维护了一个跳表。
  3. 当需要根据member查询score时,就去哈希表中查询
  4. 当需要根据score排序查询时,则基于跳表查询

更多的细节

  1. SortedSet是有序集合,底层的存储的每个数据都包含element和score两个值。score是得分,element则是字符串值。SortedSet会根据每个element的score值排序,形成有序集合。

它支持的操作很多,比如:

  • 根据element查询score值
  • 按照score值升序或降序查询element
  1. 要实现根据element查询对应的score值,就必须实现element与score之间的键值映射。SortedSet底层是基于HashTable来实现的。
  2. 要实现对score值排序,并且查询效率还高,就需要有一种高效的有序数据结构,SortedSet是基于跳表实现的。
  3. 因为SortedSet底层需要用到两种数据结构,对内存占用比较高。因此Redis底层会对SortedSet中的元素大小做判断。如果元素大小小于128每个元素都小于64字节,SortedSet底层会采用ZipList,也就是压缩列表来代替HashTableSkipList
  4. 不过,ZipList存在连锁更新问题,因此而在Redis7.0版本以后,ZipList又被替换为Listpack(紧凑列表)。

Redis源码中zset,也就是SortedSet的结构体如下:

typedef struct zset {dict *dict; // dict,底层就是HashTablezskiplist *zsl; // 跳表
} zset;

其内存结构如图:


http://www.ppmy.cn/embedded/154028.html

相关文章

深度学习与通信技术的融合:未来的创新与机遇

目录 引言:深度学习与通信技术的结合深度学习在通信领域的应用深度学习与通信技术融合的前景与挑战博雅智信的辅导模式学术诚信声明 引言:深度学习与通信技术的结合 随着信息技术的飞速发展,深度学习在多个领域取得了显著进展。通信技术作为…

Redis:持久化机制

Redis 的持久化机制是确保数据在服务器重启后不会丢失的关键功能。它提供了两种主要的持久化方式:RDB(Redis Database Backup)快照和 AOF(Append Only File)日志记录。 1. RDB 快照(Redis Database Backup) 简介 概念:RDB 是 Redis 在指定的时间点将内存中的所有数据…

《计算机网络》课后探研题书面报告_网际校验和算法

网际校验和算法 摘 要 本文旨在研究和实现网际校验和(Internet Checksum)算法。通过阅读《RFC 1071》文档理解该算法的工作原理,并使用编程语言实现网际校验和的计算过程。本项目将对不同类型的网络报文(包括ICMP、TCP、UDP等&a…

CSS语言的语法糖

CSS语言的语法糖 CSS(层叠样式表)是现代网页设计中一个不可或缺的工具,它允许开发者通过一套简洁而强大的语法来控制网页的布局、样式和外观。随着Web技术的发展,CSS的功能不断增强,出现了许多新的特性和用法&#xf…

【Debug】django.db.utils.OperationalError: (1040, ‘Too many connections‘)

报错: django.db.utils.OperationalError: (1040, ‘Too many connections‘) 排查 可能是Mysql的连接数量超过了允许的最大连接数量; 查看Mysql允许最大连接数量: -- 查看允许连接的最大数量 SHOW VARIABLES LIKE %max_connections%;-- 查…

Vue.js 条件渲染和列表渲染

Vue.js 条件渲染和列表渲染 今天我们来聊聊 Vue.js 的两个基础功能:条件渲染 和 列表渲染。这是写前端页面时必备的技能,掌握好它们,你就能轻松应对页面上的动态显示需求。 一、什么是条件渲染? 所谓条件渲染,就是根…

SOLID原则学习,开闭原则(Open Closed Principle, OCP)

文章目录 1. 定义2. 开闭原则的详细解释3. 实现开闭原则的方法4. 总结 1. 定义 开闭原则(Open-Closed Principle,OCP)是面向对象设计中的五大原则(SOLID)之一,由Bertrand Meyer提出。开闭原则的核心思想是…

【深度学习】核心概念-特征学习(Feature Learning)

特征学习(Feature Learning) 特征学习是机器学习和深度学习的核心概念之一,其目的是通过算法自动从数据中学习有效的特征表示,而不是依赖人工设计特征。特征学习的目标是让模型从原始数据中提取和表示有意义的信息,以…