Redis 对象

0、对象

Redis 没有直接使用基本数据结构来实现键值对数据库,而是基于这些数据结构创建了一个对象系统:

  • 字符串对象
  • 列表对象
  • 哈希对象
  • 集合对象
  • 有序集合对象

使用对象的优点:

  • 可以在执行命令前,根据对象的类型来判断一个对象是否可以执行给定的命令。
  • 可以针对不同的使用场景,为对象设置多种不同的数据结构实现,从而优化效率。
  • Redis 的对象系统实现了基于引用计数技术的内存回收机制
  • Redis 的对象系统实现了基于引用计数技术的对象共享机制,这一机制可以在适当的条件下,通过让多个数据库共享同一个对象来节约内存。
  • Redis 对象带有访问时间记录信息,在服务器启用了 maxmemory 功能的情况下,空转时长较大的键可能会优先被服务器删除。
对象定义
typedef struct redisObject {
    // 类型
    unsigned type:4;
    // 编码
    unsigned encoding:4;
    // 引用计数
    int refcount;
    unsigned lru;
    // 指向底层实现数据结构的指针
    void *ptr;
} robj;
类型
类型常量对象的名称TYPE 命令的输出
REDIS_STRING字符串对象“string”
REDIS_LIST列表对象“list”
REDIS_HASH哈希对象“hash”
REDIS_SET集合对象“set”
REDIS_ZSET有序集合对象“zset”
编码
编码常量编码所对应的底层数据结构OBJECT ENCODING 命令输出
REDIS_ENCODING_INTlong 类型的整数“int”
REDIS_ENCODING_EMBSTRembstr 编码的 SDS“embstr”
REDIS_ENCODING_RAWSDS“raw”
REDIS_ENCODING_HT字典“hashtable”
REDIS_ENCODING_LINKEDLIST双端列表“linkedlist”
REDIS_ENCODING_ZIPLIST压缩列表“ziplist”
REDIS_ENCODING_INTSET整数集合“intset”
REDIS_ENCODING_SKIPLIST跳跃表和字典“skiplist”
类型与编码对象
类型编码
REDIS_STRINGREDIS_ENCODING_INT
REDIS_ENCODING_EMBSTR
REDIS_ENCODING_RAW
REDIS_LISTREDIS_ENCODING_ZIPLIST
REDIS_ENCODING_LINKEDLIST
REDIS_HASHREDIS_ENCODING_ZIPLIST
REDIS_ENCODING_HT
REDIS_SETREDIS_ENCODING_INTSET
REDIS_ENCODING_HT
REDIS_ZSETREDIS_ENCODING_ZIPLIST
REDIS_ENCODING_SKIPLIST

在这里插入图片描述

1、字符串对象

编码
  • int
  • embstr(字符串长度小于等于 32 字节)
  • raw(字符串长度大于 32 字节)
embstr 和 raw

embstr 编码是专门用于保存短字符串的一种优化编码方式。

两者都使用 redisObject 结构和 sdshdr 结构来表示字符串对象。

raw 编码会调用两次内存分配函数来分别创建 redisObject 结构和 sdshdr 结构。

embstr 编码调用一次内存分配函数来分配一块连续的空间,空间中依次包括 redisObject 和 sdshdr,连续的空间使得更好地利用缓存带来的优势。

释放内存时,同上。

在这里插入图片描述

编码转换
  • int 编码的字符串对象和 embstr 编码的字符串对象在条件满足的情况下,会被转换为 raw 编码的字符串对象。
  • embstr 编码的字符串没有修改程序,一旦被修改,就会转换成 raw 编码的字符串对象。

在这里插入图片描述

2、列表对象

编码
  • ziplist
  • linkedlist
编码转换

同时满足以下两个条件时,使用 ziplist 编码:

  • 所有元素长度小于 64 字节
  • 元素数量小于 512 个

list-max-ziplist-value

list-max-ziplist-entries

在这里插入图片描述

3、哈希对象

编码
  • ziplist
  • hashtable
编码转换

同时满足以下两个条件时,使用 ziplist 编码:

  • 所有元素长度小于 64 字节
  • 元素数量小于 512 个

hash-max-ziplist-value

hash-max-ziplist-entries

在这里插入图片描述

4、集合对象

编码
  • intset
  • hashtable
编码转换

同时满足以下两个条件时,使用 intset 编码:

  • 所有元素都是整数值

  • 元素数量小于 512 个

set-max-intset-entries

在这里插入图片描述
在这里插入图片描述

5、有序集合对象

编码
  • ziplist
  • skiplist
skiplist 编码的有序集合

使用 zset 结构作为底层实现。

typedef struct zset {
    zskiplist *zsl;
    dict *dict;
} zset;
// 两种数据结构通过指针来共享相同元素的成员和分值,所以不会浪费额外的内存。

在这里插入图片描述

编码转换

同时满足以下两个条件时,使用 ziplist 编码:

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

zset-max-ziplist-value

zset-max-ziplist-entries

在这里插入图片描述

类型检查与命令多态

在这里插入图片描述

类型检查通过 redisObject 结构的 type 属性来实现。

命令多态通过 redisObject 结构的 encoding 属性来实现。

在这里插入图片描述

对象共享

Redis 会在初始化服务器时,创建一万个字符串对象,包含了从 0 到 9999 的所有整数值。创建字符串对象的数量可以通过 redis.h/REDIS_SHARED_INTEGERS 常量来修改。

Redis 只共享整数值的字符串对象。

查看对象的引用计数:object refcount key

对象的空转时长

查看对象的空转时长:object idletime key

如果服务器打开了 maxmemory 选项,并且服务器用于回收内存的算法为 volatile-lru 或者 allkeys-lru,当占用内存超过 maxmemory 时,空转时长较高的键会被服务器释放,从而回收内存。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值