跳到主要内容

redisObject

2025年01月15日
柏拉文
越努力,越幸运

一、认识


Redis 的内部实现中,redisObjectRedis 用来表示键和值的一种抽象数据结构。每个键值对的值在 Redis 中都被包装为一个 redisObject,以便支持不同类型的数据和优化存储与操作。在 RedisC 源码中,redisObject 的定义类似如下(以 Redis 6.x 为例,具体实现可能会因版本不同有所变化):

typedef struct redisObject {
unsigned type:4; // 对象的类型,如字符串、列表、集合等
unsigned encoding:4; // 数据的编码方式,如原始字符串、压缩列表等
unsigned lru:LRU_BITS; // 最近一次被访问的时间,用于 LRU 机制
int refcount; // 引用计数,用于内存管理
void *ptr; // 指向实际数据的指针
} robj;
  • type: 描述对象的类型,例如:

    • REDIS_STRING:字符串类型。

    • REDIS_LIST:列表类型。

    • REDIS_SET:集合类型。

    • REDIS_ZSET:有序集合类型。

    • REDIS_HASH:哈希类型。

  • encoding: 描述对象的数据编码方式,常见的值包括:

    • RAW:原始字符串。

    • INT:整数值。

    • EMBSTR:优化的小字符串。

    • ZIPLIST:压缩列表(用于小型列表或哈希)。

    • HT:哈希表(用于大型哈希或集合)。

    • SKIPLIST:跳跃表(用于有序集合)。

  • lru: 存储对象最后一次被访问的时间戳,用于 Redis 的内存管理策略(如 LRU 驱逐策略)。

  • refcount: 引用计数,用于实现对象的共享和内存管理。当引用计数为 0 时,Redis 会释放该对象。

  • ptr: 指向实际数据的指针,例如,字符串的具体值、哈希表的结构等。

Redis 工作流为: 假设在 Redis 中设置一个字符串 set key hello, 在 Redis 内部, 创建一个 redisObject,类型为 REDIS_STRING, 使用适当的编码(如 EMBSTRRAW)存储字符串 hello。将 redisObject 存储在 Redis 的全局字典中,键为 key

RedisredisObject 是优化性能和内存使用的核心: 使用不同的编码(如整数编码、压缩列表)根据数据大小选择最佳存储方式。使用引用计数减少重复对象的内存开销(如 SETNX 操作中多个键共享相同值)。