redis的Object结构体怎么定义

58次阅读
没有评论

共计 2558 个字符,预计需要花费 7 分钟才能阅读完成。

这篇文章主要介绍“redis 的 Object 结构体怎么定义”的相关知识,丸趣 TV 小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“redis 的 Object 结构体怎么定义”文章能帮助大家解决问题。

Redis 的两层数据结构简介

redis 的性能高的原因之一是它每种数据结构都是经过专门设计的,并都有一种或多种数据结构来支持,依赖这些灵活的数据结构,来提升读取和写入的性能。如果要了解 redis 的数据结构,可以从两个不同的层面来讨论它:

第一个层面,是从使用者的角度,这一层面也是 Redis 暴露给外部的调用接口,比如:string,list,hash,set,sorted set。

第二个层面,是从内部实现的角度,属于更底层的实现,比如:dict,sds,ziplist,quicklist,skiplist,intset。

Redis 数据结构的内部实现

从 Redis 的使用者的角度来看,一个 Redis 节点包含多个 database(非 cluster 模式下默认是 16 个,cluster 模式下只能是 1 个),而一个 database 维护了从 key space 到 object space 的映射关系。这个映射关系的 key 是 string 类型,而 value 可以是多种数据类型,比如:string, list, hash、set、sorted set 等。我们可以看到,key 的类型固定是 string,而 value 可能的类型是多个。

而从 Redis 内部实现的角度来看,database 内的这个映射关系是用一个 dict 来维护的。dict 的 key 固定用一种数据结构来表达就够了,这就是动态字符串 sds。而 value 则比较复杂,为了在同一个 dict 内能够存储不同类型的 value,这就需要一个通用的数据结构,这个通用的数据结构就是 robj,全名是 redisObject。

举个例子:

如果 value 是一个 list,那么它的内部存储结构是一个 quicklist。

如果 value 是一个 string,那么它的内部存储结构一般情况下是一个 sds。但如果 string 类型的 value 的值是一个数字,那么 Redis 内部还会把它转成 long 型来存储,从而减小内存使用。

所以,一个 robj 既能表示一个 sds,也能表示一个 quicklist,甚至还能表示一个 long 型。

redisObject 结构体

redisObject 的定义如下:

typedef struct redisObject {
 unsigned type:4;
 unsigned encoding:4;
 unsigned lru:LRU_BITS; /* lru time (relative to server.lruclock) */
 int refcount;
 void *ptr;} robj;

一个 robj 包含如下 5 个字段:

type: 对象的数据类型。占 4 个 bit。可能的取值有 5 种: OBJ_STRING, OBJ_LIST, OBJ_SET, OBJ_ZSET,
OBJ_HASH,分别对应 Redis 对外暴露的 5 种数据结构

encoding: 对象的内部表示方式(也可以称为编码),占 4 个 bit,可能的取值有 10 种。

lru: 做 LRU 替换算法用,占 24 个 bit。

refcount: 引用计数。它允许 robj 对象在某些情况下被共享。

ptr: 数据指针。指向真正的数据。比如,一个代表 string 的 robj,它的 ptr 可能指向一个 sds 结构;一个代表 list 的 robj,它的 ptr 可能指向一个 quicklist。

这里特别需要仔细察看的是 encoding 字段。对于同一个 type,还可能对应不同的 encoding,这说明同样的一个数据类型,可能存在不同的内部表示方式。而不同的内部表示,在内存占用和查找性能上会有所不同。

当 type = OBJ_STRING 的时候,表示这个 robj 存储的是一个 string,这时 encoding 可以是下面 3 种中的一种:

OBJ_ENCODING_RAW: string 采用原生的表示方式,即用 sds 来表示。

OBJ_ENCODING_INT: string 采用数字的表示方式,实际上是一个 long 型。

OBJ_ENCODING_EMBSTR: string 采用一种特殊的嵌入式的 sds 来表示。

当 type = OBJ_HASH 的时候,表示这个 robj 存储的是一个 hash,这时 encoding 可以是下面 2 种中的一种:

OBJ_ENCODING_HT: hash 采用一个 dict 来表示。

OBJ_ENCODING_ZIPLIST: hash 采用一个 ziplist 来表示。

encoding 的十种取值如下:

OBJ_ENCODING_RAW: 最原生的表示方式。其实只有 string 类型才会用这个 encoding 值(表示成 sds)。

OBJ_ENCODING_INT: 表示成数字。实际用 long 表示。

OBJ_ENCODING_HT: 表示成 dict。

OBJ_ENCODING_ZIPMAP: 是个旧的表示方式,已不再用。在小于 Redis 2.6 的版本中才有。

OBJ_ENCODING_LINKEDLIST: 也是个旧的表示方式,已不再用。

OBJ_ENCODING_ZIPLIST: 表示成 ziplist。

OBJ_ENCODING_INTSET: 表示成 intset。用于 set 数据结构。

OBJ_ENCODING_SKIPLIST: 表示成 skiplist。用于 sorted set 数据结构。

OBJ_ENCODING_EMBSTR: 表示成一种特殊的嵌入式的 sds。

OBJ_ENCODING_QUICKLIST: 表示成 quicklist。用于 list 数据结构。

redisObject 的作用

redisObject 的作用的作用如下:

redisObjec 是联结两个层面的数据结构的桥梁。

为多种数据类型提供一种统一的表示方式。

允许同一类型的数据采用不同的内部表示,从而在某些情况下尽量节省内存。

支持对象共享和引用计数。当对象被共享的时候,只占用一份内存拷贝,进一步节省内存。

关于“redis 的 Object 结构体怎么定义”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注丸趣 TV 行业资讯频道,丸趣 TV 小编每天都会为大家更新不同的知识点。

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-07-13发表,共计2558字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)