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

news2024/10/6 12:27:44

 本文是深入理解 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.coloradmin.cn/o/1479920.html

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

相关文章

CCDP.01.寄主机SSH连接虚拟机的QA

V0.0 初始版本-2024.2.29 检查VM的网卡配置 如上图&#xff0c;如果enp0s3网卡没有出现形如10.0.0.??/24的ip配置&#xff0c;说明该网卡配置存在错误&#xff0c;或者没有“使能”该网卡。在RockyLinux8.X中可检查“ifcfg-enp0s&#xff1f;” vi /etc/sysconfig/network-…

51-n皇后(回溯算法)

题目 按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数 n &#xff0c;返回所有不同的 n 皇后问题 的解决方案。 每一…

C# Post数据或文件到指定的服务器进行接收

目录 应用场景 实现原理 实现代码 PostAnyWhere类 ashx文件部署 小结 应用场景 不同的接口服务器处理不同的应用&#xff0c;我们会在实际应用中将A服务器的数据提交给B服务器进行数据接收并处理业务。 比如我们想要处理一个OFFICE文件&#xff0c;由用户上传到A服务器…

【CesiumJS-3】加载倾斜模型数据(3DTilest)以及修改位置

引入倾斜模型数据 // 加载3DTiles数据let tileset;try {tileset await Cesium.Cesium3DTileset.fromUrl("/api/3DTiles/b3dm_qx/tileset.json");viewer.value.scene.primitives.add(tileset); // 倾斜模型添加到场景中viewer.value.zoomTo(tileset); // 视角定位到倾…

外汇天眼:2月客诉TOP10榜单公布,快来看看你用的平台有没有上榜!

作为外汇投资者了解每个月登上客诉榜单的交易平台很重要&#xff0c;只有这样才能有效的预防自己遭遇外汇黑平台&#xff0c;也能警觉的提前发现平台的异常&#xff0c;对于自己的外汇交易道路只有利无弊&#xff01; 快来看看有哪些平台上榜&#xff0c;你所使用的平台是否在…

3 局域网基础(1)

1.局域网 早期的局域网主要是令牌环网。20世纪80年代&#xff0c;局域网领域出现 Ethernet与Token Bus、Token Ring三足鼎立的局面&#xff0c;并且各自都形成了相应的国际标准。21 世纪&#xff0c;Ethernet 已成为局域网领域的主流技术。介质访问控制&#xff08;MAC&#xf…

破局数据分析滞后难题,赋能企业高速增长的指标管理解决方案

指标是什么&#xff1f; 业务发展过程中&#xff0c;企业内外部都会产生很多的业务数据&#xff0c;对这些数据进行采集、计算、落库、分析后&#xff0c;形成的统计结果称为指标。简单来说&#xff0c;指标是业务被拆解、量化后形成的数量特征&#xff0c;企业利用数据指标对…

如何使用Portainer创建Nginx容器并搭建web网站发布至公网可访问【内网穿透】

文章目录 前言1. 安装Portainer1.1 访问Portainer Web界面 2. 使用Portainer创建Nginx容器3. 将Web静态站点实现公网访问4. 配置Web站点公网访问地址4.1公网访问Web站点 5. 固定Web静态站点公网地址6. 固定公网地址访问Web静态站点 前言 Portainer是一个开源的Docker轻量级可视…

【PyTorch][chapter 18][李宏毅深度学习]【无监督学习][ VAE]

前言: VAE——Variational Auto-Encoder&#xff0c;变分自编码器&#xff0c;是由 Kingma 等人于 2014 年提出的基于变分贝叶斯&#xff08;Variational Bayes&#xff0c;VB&#xff09;推断的生成式网络结构。与传统的自编码器通过数值的方式描述潜在空间不同&#xff0c;它…

用JavaScript动态提取视频中的文字

现阶段整个社会短视频&#xff0c;中视频为王&#xff0c;文字传播虽然被弱化&#xff0c;但在业务中还是有一定的传播价值&#xff0c;今天就来讲一讲如何使用js动态提取视频中的字幕。 先来看看效果&#xff1a; 屏幕录制2024-02-29 15.40.18 一&#xff0c;tesseract.js介…

