# 类型

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

# 定义

typedef struct redisObject {
    // 类型
    unsigned type:4;
    // 编码
    unsigned encoding:4;
    // 指向底层数据结构
    void *ptr;
    // 引用计数
    int refcount;
    // 最后一次被访问的时间
    unsigned lru:22;
}

# 对象与底层结构

typeencoding
REDIS_STRINGREDIS_ENCODING_INT
REDIS_STRINGREDIS_ENCODING_EMBSTR
REDIS_STRINGREDIS_ENCODING_RAW
REDIS_LISTREDIS_ENCODING_ZIPLIST
REDIS_LISTREDIS_ENCODING_LINKEDLIST
REDIS_HASHREDIS_ENCODING_ZIPLIST
REDIS_HASHREDIS_ENCODING_HT
REDIS_SETREDIS_ENCODING_INTSET
REDIS_SETREDIS_ENCODING_HT
REDIS_ZSETREDIS_ENCODING_ZIPLIST
REDIS_ZSETREDIS_ENCODING_SKIPLIST

# 字符串对象

# type

REDIS_STRING

# 编码

# REDIS_ENCODING_INT

# 条件

可以用 long 类型表示的

# 结构

# REDIS_ENCODING_EMBSTR

# 条件

长度小于等于 32 字节的字符串

# 结构

# 优点
  • redisObject 和 sdshdr 结构内存连续,分配和释放内存时只需执行一次
  • 连续内存可以更好的利用缓存

# REDIS_ENCODING_RAW

# 条件

长度大于 32 字节的字符串

# 结构

# 编码转换

  • int 转 raw,对 int 编码的进行 append 操作,操作后不再是个能用 long 表示的整数
  • embstr 转 raw,对 embstr 做任何修改操作都会转为 raw,因为 embstr 是只读的

# 列表对象

# 编码

# REDIS_ENCODING_ZIPLIST

# 条件
  1. 所有字符串元素的长度都小于 64 字节
  2. 元素数量小于 512 个
# 结构

# REDIS_ENCODING_LINKEDLIST

# 条件

不满足 ziplist 条件的

# 结构

# 哈希对象

# 编码

# REDIS_ENCODING_ZIPLIST

# 条件
  1. 键和值的字符串长度都小于 64 字节
  2. 键值对数量小于 512 个
# 结构

# REDIS_ENCODING_HT

# 条件

不满足 ziplist 条件的

# 结构

# 集合对象

# 编码

# REDIS_ENCODING_INTSET

# 条件
  1. 所有元素都是整数值
  2. 元素数量不超过 512 个
# 结构

# REDIS_ENCODING_HT

# 条件

不满足 inset 条件的

# 结构

# 有序结合对象

# 编码

# REDIS_ENCODING_ZIPLIST

# 条件
  1. 元素数量小于 512 个
  2. 元素长度都小于 64 字节
# 结构

# REDIS_ENCODING_SKIPLIST

# 条件

不满足 ziplist 条件的

# 结构

同时使用跳跃表和字典来实现,字典中键是元素,值是分值,元素何止是字符串对象,跳跃表和字典共享元素和值。

# 类型检查与多态

两种类型命令:

  • 可以对任何类型的键执行
  • 只能对特定类型的键执行

执行命令前,会检查键的类型是否正确,执行命令时会根据编码类型来调用不同的函数。

# 内存回收

使用引用计数,新创建时初始化为 1,被一个新程序使用时加一,不再被一个程序使用时减一,当计数值变为 0 时,会被释放。

对象生命周期:

  1. 创建对象
  2. 操作对象
  3. 释放对象

# 对象共享

只对包含整数数值的字符串对象进行共享,在初始化服务器时,会创建 0 到 9999 的字符串对象。
如果内存中已有对应对象,则将指针指向它,并把其引用计数加一。

谁可以使用共享对象:

  • 字符串键
  • 嵌套字符串的对象
    • linkedlist 编码的列表对象
    • hashtable 编码的哈希对象
    • hashtable 编码的集合对象
    • zset 编码的有序集合对象

# 对象的空转时长

对象的 lru 字段记录了对象最后一次被命令程序访问的时间。空转时长就是当前时间减去 lru,OBJECT IDLETIME 命令可以获取到空转时长。