redis的基础底层篇 zset的详解

一 zset的作用以及结构

1.1 zset作用

redis的zset是一个有序的集合,和普通集合set非常相似,是一个没有重复元素的字符串集合。常用作排行榜等功能,以用户 id 为 value,关注时间或者分数作为 score 进行排序。

1.2 zset的底层结构

1.zset是一个特别的数据结构,一方面它等价于 Java 的数据结构 Map<String, Double>,可以给每一个元素 value 赋予一个权重 score,另一方面它又类似于 TreeSet,内部的元素会按照权重 score 进行排序,可以得到每个元素的名次,还可以通过 score 的范围来获取元素的列表。

2.zset 底层使用了两个数据结构:

hash,hash 的作用就是关联元素 value 和权重 score,保障元素 value 的唯一性,可以通过元素 value 找到相应的 score 值。
跳跃表,跳跃表的目的在于给元素 value 排序,根据 score 的范围获取元素列表。
https://blog.51cto.com/u_14191/6345603

ZSet 有两种不同的实现,分别是 ziplist 和 skiplist。具体使用哪种结构进行存储,规则如下:

1.ziplist:满足以下两个条件:

[value,score]键值对数量少于128个;每个元素的长度小于64字节。

2.skiplist:不满足以上两个条件时使用skiplist跳表,组合了hash和skiplist

hash用来存储value到score的映射,在时间复杂度o(1)时间内知道对应value的分数。

skiplist按照从小到大的顺序存储分数;每个元素存储的都是<value,score>对。

1.3 zset的api接口

zrevrange key start stop [WITHSCORES]----------------返回按score从大到小排序后且索引在[start,stop]区间的元素,从0开始
zrevrangebyscore key max min[WITHSCORES]------------------返回按score从大到小排序后且分数在[min,max]区间的元素
zrangebylex key min max[LIMIT offset count]--------------通过字典区间返回有序集合的成员
zrank key member-------------返回元素member的索引,不存在nil
zrevrank key member--------------返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序
zscore key member---------------返回有序集合中,元素member分数
zscan key cursor [MATCH pattern] [COUNT count]-------------迭代有序集合中的元素(包括元素的分值)
zunionstore destination numkeys key [key …]-------------计算给定的一个或多个有序集的并集,并存储在新的 key 中
zinterstore destination numkeys key [key …]--------------计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 key 中
zincrby key increment member-----------有序集合中对指定元素的分数加上增量 increment
zrem key member[member…]-----------移除有序集合中的一个或多个元素
zremrangebylex key min max-----------移除有序集合中给定的字典区间的所有成员
zremrangebyrank key start stop---------移除有序集合中给定的排名区间的所有成员
zremrangebyscore key min max-------移除有序集合中给定的分数区间的所有成员
https://blog.51cto.com/u_14191/6345603

二  跳跃表

2.1 跳跃表

跳跃表(skiplist)是一种有序数据结构,它通过在每个节点中维持多个指向其它节点的指针,从而达到快速访问节点的目的。链表加多级索引的的结构,就是跳跃表。

数组支持随机访问的线性结构,底层使用二分查找。链表不支持随机访问的线性结构。跳跃表中查询任意数据的时间复杂度就是 O(logn)

2.2 跳跃表分析

1.对于一个单链表来讲,即便链表中存储的数据是有序的,如果我们要想在其中查找某个数据,也只能从头到尾遍历链表。这样查找效率就会很低,时间复杂度会很高,是 O(n)。

2.在该链表中,每隔一个节点就有一个附加的指向它在表中前两个位置上的节点的链,正因为如此,在最坏的情形下,最多考察 n/2 + 1 个节点。比如我们要查 90 这个节点,按照之前单链表的查找的话要 8 个节点,现在只需 5 个节点。 

3.这里每隔 4 个节点就有一个链接到该节点前方的下一个第 4 节点的链,只有 n/4 + 1 个节点被考察。

我们利用数学的思想,针对通用性做扩展。每隔第 2^i 个节点就有一个链接到这个节点前方下一个第  2^i  个节点链。链的总个数仅仅是加倍,但现在在一次查找中最多只考察 logn 个节点。不难看到一次查找的总时间消耗为 O(logn),这是因为查找由向前到一个新的节点或者在同一节点下降到低一级的链组成。在一次查找期间每一步总的时间消耗最多为 O(logn)。注意,在这种数据结构中的查找基本上是折半查找(Binary Search)。

2.3 跳跃表底层结构