springcloud alibaba组件简介

一、Nacos 服务注册中心/统一配置中心 1、介绍 Nacos是一个配置中心&#xff0c;也是一个服务注册与发现中心。 1.1、配置中心的好处&#xff1a; &#xff08;1&#xff09;配置数据脱敏 &#xff08;2&#xff09;防止出错&#xff0c;方便管理 &#xff08;3&#xff…

Web漏扫工具OWASP ZAP安装与使用(非常详细)从零基础入门到精通,看完这一篇就够了。

本文仅用于安全学习使用&#xff01;切勿非法用途。 一、OWASP ZAP简介 开放式Web应用程序安全项目&#xff08;OWASP&#xff0c;Open Web Application Security Project&#xff09;是一个组织&#xff0c;它提供有关计算机和互联网应用程序的公正、实际、有成本效益的信息。…

javascript作用域编译浅析

作用域思维导图 1&#xff1a;编译原理 分词/词法分析 如果词法单元生成器在判断a是一个独立的词法单元还是其他词法单元的一部分时&#xff0c;调用的是有状态的解析规则&#xff0c;那么这个过程就被称为词法分析。 解析/语法分析 由词法单元流转换成一个由元素逐级嵌套所组…

java: 错误: 不支持发行版本 5

目录 一、问题描述 二、解决办法 方法一&#xff1a;修改idea设置中的jdk版本 方法二&#xff1a;配置pom.xml文件 方法三&#xff1a;配置maven的xml文件&#xff08;推荐&#xff09; 三、结果 一、问题描述 问题描述&#xff1a;今天创建了一个maven项目&#xff0c;…

第六课:NIO简介

一、传统BIO的缺点 BIO属于同步阻塞行IO,在服务器的实现模型为&#xff0c;每一个连接都要对应一个线程。当客户端有连接请求的时候&#xff0c;服务器端需要启动一个新的线程与之对应处理&#xff0c;这个模型有很多缺陷。当客户端不做出进一步IO请求的时候&#xff0c;服务器…

Gitlab: 私有化部署

目录 1. 说明 2. 资源要求 3. 安装 4. 配置实践 4.1 服务器 4.2 人员与项目 4.2 部署准备 4.2.1 访问变量及用户账号设置 4.2.2 Runner设置 4.2.3 要点 5. 应用项目 CI/CD 6. 参考 1. 说明 gitlab是一个强大且免费的代码管理/部署工具&#xff0c;能统一集成代码仓…

springboot233大学生就业需求分析系统

大学生就业需求分析系统设计与实现 摘 要 信息数据从传统到当代&#xff0c;是一直在变革当中&#xff0c;突如其来的互联网让传统的信息管理看到了革命性的曙光&#xff0c;因为传统信息管理从时效性&#xff0c;还是安全性&#xff0c;还是可操作性等各个方面来讲&#xff…

SpringBoot接收参数的几种形式

SpringBoot接收参数的几种形式 在SpringBoot中获取参数基本方式有5种,需要都掌握. 这里需要记住一个技术术语或概念 API接口: 你写好的那个URL地址,就被称为API接口 1. 接收常规参数 给/param/demo1这个URL接口发送id, name两个参数 以上是以GET请求类型进行发送,实际发送…

一封来自 DatenLord 关于GSoC 2024的挑战书

Google Summer of Code 是一项全球性的在线计划&#xff0c;致力于将新的contributor引入开源软件开发领域。GSoC 参与者在导师的指导下&#xff0c;与开源组织合作开展为期 12 周以上的编程项目。今年&#xff0c;达坦科技入选作为开源社区组织&#xff0c;携CNCF Sandbox项目…

深入探讨Java中的OutputStreamWriter类

咦咦咦&#xff0c;各位小可爱&#xff0c;我是你们的好伙伴——bug菌&#xff0c;今天又来给大家普及Java SE相关知识点了&#xff0c;别躲起来啊&#xff0c;听我讲干货还不快点赞&#xff0c;赞多了我就有动力讲得更嗨啦&#xff01;所以呀&#xff0c;养成先点赞后阅读的好…