redis zset我之见

本文深入介绍了Redis中的ZSet数据结构,包括其内部使用的跳跃列表(Skip List)实现原理。通过示例展示了ZSet的操作如添加、查询成员及其分数,并解释了跳跃列表如何提供高效的查找效率。同时,详细解析了跳跃列表节点和对象的数据结构,以及它们在查找和排序中的作用。
摘要由CSDN通过智能技术生成

Zset案例

先看一个最简单的zset案例

alpha:3>zadd key 1 tom # 添加key
"1"
alpha:3>zadd key 2 yorick
"1"
alpha:3>zadd key 3 yorick  # 这里事实上是 将yorick 的score 由2改为了3
"0"
alpha:3>zrange key 0 10  withscores #查询指定区间内的 成员,并连key 一起返回 
 1)  "tom"
 2)  "1"
 3)  "yorick"
 4)  "3"
alpha:3>zrank key yorick #查询yorick 的索引
"1"
alpha:3>zscore key yorick #查询yoirck 的分值
 "3"

Zset 数据结构

zset的数据结构是 map 和 跳跃列表

从源码redis 3.0中看到定义 zset 结构如下:

/*
 * 有序集合
 */
typedef struct zset {

    // 字典,键为成员,值为分值
    // 用于支持 O(1) 复杂度的按成员取分值操作
    dict *dict;

    // 跳跃表,按分值排序成员
    // 用于支持平均复杂度为 O(log N) 的按分值定位成员操作
    // 以及范围操作
    zskiplist *zsl;

} zset;

跳跃列表

跳跃列表类似下面这样:
在这里插入图片描述
1606036696502.png)]

那为什么要用这样的数据结构呢?答案是因为快,那为什么快呢?我们来看下面这个图:

img

假设我们要查找 19 。先从最上层的跳跃区间大的层開始查找。从头结点開始。首先和23进行比較,小于23,(此时查找指针在图中“1”位置处)。查找指针到下一层继续查找。

然后和9进行推断,大于9,查找指针再往前走一步和23比較,小于23。(此时查找指针在图中“2”位置处) 此时这个值肯定在9结点和23结点之间。查找指针到下一层继续查找。

然后和13进行推断。大于13,查找指针再往前走一步和23比較,小于23,(此时查找指针在图中“3”位置处)此时这个值肯定在13结点和23结点之间。查找指针到下一层继续查找。

此时,我们和19进行推断。找到了。

redis中跳跃链表数据结构

那redis是如何实现跳跃链表的呢?

在redis 5中,定义的数据结构如下:

// 跳跃表节点
typedef struct zskiplistNode {
sds ele;// 用于存储字符串类型的数据	
double score; //用于存储排序的分值。
struct zskiplistNode *backward; //后退指针, 只能指向当前节点最底层的前一个节
//点, 头节点和第一个节点——backward指向NULL, 从后向前遍历跳
//跃表时使用。
struct zskiplistLevel {
struct zskiplistNode *forward;// 指向本层的下一个节点
unsigned int span; //forward指向的节点与本节点之间的元素个数。 span值越
//大, 跳过的节点个数越多。
} level[];// 数组 最长64 ,
} zskiplistNode;

//跳跃表对象
typedef struct zskiplist {
struct zskiplistNode *header,*tail;
unsigned long length;
int level;
} zskiplist;

需要注意 :zsKiplist 的head 是一个一个特殊节点, 它的level数组元素个数为64。 头节点在有序集合中不存储任何member和score值, ele值为NULL, score值为0; 也不计入跳跃表的总长度。 头节点在初始化时, 64个元素的forward都指向NULL, span值都为0。

最后示意图如下:
在这里插入图片描述

基本上看了完这个数据结构 对redis的zset 也就大致了解了;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值