# 类型
- 字符串对象
- 列表对象
- 哈希对象
- 集合对象
- 有序集合对象
# 定义
typedef struct redisObject { | |
// 类型 | |
unsigned type:4; | |
// 编码 | |
unsigned encoding:4; | |
// 指向底层数据结构 | |
void *ptr; | |
// 引用计数 | |
int refcount; | |
// 最后一次被访问的时间 | |
unsigned lru:22; | |
} |
# 对象与底层结构
type | encoding |
---|---|
REDIS_STRING | REDIS_ENCODING_INT |
REDIS_STRING | REDIS_ENCODING_EMBSTR |
REDIS_STRING | REDIS_ENCODING_RAW |
REDIS_LIST | REDIS_ENCODING_ZIPLIST |
REDIS_LIST | REDIS_ENCODING_LINKEDLIST |
REDIS_HASH | REDIS_ENCODING_ZIPLIST |
REDIS_HASH | REDIS_ENCODING_HT |
REDIS_SET | REDIS_ENCODING_INTSET |
REDIS_SET | REDIS_ENCODING_HT |
REDIS_ZSET | REDIS_ENCODING_ZIPLIST |
REDIS_ZSET | REDIS_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
# 条件
- 所有字符串元素的长度都小于 64 字节
- 元素数量小于 512 个
# 结构
# REDIS_ENCODING_LINKEDLIST
# 条件
不满足 ziplist 条件的
# 结构
# 哈希对象
# 编码
# REDIS_ENCODING_ZIPLIST
# 条件
- 键和值的字符串长度都小于 64 字节
- 键值对数量小于 512 个
# 结构
# REDIS_ENCODING_HT
# 条件
不满足 ziplist 条件的
# 结构
# 集合对象
# 编码
# REDIS_ENCODING_INTSET
# 条件
- 所有元素都是整数值
- 元素数量不超过 512 个
# 结构
# REDIS_ENCODING_HT
# 条件
不满足 inset 条件的
# 结构
# 有序结合对象
# 编码
# REDIS_ENCODING_ZIPLIST
# 条件
- 元素数量小于 512 个
- 元素长度都小于 64 字节
# 结构
# REDIS_ENCODING_SKIPLIST
# 条件
不满足 ziplist 条件的
# 结构
同时使用跳跃表和字典来实现,字典中键是元素,值是分值,元素何止是字符串对象,跳跃表和字典共享元素和值。
# 类型检查与多态
两种类型命令:
- 可以对任何类型的键执行
- 只能对特定类型的键执行
执行命令前,会检查键的类型是否正确,执行命令时会根据编码类型来调用不同的函数。
# 内存回收
使用引用计数,新创建时初始化为 1,被一个新程序使用时加一,不再被一个程序使用时减一,当计数值变为 0 时,会被释放。
对象生命周期:
- 创建对象
- 操作对象
- 释放对象
# 对象共享
只对包含整数数值的字符串对象进行共享,在初始化服务器时,会创建 0 到 9999 的字符串对象。
如果内存中已有对应对象,则将指针指向它,并把其引用计数加一。
谁可以使用共享对象:
- 字符串键
- 嵌套字符串的对象
- linkedlist 编码的列表对象
- hashtable 编码的哈希对象
- hashtable 编码的集合对象
- zset 编码的有序集合对象
# 对象的空转时长
对象的 lru 字段记录了对象最后一次被命令程序访问的时间。空转时长就是当前时间减去 lru,OBJECT IDLETIME 命令可以获取到空转时长。