【Redis】深入理解 Redis 常用数据类型源码及底层实现(6.详解Set和ZSet数据结构)

 本文是深入理解 Redis 常用数据类型源码及底层实现系列的第6篇~前5篇可移步( ̄∇ ̄)/

【Redis】深入理解 Redis 常用数据类型源码及底层实现(1.结构与源码概述)-CSDN博客

【Redis】深入理解 Redis 常用数据类型源码及底层实现(2.版本区别+dictEntry & redisObject详解)-CSDN博客

【Redis】深入理解 Redis 常用数据类型源码及底层实现(3.详解String数据结构)-CSDN博客

【Redis】深入理解 Redis 常用数据类型源码及底层实现(4.详解Hash数据结构)_查看 hash-max-ziplist-entries 命令-CSDN博客

【Redis】深入理解 Redis 常用数据类型源码及底层实现(5.详解List数据结构)-CSDN博客


本文目录

Set数据结构

ZSet数据结构

t_zset.c

skiplist


Set数据结构

Set数据结构相对其他的数据结构比较简单,因为从Redis 6到Redis 7都没变~底层都是哈希表+整数数组,即使用intset和hashtable存储set的,如果元素都是整数类型就使用intset,如果不是则使用hashtable(数组+链表,key是元素值,value是null)

我们看下当执行命令sadd时,Redis底层到底做了些什么

在方法setTypeCreate()中,我们可以看到当集合元素都是LongLong类型并且集合元素个数<=server.set_max_intset_entries时,就采用intset的编码方式,不能同时满足上面两个条件的话则判断集合元素是否<=server.set_max_listpack_entrie,如果满足则采用listpack的编码方式(Redis 7),不满足则调用方法createSetObject()

方法createSetObject()中则采用hashtable的编码方式

上面源码中的参数server.set_max_intset_entries和server.set_max_listpack_entrie声明于文件server.h中

我们按照注释到redis.conf中就可以看到默认配置啦

我们总结下,对于Set数据结构,Redis 6 和Redis 7的底层都是intset和hashtable,当添加的数据是LongLong类型并且集合元素数<=512(默认配置,一般不作修改)时,就会使用intset的编码方式,反之则使用hashtable的编码方式。

ZSet数据结构

ZSet有两种编码格式,并且跟之前介绍的Hash数据结构类似,Redis 6是ziplist和skiptable而Redis 7是listpack和skiptable,我们先来看下不同版本基本配置信息的区别:

我们分别介绍下这些配置参数的含义:

  • zset-max-ziplist-entries:使用压缩列表保存数据时,zset有序集合中最大的元素个数(默认128)
  • zset-max-ziplist-value:使用压缩列表保存数据时,zset有序集合中单个元素的最大长度(默认64)
    • 单位byte:一个英文字母一个byte
  • zset-max-listpack-entries:使用紧凑列表保存数据时,zset有序集合中最大的元素个数(同样默认128)
  • zset-max-listpack-value:使用紧凑列表保存数据时,zset有序集合中单个元素的最大长度(默认64)

Redis 7兼容ziplist,当我们修改zset-max-listpack-entries和zset-max-listpack-value时,对应的zset-max-ziplist-entries和zset-max-ziplist-value也会被修改:

反之,当修改zset-max-ziplist-entries和zset-max-ziplist-value时,对应的zset-max-listpack-entries和zset-max-listpack-value也会被修改:

而且,当集合中的数据元素超过zset-max-ziplist-entries/zset-max-listpack-entries(不包括等于),或者元素长度大于zset-max-ziplist-value/zset-max-listpack-value时(不包括等于),底层会使用skiptable进行数据的存储,我们可以做下测试:

t_zset.c

接下来我们从源码层面看下,当执行刚才测试的添加元素的操作时,Redis底层执行的逻辑是什么。

打开t_zset.c文件(以Redis 7为示例),找到方法zsetAdd()

这里可以看到ZSet的两种编码方式OBJ_ENCODING_LISTPACK和OBJ_ENCODING_SKIPLIST

skiplist

为什么会出现skiplist跳表?

一个新的东西产生一般都是由问题导致的,原有的部分产生了问题,或者说痛点,就像原有的链表和数组,他们就各有优缺点(数组插入删除慢,链表遍历慢),于是在寻求解决方法的时候,skiplist跳表就应运而生。

