Redis 原理 - Sorted Set (ZSet)
Sorted Set (ZSet) 数据结构
Sorted Set (ZSet), 即有序集合, 底层使用 压缩列表(ziplist) 或者 跳跃表(skiplist)
有趣的命名: Sorted Set 为啥不缩写为 SSet ? GitHub有人提问
- Z代表XYZ中的Z, 所以有排序的意思(这个说法有点牵强吧)
- Set命令已经使用S作为前缀了, 所以Sorted Set不再使用S (可信度较高)
- SSet 很奇怪, 很难发音 (这个理由也可以接受)
使用 ziplist 图解

使用 skiplist 图解
skiplist 定义
跳表是一种数据结构。它使得包含n个元素的有序序列的查找和插入操作的平均时间复杂度都是 O(logn),优于数组的 O(n)复杂度。快速的查询效果是通过维护一个多层次的链表实现的,且与下面一层链表元素的数量相比,每一层链表中的元素的数量更少。
skiplist 数据结构
//跳跃表节点
typedef struct zskiplistNode {
robj *obj; // 成员对象
double score; // 分值
struct zskiplistNode *backward; // 后退指针
// 层
struct zskiplistLevel {
struct zskiplistNode *forward; // 前进指针
unsigned int span; // 跨度
} level[];
} zskiplistNode;
//跳跃表
typedef struct zskiplist {
struct zskiplistNode *header, *tail; // 表头节点和表尾节点
unsigned long length; // 表中节点的数量
int level; // 表中层数最大的节点的层数
} zskiplist;
//有序集合
typedef struct zset {
dict *dict; // 字典,键为成员,值为分值, 用于支持 O(1) 复杂度的按成员取分值操作
zskiplist *zsl; // 跳跃表,按分值排序成员, 用于支持平均复杂度为 O(log N) 的按分值定位成员操作, 以及范围操作
} zset;
skiplist 图解

