redis数据结构_Redis数据结构(下)

之前两篇我们已经介绍完了Redis大部分的数据结构,本篇我们来分析一下剩余的两种数据结构:
  1. 压缩列表

  2. 对象

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

da9666b6bc776c4b2b9f92507f6f7623.png

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

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

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

最后是对象,前面我们讲了Redis的数据结构,Redis不是用这些数据结构直接实现Redis的键值对数据库,而是基于这些数据结构创建了一个对象系统。包含字符串对象,列表对象,哈希对象,集合对象和有序集合对象。根据对象的类型可以判断一个对象是否可以执行给定的命令,也可针对不同的使用场景,对象设置有多种不同的数据结构实现,从而优化对象在不同场景下的使用效率。Redis中的每个对象都是由如下结构表示(列出了与保存数据有关的三个属性):
typedef struct redisObject {        unsigned type:4;//类型 五种对象类型        unsigned encoding:4;//编码        void *ptr;//指向底层实现数据结构的指针        //...        int refcount;//引用计数        //...        unsigned lru:22;//记录最后一次被命令程序访问的时间     //...}robj;
type 字段表示对象的类型,占 4 个比特,目前包括 REDIS_STRING(字符串)、REDIS_LIST (列表)、 REDIS_HASH(哈希)、REDIS_SET(集合)、REDIS_ZSET(有序集合)。当我们执行 type 命令时,便是通过读取 RedisObject 的 type 字段获得对象的类型,如下所示:
127.0.0.1:6379> type a1 string
encoding 表示对象的内部编码,占 4 个比特。对于 Redis 支持的每种类型,都有至少两种内部编码,例如对于字符串,有 int、embstr、raw 三种编码。通过 encoding 属性,Redis 可以根据不同的使用场景来为对象设置不同的编码,大大提高了 Redis 的灵活性和效率。以列表对象为例,有压缩列表和双端链表两种编码方式,如果列表中的元素较少,Redis 倾向于使用压缩列表进行存储,因为压缩列表占用内存更少,而且比双端链表可以更快载入。当列表对象元素较多时,压缩列表就会转化为更适合存储大量元素的双端链表。通过 object encoding 命令,可以查看对象采用的编码方式,如下所示:
127.0.0.1:6379> object encoding a1 "int"
lru 记录的是对象最后一次被命令程序访问的时间,占据的比特数不同的版本有所不同(如 4.0 版本占 24 比特,2.6 版本占 22 比特)。通过对比 lru 时间与当前时间,可以计算某个对象的空转时间,object idletime 命令可以显示该空转时 间(单位是秒)。object idletime 命令的一个特殊之处在于它不改变对象的 lru 值。lru 值除了通过 object idletime 命令打印之外,还与 Redis 的内存回收有关系。如果 Redis 打开了 maxmemory 选项,且内存回收算法选择的是 volatile-lru 或 allkeys—lru,那么当

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

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

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

127.0.0.1:6379> object refcount a1 (integer) 2147483647
ptr 指针指向具体的数据,比如:set hello world,ptr 指向包含字符串 world 的 SDS。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值