Redis内存优化——ZSet类型介绍及底层原理详解

news2025/1/19 3:10:41

系列文章目录

Redis内存优化——String类型介绍及底层原理详解
Redis内存优化——Hash类型介绍及底层原理详解
Redis内存优化——List类型介绍及底层原理详解
Redis内存优化——Set类型介绍及底层原理详解
Redis内存优化——ZSet类型介绍及底层原理详解


文章目录

  • 系列文章目录
  • 前言
  • ZSet
    • 概述
    • skiplist
    • redis的skiplist
  • 总结


前言

Redis是一种高性能的键值型数据库,它支持多种数据结构,其中一种是zset类型。zset类型可以存储一个有序的、不重复的字符串集合,类似于Java中的TreeSet或Python中的sorted set。zset类型的优点是可以对集合进行快速的添加、删除、判断是否存在等操作,以及对集合中的元素按照分值(score)进行排序,分值相同则按照字典序排序。


ZSet

概述

Redis 中的 zset 是一种有序集合类型,它可以存储不重复的字符串元素,并且给每个元素赋予一个排序权重值(score)。Redis 通过权重值来为集合中的元素进行从小到大的排序。zset 的成员是唯一的,但权重值可以重复。一个 zset 类型的键最多可以存储 2^32 - 1 个元素。

Redis中zset源码

typedef struct zskiplistNode {
    sds ele;
    double score;
    struct zskiplistNode *backward;
    struct zskiplistLevel {
        struct zskiplistNode *forward;
        unsigned long span;
    } level[];
} zskiplistNode;

typedef struct zskiplist {
    struct zskiplistNode *header, *tail;
    unsigned long length;
    int level;
} zskiplist;

typedef struct zset {
    dict *dict;
    zskiplist *zsl;
} zset;

Redis在存储zset结构的数据,为了达到内存和性能的平衡,针对少量存储和大量存储分别设计了两种结构,分别为:

  • redis7.0之前使用的ziplistskiplist
  • redis7.0之后使用的listpackskiplist

也就是说不论是7.0前后都有两种结构,但是7.0后使用了listpack代替ziplist,这是由于ziplist的连锁更新问题,连锁更新问题请见我另一篇博文:Redis高可用系列——Set类型底层详解。这边博文中详细的解释。

zset 中的元素个数和元素值的长度比较小的时候,Redis 使用ziplist/listpack来节省内存空间。当 zset 中的元素个数和元素值的长度达到一定阈值时,Redis 会自动将ziplist/listpack转换为skiplist,以提高操作效率

具体来说,当 zset 同时满足以下两个条件时,会使用 listpack作为底层结构:

  • 元素个数小于 zset_max_listpack_entries ,默认值为 128
  • 元素值的长度小于zset_max_listpack_value,默认值为 64

zset 中不满足以上两个条件时,会使用 skiplist 作为底层结构。

skiplist

跳跃表是一种随机化的数据结构,实质就是一种可以进行二分查找的有序链表。跳跃表在原有的有序链表上面增加了多级索引,通过索引来实现快速查找。跳跃表不仅能提高搜索性能,同时也可以提高插入和删除操作的性能

在这里插入图片描述

跳跃表相比于其他平衡树结构,有以下几个优点和缺点:

优点:

  • 实现简单,易于理解和调试
  • 插入和删除操作只需要修改局部节点的指针,不需要像平衡树那样进行全局调整
  • 可以利用空间换时间,通过增加索引层来提高查找效率
  • 支持快速的范围查询,可以方便地返回指定区间内的所有元素

缺点:

  • 空间复杂度较高,需要额外存储多级索引
  • 随机性太强,性能不稳定,最坏情况下可能退化成链表
  • 不支持快速的倒序遍历,需要额外的指针来实现

redis的skiplist