简单说下skiplist的查找过程:
比如查询 分数比 broadm 小的用户名
- 使用zset中的字典dict快速获取broadm节点对应的score=4
- 从header节点的最高层(第5层)出发,最高层(第5层)的前进节点是 obj:mike score:3,对比发现,此节点的score=3, 小于要查询的节点的score=4 (说明目标节点在此节点的右边), 应该继续前进, 但是此节点没有前进节点了, 那就降低一层,直到找到有前进节点的层为止(这里是第2层)
- 第2层的前进节点就是 broadm 了,找到了
- 因为skiplist是有序的,并且每个节点都保存了 backward 指针, 所以直接遍历链表就可以获取分数比broadm小的节点了
这里的数据量比较少,不容易看出来效果, 当数据量很大的时候,这种查询是非常高效的,平均时间复杂度为 O(logn),基本和平衡二叉树等效
Redis使用skiplist而不是红黑树的原因?
- 红黑树实现细节过于复杂,比如为了保持平衡,需要做节点的旋转操作, 而skiplist完全是靠随机层数实现的自平衡,非常简单
- 在范围查找时,跳跃表明显优于红黑树, 跳跃表是有序的链表,直接遍历后继节点即可, 而红黑树需要中序遍历,复杂度更高
Sorted Set (ZSet) 常用命令
- ZADD key score member 添加一个或多个元素到集合中,如果已经存在,则更新其score
- ZREM key member 删除集合中的指定元素
- ZSCORE key member 获取集合中指定元素的score
- ZRANK key member 获取集合中指定元素的排名(从0开始)
- ZCARD key 获取集合中元素的个数
- ZCOUNT key min max 统计score在闭区间[min,max]的元素的个数
- ZRANGE key min max 获取指定排名范围内的元素
- ZDIFF, ZINTER, ZUNION 求多个集合的 差集,交集,并集
Redis 原理 - Sorted Set (ZSet)的更多相关文章
- Redis原理及使用
一:原理介绍 1:什么是redis? Redis 是一个基于内存的高性能key-value数据库. 2:Reids的特点Redis本质上是一个Key-Value类型的内存数据库,很像memcache ...
- Redis原理与实践总结
Redis原理与实践总结 本文主要对Redis的设计和实现原理做了一个介绍很总结,有些东西我也介绍的不是很详细准确,尽量在自己的理解范围内把一些知识点和关键性技术做一个描述.如有错误,还望见谅,欢迎指 ...
- Redis原理详解
Redis原理详解 数据类型 Redis最为常用的数据类型主要有以下五种: String Hash List Set Sorted set 在具体描述这几种数据类型之前,我们先通过一张图了解下Redi ...
- php使用redis的有序集合zset实现延迟队列
延迟队列就是个带延迟功能的消息队列,相对于普通队列,它可以在指定时间消费掉消息. 延迟队列的应用场景: 1.新用户注册,10分钟后发送邮件或站内信. 2.用户下单后,30分钟未支付,订单自动作废. 我 ...
- Redis原理篇
Redis原理篇 1.发布 订阅模式 1.1列表 的局限 前面我们说通过队列的 rpush 和 lpop 可以实现消息队列(队尾进队头出),但是消费者需要不停地调用 lpop 查看 List 中是 ...
- Redis 系列(04-2)Redis原理 - 内存回收
目录 Redis 系列(04-2)Redis原理 - 内存回收 Redis 系列目录 1. 过期策略 1.1 定时过期(主动淘汰) 1.2 惰性过期(被动淘汰) 1.3 定期过期 2. 淘汰策略 2. ...
- 面试被吊打系列 - Redis原理
小张兴冲冲去面试,结果被面试官吊打! 小张: 面试官,你好.我是来参加面试的. 面试官: 你好,小张.我看了你的简历,熟练掌握Redis,那么我就随便问你几个Redis相关的问题吧.首先我的问题是,R ...
- 聊聊Mysql索引和redis跳表 ---redis的有序集合zset数据结构底层采用了跳表原理 时间复杂度O(logn)(阿里)
redis使用跳表不用B+数的原因是:redis是内存数据库,而B+树纯粹是为了mysql这种IO数据库准备的.B+树的每个节点的数量都是一个mysql分区页的大小(阿里面试) 还有个几个姊妹篇:介绍 ...
- Redis详细讲解(Redis原理,Redis安装,Redis配置,Redis使用,Redis命令)
一.Redis介绍 Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API.从2010年3月15日起,Redis的开发 ...
- Redis原理(一)
基础和应用 1.Redis是远程调用技术的首字母缩写. 2.Redis可以用来做什么? Redis可以用来做缓存. 分布式锁 3.Redis的应用举例 记录帖子的点赞数.评论数和点击数.(使用HASH ...
随机推荐
- 即时通讯技术文集(第13期):Web端即时通讯技术精华合集 [共15篇]
为了更好地分类阅读52im.net 总计1000多篇精编文章,我将在每周三推送新的一期技术文集,本次是第13 期. [- 1 -] 新手入门贴:史上最全Web端即时通讯技术原理详解 [链接] http ...
- kubernetes系列(七) - Pod生命周期
目录 1. pod生命周期 2. initC 2.1 initC介绍 2.2 initC的作用 2.3 initC的模版 2.4 initC的一些其他补充 3. Pod健康性检查(liveiness) ...
- DVWA靶场Weak Session IDs(弱会话) 漏洞所有级别通关教程及源码审计
Weak Session IDs(弱会话) Weak Session IDs(弱会话ID)漏洞是一种安全漏洞,涉及在 web 应用程序中使用不安全或容易被猜测的会话标识符(Session IDs).会 ...
- [软件工具使用记录] windows离线ollama部署本地模型并配置continue实现离线代码补全
qwen2.5coder发布之后,觉得差不多可以实现离线模型辅助编程了,所以尝试在公司内网部署模型,配合vsocde插件continue实现代码提示.聊天功能. 目前使用qwen2.5coder的32 ...
- ofd文件拆分合并思路探索 -- 附下载程序
前言 ofd文件拆分合并会在多个场合用到,但市面上此类工具并不多.拆分和合并虽然为两个功能,但从编程角度考虑,其处理思路有相同之处.文章就以合并为例,讲一下处理思路.作者也写了一个拆分合并小工具 ...
- 对比使用DeepSeek与文新一言,了解DeepSeek的关键技术论文
DeepSeek是国内大模型技术的新秀,最近也在业界和媒体界火爆出圈,所以想学习一下其技术. 大模型时代,学习知识,当然首先想到利用大模型,由于在过去一年,对DeepSeek使用不多,所以想和文新一言 ...
- java集合中的迭代器Iterator和数组内置方法以及常见的报错
删除Map的中某一项报错 package part; import java.util.HashMap; import java.util.Set; public class Java01 { pub ...
- Git操作的基本命令
git命令常用步骤 初始化,把当前文件夹作为git本地仓库 git init 把本地仓库与选程仓库关联 git remote add origin http://gitee.com/ 把项目区中做了修 ...
- SqlServer性能检测之Sql语句排查
很多时候,我们在用SQL语句查询数据时,难免会漏掉对SQL语句性能的考虑,所以有时就会造成SqlServer服务占用过高的问题,为了大致排查是哪些SQL语句造成的问题,我们可以通过如下SQL查询出最近 ...
- mac支持rar解压缩
一.下载 下载macOS版本:RAR 5.71 for macOS (64 bit) 二.安装 1.双击解压刚才下载的rarosx-5.7.1.tar,使用终端进入刚才解压的文件夹目录下cd /Use ...