Redis 的跳跃表是由 redis.h/zskiplistNode 和 redis.h/zskiplist 两个结构定义,其中 zskiplistNode 用于表示跳跃节点,而 zskiplist 结构则用于保存跳跃表节点的相关信息,比如节点的数量以及指向表头节点和表尾节点的指针等等。

上图最左边的是 zskiplist 结构,该结构包含以下属性:

  • header:指向跳跃表的表头节点

  • tail:指向跳跃表的表尾节点

  • level:记录目前跳跃表内,层数最大的那个节点层数(表头节点的层数不计算在内)

  • length:记录跳跃表的长度,也就是跳跃表目前包含节点的数量(表头节点不计算在内)

位于 zskiplist 结构右侧是四个 zskiplistNode 结构,该结构包含以下属性:

  • 层(level):节点中用 L1、L2、L3 等字样标记节点的各个层,L1 代表第一层,L2 代表第二层,以此类推。每个层都带有两个属性:前进指针和跨度。前进指针用于访问位于表尾方向的其它节点,而跨度则记录了前进指针所指向节点和当前节点的距离。

  • 后退(backward)指针:节点中用 BW 字样标识节点的后退指针,它指向位于当前节点的前一个节点。后退指针在程序从表尾向表头遍历时使用。

  • 分值(score):各个节点中的 1.0、2.0 和 3.0 是节点所保存的分值。在跳跃表中,节点按各自所保存的分值从小到大排列。

  • 成员对象(obj):各个节点中的 o1、o2 和 o3 是节点所保存的成员对象。

 2.4 平衡树,跳跃表,hash之间的比较

Redis中ZSet的底层数据结构跳跃表skiplist,你真的了解吗?

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Maven的介绍和使用

Maven的作用 项目构建 依赖管理&#xff1a;避免资源间版本冲突问题 统一开发结构&#xff1a;提供统一的项目结构 Maven的使用 下载完压缩包之后放在合适的目录下&#xff0c;其中apache-maven-3.8.8文件夹是安装的maven&#xff0c;下面的repository是本地仓库&#xff…

设计模式Java实战

文章目录 一、前置1.1 目的1.2 面向对象1.3 接口和抽象类 二、七大设计原则2.1 单一职责2.2 接口隔离原则2.3 依赖倒转原则2.4 里氏替换原则2.5 开闭原则2.6 不要重复原则2.7 迪米特最少知道法则 三、23种设计模式3.1创建型&#xff1a;创建对象3.1.1 单例模式定义最佳实践场景…

【送书】实现可观测性平台的技术要点是什么?

文章目录 实现可观测性平台的技术要点是什么?兼容全域信号量所谓全域信号量有哪些&#xff1f;统一采集和上传工具统一的存储后台自由探索和综合使用数据总结 实现可观测性平台的技术要点是什么? 随着可观测性理念的深入人心&#xff0c;可观测性平台已经开始进入了落地阶段…

Spring学习笔记2 Spring的入门程序

Spring学习笔记1 启示录_biubiubiu0706的博客-CSDN博客 Spring官网地址:https://spring.io 进入github往下拉 用maven引入spring-context依赖 写spring的第一个程序 引入下面依赖,好比引入Spring的基本依赖 <dependency><groupId>org.springframework</groupId&…

使用vue-cli搭建spa项目