skiplist这种数据结构有一个层数上的问题,当层数过多,会影响查询效率。是因为当层数过多,会进行多次IO操作。而Redis 使用了一个随机函数来决定每个节点的层数,这个随机函数的期望值是 1/(1-p) ,其中 p 是一个概率常数,Redis 中默认为 0.25。这样可以保证跳跃表的平均高度为 log (1/p) n ,其中 n 是节点数。Redis 还限制了跳跃表的最大层数为 32 ,这样可以避免过高的索引层造成空间浪费


总结

Redis Zset类型是一种可以存储一个有序的、不重复的字符串集合的数据结构,它有以下特点:

  • 可以对集合进行添加、删除、判断是否存在等操作,时间复杂度都是O (1)
  • 可以对集合中的元素按照分值(score)进行排序,分值相同则按照字典序排序
  • 可以对多个集合进行交集、并集、差集等操作,并指定分值的聚合方式
  • 可以用作排行榜、优先队列、延时任务等场景

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

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

相关文章

Ingress:k8s集群进出流量的总管

Ingress:k8s集群进出流量的总管 Service 对象,它是 Kubernetes 内置的负载均衡机制,使用静态 IP 地址代理动态变化的 Pod,支持域名访问和服务发现,是微服务架构必需的基础设施。 Service 很有用,但也只能说…

分享一个国内可用的ChatGPT网站,免费无限制,支持AI绘画 - AI 百晓生

背景 ChatGPT作为一种基于人工智能技术的自然语言处理工具,近期的热度直接沸腾🌋。 作为一个AI爱好者,翻遍了各大基于ChatGPT的网站,终于找到一个免费!免登陆!手机电脑通用!国内可直接对话的C…

使用apisix代理静态文件

前言 最近公司考虑用apisix作为公司网关并且部署到k8s上,我这边收到一个小任务:使用apisix代理静态文件 通过apisix官网了解到它构建于 NGINX ngx_lua 的技术基础之上,所以按理应该和nginx代理静态资源是一样的。因为是通过docker容器部署…

STM32-内部温度传感器实验

STM32内部是有温度传感器的,以F1为例,它的温度采集范围是-40度到125度,精度为正负2度,采样通道为ADC1_INI6,上电控制位为TSVREFE位。 温度计算方式为:T(摄氏度) (V25 - Vsense) / Avg_Slope 25&#xff…

数据库管理-第七十六期 如何升级19c RAC(20230516)

数据库管理 2023-05-16 第七十六期 如何升级19c RAC1 回头处理2 升级AHF3 升级GI及DB3.1 拷贝所需文件3.2 升级OPatch3.3 升级GI与DB3.4 应用SQL变更 4 升级OJVM4.1 解压补丁4.2执行补丁冲突检查:4.3 升级OJVM4.4 应用SQL变更 5 最终验证总结 第七十六期 如何升级19…

NC 人力薪酬管理怎么结账?

NC 人力薪酬管理结账流程 1、先在【薪资发放】节点选择相应的薪资方案进行查询操作,然后进行计算操作; 2、计算操作完后,再进行审核操作; 3、如果薪资方案勾选了“发放数据需要审批”属性,则需要在【发放申请】节点…

【NB 2023】从一般蛋白质语言模型中高效进化人类抗体

Efficient evolution of human antibodies from general protein language models 哈佛大学化学与化学生物学系和圣路易斯华盛顿大学的研究人员共同完成的一篇论文,发表在Nature Biotechnology上。 抗体是一种大分子,属于免疫球蛋白家族,它…

springboot 启动后,调用接口时报错404问题汇总(层层推进、超全面)

线上环境 确保项目启动成功 看到这条日志才能判定项目是启动成功的 确保controller类被成功注册到了springboot容器中 首先,按springboot的类扫描规则来说,启动类和被扫描的组件类应该要在同一包下的 验证策略 从springboot容器中尝试去获取到contro…

【Springboot】yaml配置文件多环境切换

关于配置文件的详细说明可以看官方文档: 24. Externalized Configuration 以下是个人学习过程中的笔记,如有错误,请多指教! 目录 (一)配置文件 (二)yaml的概述及基本使用 yaml基本…

