Redis有序集合对象(Zset)使用ziplist和skiplist

2021/6/6 19:27:03

本文主要是介绍Redis有序集合对象(Zset)使用ziplist和skiplist,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

标题首先明确一下几点基本常识:

  • Redis常见的5种数据类型:String(字符串)、List(列表)、Hash(哈希)、Set(集合)、ZSet(有序集合),这五种常见的数据类型,本质上对应着五种对象,即字符串对象、列表对象、哈希对象、集合对象、有序集合对象。
  • 在Redis中,任意一个对象都具有五种属性

[1] type ====> 类型对应基本数据类型。例如Redis_String 对应字符串,Redis_List对应列表
[2] encoding ====> 编码。编码方式决定了对象的底层的数据结构,一个对象至少有两种编码方式
[3] prt ====> 指针。指向由编码决定的数据结构,数据结构中往往包含有所存的数据
[4] refcount ====> 引用计数。这个属性主要是为了实现redis中的内存回收机制
[5] lru ====> 最近最少使用。用来解决对象的空转时长,同时也会被用于当缓冲达到最大值,再向其中添加数据时,应该删除什么数据。

有序结合(ZSet)对象详解

上述说过,一个对象的底层的数据结构是由对象的编码方式决定的,而ZSet的编码方式有两种

  • ziplist
  • skiplist
    上述两种数据结构的底层实现见书籍 《redis设计与实现》。
    有序结合底层s

ZipList

使用压缩连表时,要保证集合中的数据有序,会将key放在前面一位,然后将key所对应value放在key的后一位。这样就能够保证集合的有序。
在这里插入图片描述

SkipList

使用跳跃链表时,由于跳跃链表本来就是有序的,直接使用即可。
跳表数据结构见《Redis设计与实现》P39

当有序集合对象同时满足以下两个条件时,对象使用压缩链表编码:

  • 有序集合保存的元素数量小于128个;
  • 有序集合保存的所有元素成员的长度都小于64字节;

如果不满足上述两个条件,那么ZipList会转化为SkipList,同时,当后面的SkipList的元素数量和元素成员的长度满足要求时,也不会回退为ZipList。

重点

当使用SkipList实现ZSet时,ptr所指向的zset数据结构中包含了一个skiplist和dict结构。其中dict结构中创建了一个从SkipList对象到score的映射。通过dict可以实现O(1)时间复杂度查找key所对应的value。

那么为什么不直接使用字典或者skipList实现Zset呢?

  • 当直接使用字典的时候,虽然可以做到查询key-value的时间复杂度O(1),但是字典本身是无序的,要排序至少也需要O(Nlog(N))。
  • 当直接使用SkipList时,虽然可以做到有序,但是查询key-value至少也需要O(logN)。


这篇关于Redis有序集合对象(Zset)使用ziplist和skiplist的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程