目录 什么是vue-cli 安装vue-cli 使用脚手架vue-cli(来构建项目&#xff09; vue项目结构的说明 基于spa项目完成路由 基于spa项目完成嵌套路由 什么是vue-cli Vue CLI是一个官方发布的用于快速搭建Vue.js项目的命令行工具。它提供了一套交互式的脚手架&#xff0c;可以帮…

计算物理专题----随机游走实战

计算物理专题----随机游走实战 Problem 1 Implement the 3D random walk 拟合线 自旋的 拟合函数&#xff08;没有数学意义&#xff09; 参数&#xff1a;0.627,3.336,0.603&#xff0c;-3.234 自由程满足在一定范围内的均匀分布以标准自由程为单位长度&#xff0c;…

数据结构 - 线性表(顺序表)

线性表是什么 线性表是包含若干数据元素的一个线性序列&#xff0c;记为&#xff1a; L (a0&#xff0c;…ai-1&#xff0c;ai,ai1,…an-1) L为表名&#xff0c;ai&#xff08;0≤ i ≤n-1&#xff09;为数据元素&#xff1b;n为表长&#xff0c;n>0时&#xff0c;线性表…

MySQL全局优化与Mysql8.0新增特性

Mysql全局优化总结 ​ 从上图可以看出SQL及索引的优化效果是最好的&#xff0c;而且成本最低&#xff0c;所以工作中我们要在这块花更多时间。 补充一点配置文件my.ini或my.cnf的全局参数&#xff1a; 假设服务器配置为&#xff1a; CPU&#xff1a;32核内存&#xff1a;6…

vue+express、gitee pm2部署轻量服务器

一、代码配置 前后端接口都保持 127.0.0.1:3000 vue创建文件 pm2.config.cjs module.exports {apps: [{name: xin-web, // 应用程序的名称script: npm, // 启动脚本args: run dev, // 启动脚本的参数cwd: /home/vue/xin_web, // Vite 项目的根目录interpreter: none, // 告诉…

burpsuite+proxifier小程序抓包

burpsuiteproxifier小程序抓包 安装bp证书到系统 配置

推荐一款可以快速抽取sap数据的ETL工具

使用SAP在数据分析上面临的问题 SAP Enterprise Resource Planning (ERP) 是国内最广泛使用的ERP系统之一。然而&#xff0c;使用SAP ERP系统面临着一些数据分析不方便&#xff0c;数据导出困难等问题&#xff1a; 数据集成困难&#xff1a;将SAP中的数据整合到其他系统或本地…

局部变量,全局变量与内存

本文会使用IDA分析局部变量&#xff0c;全局变量在内存的存储 目录 使用IDA分析局部变量 使用IDA分析全局变量 总结 使用IDA分析局部变量 #include <stdio.h>int main() {int nNum 1;float fNum 2.5;char ch A;printf("int %d, float %f, char %c", nNu…

opencv dnn模块 示例(16) 目标检测 object_detection 之 yolov4

博客【opencv dnn模块 示例(3) 目标检测 object_detection (2) YOLO object detection】 测试了yolov3 及之前系列的模型&#xff0c;有在博客【opencv dnn模块 示例(15) opencv4.2版本dnn支持cuda加速&#xff08;vs2015异常解决&#xff09;】 说明了如何使用dnn模块进行cuda…

vue2中年份季度选择器(需要安装element)

调用 <!--父组件调用--><QuarterCom v-model"quart" clearable default-current/> 组件代码 <template><div><span style"margin-right: 10px">{{ label }}</span><markstyle"position:fixed;top:0;bottom:0…

路由器ip地址设置

当你使用路由器时&#xff0c;你可以按照以下步骤设置路由器的IP地址。这样可以确保你的网络连接正常并允许其他设备连接到你的路由器。 **步骤一&#xff1a;登录路由器管理界面** 首先&#xff0c;你需要登录到路由器的管理界面。打开你的浏览器&#xff0c;并输入路由器的…

本地Docker Registry远程连接,为你带来高效便捷的镜像管理体验!

Linux 本地 Docker Registry本地镜像仓库远程连接 文章目录 Linux 本地 Docker Registry本地镜像仓库远程连接1. 部署Docker Registry2. 本地测试推送镜像3. Linux 安装cpolar4. 配置Docker Registry公网访问地址5. 公网远程推送Docker Registry6. 固定Docker Registry公网地址…

ChatGLM Pytorch从0编写Transformer算法

预备工作 # !pip install http://download.pytorch.org/whl/cu80/torch-0.3.0.post4-cp36-cp36m-linux_x86_64.whl numpy matplotlib spacy torchtext seaborn import numpy as np import torch import torch.nn as nn import torch.nn.functional as F import math, copy, tim…

【漏洞复现】企望制造 ERP命令执行

漏洞描述 由于企望制造 ERP comboxstore.action接口权限设置不当&#xff0c;默认的配置可执行任意SQL语句&#xff0c;利用xp_cmdshell函数可远程执行命令&#xff0c;未经认证的攻击者可通过该漏洞获取服务器权限。 免责声明 技术文章仅供参考&#xff0c;任何个人和组织…

golang入门笔记——pprof性能分析

文章目录 简介runtime/pprof的使用命令行交互网络服务性能分析pprof与性能测试结合压测工具go-wrk 简介 golang性能分析工具pprof的8个指标 1.性能分析的5个方面&#xff1a;CPU、内存、I/O、goroutine&#xff08;协程使用情况和泄漏检查&#xff09;、死锁检测以及数据竟态…

ETHERCAT转MODBUS TCP/IP协议网关

产品介绍 JM-ECT-TCPIP是自主研发的一款EtherCAT从站功能的通讯网关。该产品主要功能是将EtherCAT网络和 TCP/IP 网络连接起来。 本网关连接到EtherCAT总线中做为从站使用&#xff0c;连接到 TCP/IP 网络中做为服务器或客户端使用。 产品参数 技术参数 u 网关做为EtherCAT网…