TCP与UDP相关知识(详细)

目录 一、UDP 和 TCP 的特点与区别 二、UDP 与TCP 首部格式 三、TCP 的三次握手和四次挥手 四、TCP 短连接和长连接的区别 五、TCP粘包、拆包及解决办法 六、TCP 可靠传输 七、TCP 滑动窗口 八、TCP 流量控制 九、TCP 拥塞控制 十、提供网络利用率 一、UDP 和 TCP 的特…

yolov8 pycharm运行(predict,不用command line)

yolov8就不介绍了,见主页 这里说下用pycharm运行。 代码参考segment页 from ultralytics import YOLO# Load a model model YOLO(yolov8n-seg.pt) # load an official model# Predict with the model results model(test_img.jpg) # predict on an image不通过…

Cube Map 系列之:手把手教你 实现 环境光贴图

什么是环境光贴图 下面先看两个例子: 使用左侧的纹理 渲染茶壶,得到茶壶对真实空间的反射效果 同样使用左侧的纹理,得到中心的球对四周物体的反射效果 所以,环境光贴图指的是通过构建物体周围世界的纹理,使用纹理贴…

25的大学生转行学云计算,能拿到10k+的月薪,是真的吗?

25的大学生转行学云计算,能拿到10k的月薪,是真的吗? 对于IT行业来说,月薪上万并不少见,毕竟互联网常年占据行业薪资排行榜首。作为技术行业,由于其发展的前沿性,引导性,也是作为其他…

26-2 vue-router

原始的方式好多东西需要我们自己去写,vue-router是一个集成好了的路由包,vue-router 官网 Vue Router | Vue.js 的官方路由 并非原始的东西就不好,只要是包就可能存在版本兼容问题,如果是简单的需求就建议用原始的方法 目录 1 …

如何进行远程控制电脑

电脑在我们日常生活中的作用是非常大的,尤其是在信息时代地位非常高。 其中,最常见、最具代表性的功能是实现远程控制功能。它可以直接解决一些问题,而不需要去现场,在一定程度上提高了工作效率。但是有很多朋友不知道如何实现远…

边缘计算盒子有哪些?边缘计算应用场景

边缘计算(Edge Computing)是一种分布式计算模型,旨在将数据处理和计算功能从中心数据中心移到数据源附近的边缘设备上。它的目标是在接近数据生成的地方进行实时数据处理和分析,减少数据传输延迟和网络拥塞,提高应用程…

计算机图形学-GAMES101-2

Vectors向量 一、向量的介绍 表示一个方向。计算向量的方法:AB (B-A)。向量对应的单位向量 AB / ||AB|| 。向量具有平移性,我们不关心它的开始位置。向量求和:三角形法则和平行四边形法则。在代数上计算直接把向量的…

如何防止网站被黑客攻击?黑客是怎样炼成的?

现在的黑客网站可谓是多如牛毛,不管在哪里只要你愿意学,都可以学到一招半式。看过别人的个性签名:卖菜的王大妈是黑客,烤红薯的李大爷也是黑客,对面成人用品店的老板,挖日,还是黑客-_-~!..黑客还真多啊!!!据…

关于对自动化测试的理解:目的与本质!(新手必看)

其实自动化测试很好理解,由两部分组成,“自动化”和“测试”,所以我们要理解自动化测试,就必须理解“自动化”和“测试”,只有理解了这些概念,才能更轻松的做好的自动化测试。其中“自动化”可以想象成通过…

晶飞FLA5000光谱仪.FlaSpec格式解析批处理导出CSV文件

引言 首先说明下晶飞上位机软件存在的问题,实验所采用的FLA5000型号光谱仪,光谱波段从280-970nm,FWHM值为2.4nm。 1、上位机软件中的光谱数据复制功能基本是废的,最多只能到599.9nm,后面的数据全部消失。 2、上位机软…