其实skiplist是通过升维对链表进行优化的,就是我们非常熟悉的空间换时间(还记不记得ziplist是时间换空间?),既然链表遍历太慢,我们就给它加个(或者多个)索引,即“索引升级”,我们来看张图大家应该就明白了( ̄∇ ̄)/

总的来说,skiplist跳表是可以实现二分查找的有序链表(跳表 = 链表 + 多级索引),是一种以空间换取时间的结构。由于链表无法进行二分查找,提取出链表中关键节点作为索引(借鉴数据库索引的思想),先在关键节点上查找,再进入下层链表查找,提取多层关键节点,就形成了跳跃表,但是索引也要占据一定空间的(索引添加的越多,空间占用的越多,空间换时间)

搞定🎉~~~~~

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

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

相关文章

XSS_lab(level1-level5)

level1 直接输入页面没有发现输入框&#xff0c;观察url发现有传参 尝试修改传参为&#xff1a;<script>alert(1)</script> 过啦&#xff01; level2 页面中有输入框&#xff0c;尝试构建语句&#xff1a;<script>alert(1)</script>,传输后查看源代…

SDRPI烧写教程

首先准备好需要烧写的文件&#xff0c;一共有两个 .BIN 和 .elf文件 这里提供测试文件链接&#xff1a;https://pan.baidu.com/s/1P2cjCqOCyJg7hRhbqWue9Q 提取码&#xff1a;49jp 把SDRPI设置为JTAG模式 插上电源和JTAG线&#xff0c;这块板子的电源和UART使用的是同一个接…

Linux编程3.1 进程-进程的概念

前情提及&#xff1a; 程序和进程内核中的进程结构C程序启动过程进程终止方式非局部跳转进程资源限制进程创建、执行和终止进程类型进程状态进程组 进程的概念 进程&#xff1a;程序运行&#xff0c;由操作系统内核对该程序进行资源的分配 &#xff0c; 进程中&#xff0c;再…

LL-34/DO-213AC/MiniMELF/NSMC/DO-213AB封装

最近在找几个特殊的二极管封装&#xff0c;能查到资料太少了&#xff0c;如同大海捞针&#xff0c;好不容易找到了一些资料&#xff0c;把相关信息总结一下. 1、LL-34/DO-213AC/MiniMELF/SOD80这三个封装尺寸很接近 LL-34以c5345992为例 MiniMELF以c131658为例 2、NSMC这个封装…

复合数据类型(ch3)

将array依次执行以下操作 1.把列表中的元素升序排序。 2.删除列表中的最后一个元素。 3.把列表中第一个元素移动到列表尾部。 4.返回新列表。array [85,96,2,5,3,566,0,91,5234,5555,89,62,34] #*******请输入您的代码********# #***********begin************# def sort_and_…

python笔记_程序流程控制2

C&#xff0c;循环控制 1&#xff0c;for循环 功能&#xff1a;让代码循环运行 语法&#xff1a; for <变量> in <范围、序列>&#xff1a; <循环操作语句> 例 nums &#xff08;1,2,3,4&#xff09; <class list> for i in nums&#xff1a; print&…

express+mysql+vue,从零搭建一个商城管理系统9--添加商户

提示&#xff1a;学习express&#xff0c;搭建管理系统 文章目录 前言一、新建models/shop.js二、新建routes/shop.js三、修改routes下的index.js四、添加商户总结 前言 需求&#xff1a;主要学习express&#xff0c;所以先写service部分 一、新建models/shop.js models/shop.…

ApplicationContext容器

ApplicationContext容器 1.概述 ApplicationContext接口代表了一个Spring容器,它主要负责实例化、配置和组装bean。ApplicationContext接口间接继承了BeanFactory接口,相较于BeanFactory一些基本的容器功能,ApplicationContext接口是在BeanFactory接口基础上进行了扩展,增…

alfred自定义脚本执行报错,alfred task launch path not accessible问题解决

alfred自定义脚本执行报错,alfred task launch path not accessible 原因是mac升级后 /usr/lib/php 已经不存在了,可以改由zsh方式执行,如下图 右击打开目录 将执行脚本放入目录 code如下: <?phprequire ./Util.php; $qs $argv; $query $qs[1]; date_default_timezon…

CMDB对企业和IT管理员有什么用?

