redis zset 内部的实现原理

Redis对象

Redis对象由redisObject结构体表示。

typedef struct redisObject {

    unsigned type:4; // 对象的类型,包括 /* Object types */

    unsigned encoding:4; // 底部为了节省空间,一种type的数据,可以采用不同的存储方式

    unsigned lru:REDIS_LRU_BITS; /* lru time (relative to server.lruclock) */

    int refcount; // 引用计数

    void *ptr;

} robj;
  • Redis中的每个键值对的键和值都是一个redisObject。
  • 共有五种类型的对象:字符串(String)、列表(List)、哈希(Hash)、集合(Set)、有序集合(SortedSet),源码server.h如下定义:
/* The actual Redis Object */

#define OBJ_STRING 0

#define OBJ_LIST 1

#define OBJ_SET 2

#define OBJ_ZSET 3

#define OBJ_HASH 4
  • 每种类型的对象至少都有两种或以上的编码方式;可以在不同的使用场景上优化对象的使用场景。用TYPE命令可查看某个键值对的类型

对象编码

Redis目前使用的编码方式:

/* Objects encoding. Some kind of objects like Strings and Hashes can be

* internally represented in multiple ways. The 'encoding' field of the object

* is set to one of this fields for this object.

*/

#define OBJ_ENCODING_RAW /* Raw representation */ 简单动态字符串

#define OBJ_ENCODING_INT /* Encoded as integer */ 整数

#define OBJ_ENCODING_HT /* Encoded as hash table */ 字典

#define OBJ_ENCODING_ZIPLIST /* Encoded as ziplist */ 压缩列表

#define OBJ_ENCODING_INTSET /* Encoded as intset */ 整数集合

#define OBJ_ENCODING_SKIPLIST /* Encoded as skiplist */ 跳跃表

#define OBJ_ENCODING_EMBSTR /* Embedded sds string encoding */ embstr编码的简单动态字符串

#define OBJ_ENCODING_QUICKLIST /* Encoded as linked list of ziplists */

本质上,Redis就是基于这些数据结构而构造出一个对象存储系统。redisObject结构体有个ptr指针,指向对象的底层实现数据结构,encoding属性记录对象所使用的编码,即该对象使用什么数据结构作为底层实现。

zset介绍

有序集合对象的编码可以是ziplist或者skiplist。同时满足以下条件时使用ziplist编码:

  • 元素数量小于128个
  • 所有member的长度都小于64字节

以上两个条件的上限值可通过zset-max-ziplist-entries和zset-max-ziplist-value来修改。

ziplist编码的有序集合使用紧挨在一起的压缩列表节点来保存,第一个节点保存member,第二个保存score。ziplist内的集合元素按score从小到大排序,score较小的排在表头位置。

skiplist编码的有序集合底层是一个命名为zset的结构体,而一个zset结构同时包含一个字典和一个跳跃表。跳跃表按score从小到大保存所有集合元素。而字典则保存着从member到score的映射,这样就可以用O(1)的复杂度来查找member对应的score值。虽然同时使用两种结构,但它们会通过指针来共享相同元素的member和score,因此不会浪费额外的内存。

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

行走在江湖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值