铜仁市论坛

首页 » 分类 » 定义 » Redis数据结构下
TUhjnbcbe - 2020/12/21 14:25:00
之前两篇我们已经介绍完了Redis大部分的数据结构,本篇我们来分析一下剩余的两种数据结构:

压缩列表

对象

压缩列表(ziplist)是列表键和哈希键的底层实现之一。当一个列表只包含少量列表项时,并且每个列表项是小整数值或短字符串,那么Redis会使用压缩列表来做该列表的底层实现。压缩列表(ziplist)是Redis为了节省内存而开发的,是由一系列特殊编码的连续内存块组成的顺序型数据结构,一个压缩列表可以包含任意多个节点(entry),每个节点可以保存一个字节数组或者一个整数值。压缩列表的数据结构定义如下:

previous_entry_ength:记录压缩列表前一个字节的长度。

encoding:节点的encoding保存的是节点的content的内容类型

content:content区域用于保存节点的内容,节点内容类型和长度由encoding决定。

最后是对象,前面我们讲了Redis的数据结构,Redis不是用这些数据结构直接实现Redis的键值对数据库,而是基于这些数据结构创建了一个对象系统。包含字符串对象,列表对象,哈希对象,集合对象和有序集合对象。根据对象的类型可以判断一个对象是否可以执行给定的命令,也可针对不同的使用场景,对象设置有多种不同的数据结构实现,从而优化对象在不同场景下的使用效率。Redis中的每个对象都是由如下结构表示(列出了与保存数据有关的三个属性):

typedefstructredisObject{unsignedtype:4;//类型五种对象类型unsignedencoding:4;//编码void*ptr;//指向底层实现数据结构的指针//...intrefcount;//引用计数//...unsignedlru:22;//记录最后一次被命令程序访问的时间//...}robj;type字段表示对象的类型,占4个比特,目前包括REDIS_STRING(字符串)、REDIS_LIST(列表)、REDIS_HASH(哈希)、REDIS_SET(集合)、REDIS_ZSET(有序集合)。当我们执行type命令时,便是通过读取RedisObject的type字段获得对象的类型,如下所示:

.0.0.1:typea1stringencoding表示对象的内部编码,占4个比特。对于Redis支持的每种类型,都有至少两种内部编码,例如对于字符串,有int、embstr、raw三种编码。通过encoding属性,Redis可以根据不同的使用场景来为对象设置不同的编码,大大提高了Redis的灵活性和效率。以列表对象为例,有压缩列表和双端链表两种编码方式,如果列表中的元素较少,Redis倾向于使用压缩列表进行存储,因为压缩列表占用内存更少,而且比双端链表可以更快载入。当列表对象元素较多时,压缩列表就会转化为更适合存储大量元素的双端链表。通过objectencoding命令,可以查看对象采用的编码方式,如下所示:

.0.0.1:objectencodinga1"int"lru记录的是对象最后一次被命令程序访问的时间,占据的比特数不同的版本有所不同(如4.0版本占24比特,2.6版本占22比特)。通过对比lru时间与当前时间,可以计算某个对象的空转时间,objectidletime命令可以显示该空转时间(单位是秒)。objectidletime命令的一个特殊之处在于它不改变对象的lru值。lru值除了通过objectidletime命令打印之外,还与Redis的内存回收有关系。如果Redis打开了maxmemory选项,且内存回收算法选择的是volatile-lru或allkeys—lru,那么当

Redis内存占用超过maxmemory指定的值时,Redis会优先选择空转时间最长的对象进行释放。

refcount记录的是该对象被引用的次数,类型为整型。refcount的作用,主要在于对象的引用计数和内存回收。当创建新对象时,refcount初始化为1,当有新程序使用该对象时,refcount加1,当对象不再被一个新程序使用时,refcount减1,当refcount变为0时,对象占用的内存会被释放。Redis中被多次使用的对象(refcount1),称为共享对象。Redis为了节省内存,当有一些对象重复出现时,新的程序不会创建新的对象,而是仍然使用原来的对象。这个被重复使用的对象,就是共享对象。目前共享对象仅支持整数值的字符串对象。共享对象的引用次数可以通过objectrefcount命令查看,如下所示。命令执行的结果页佐证了只有

0~之间的整数会作为共享对象。

.0.0.1:objectrefcounta1(integer)ptr指针指向具体的数据,比如:sethelloworld,ptr指向包含字符串world的SDS。预览时标签不可点收录于话题#个上一篇下一篇

1
查看完整版本: Redis数据结构下