CMDB这个词在ITSM相关文档和IT管理领域经常遇到&#xff0c;但鲜有人能解释什么是CMDB&#xff0c;CMDB是怎么帮助到企业的&#xff1f;如果这些问题也困扰着您&#xff0c;那让我们来聊一聊CMDB&#xff0c;为什么需要CMDB&#xff0c;以及如何设置自己的CMDB。 1. 资源管理&a…

[ai笔记14] 周鸿祎的ai公开课笔记1

欢迎来到文思源想的ai空间&#xff0c;这是技术老兵重学ai以及成长思考的第14篇分享&#xff01; 本周二月的最后一周&#xff0c;并不是闲下来了&#xff0c;反而是开始进行一些更多的深入实践&#xff0c;关于gpt的主体架构、关于prompt&#xff0c;同时也看了不少书和直播&…

【Linux】基本指令(下)

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:Linux ⚙️操作环境:Xshell (操作系统:CentOS 7.9 64位) 日志 日志的概念: 网络设备、系统及服务程序等&#xff0c;在运作时都会产生一个叫log的事件记录&#xff1b;每一行日志都记载着日期、时间、使用者及动作等相关…

【大厂AI课学习笔记NO.60】(13)模型泛化性的评价

我们学习了过拟合和欠拟合&#xff0c;具体见我的文章&#xff1a;https://giszz.blog.csdn.net/article/details/136440338 那么今天&#xff0c;我们来学习模型泛化性的评价。 泛化性的问题&#xff0c;我们也讨论过了&#xff0c;那么如何评价模型的泛化性呢&#xff1f; …

中科数安|防止电脑文件资料外泄

#防止电脑文件资料泄漏# 中科数安提供了一系列解决方案来防止电脑文件资料外泄。 www.weaem.com 这些解决方案包括以下几个方面&#xff1a; 访问控制&#xff1a;实施严格的文件访问控制&#xff0c;确保只有授权的人员能够访问和编辑核心文件。使用身份验证和权限管理系统&a…

1255942-05-2,DBCO-C6-Amine,可以用于构建分子结构和生物活性分子

您好&#xff0c;欢迎来到新研之家 文章关键词&#xff1a;1255942-05-2&#xff0c;DBCO C6 NH2&#xff0c;DBCO-C6-Amine&#xff0c;二苯并环辛炔-C6-氨基 一、基本信息 【产品简介】&#xff1a;DBCO-C6-NH2 is a multifunctional molecule with excellent chemical re…

【C++精简版回顾】13.(重载1)运算符重载+,前置后置++

1.友元函数方式为类重载运算符 &#xff08;友元函数声明可以放在类任何地方&#xff09; 1.类 class MM { public:MM() {}MM(int grade,string name):grade(grade),name(name){}friend MM operator(MM object1, MM object2);void print() {cout << this->grade <…

基于springboot音乐翻唱与分享平台源码和论文

1.1研究背景 随着网络不断的普及发展&#xff0c;音乐网站与分享平台依靠网络技术的支持得到了快速的发展&#xff0c;首先要从用户的实际需求出发&#xff0c;通过了解用户的需求开发出具有针对性的首页、音乐资讯、音乐翻唱、在线听歌、留言反馈、个人中心、后台管理、客服功…

Spring 事务常见错误(下)

通过上一章的学习&#xff0c;我们了解了 Spring 事务的原理&#xff0c;并解决了几个常见的问题。这一章我们将继续讨论事务中的另外两个问题&#xff0c;一个是关于事务的传播机制&#xff0c;另一个是关于多数据源的切换问题通过这两个问题&#xff0c;你可以更加深入地了解…

CopyUtil对象复制工具类

介绍 CopyUtil是一个通用的对象复制工具类&#xff0c;其中包含单体复制和列表复制两个方法。 单体复制方法copy通过传入源对象和目标class&#xff0c;利用Java反射机制创建目标对象&#xff0c;并将源对象的属性值复制到目标对象中。若源对象为空&#xff0c;则返回null。若…

如何使用支付宝沙箱环境本地配置模拟支付并实现公网远程访问【内网穿透】

文章目录 前言1. 下载当面付demo2. 修改配置文件3. 打包成web服务4. 局域网测试5. 内网穿透6. 测试公网访问7. 配置二级子域名8. 测试使用固定二级子域名访问 前言 在沙箱环境调试支付SDK的时候&#xff0c;往往沙箱环境部署在本地&#xff0c;局限性大&#xff0c;在沙箱环境…
最新文章