对象使用
- 使用对象一个好处是:我们可以针对不同的使用场景,为对象设置多种不同的数据结构实现,从而优化对象在不同场景下的使用效率
- 对象系统还实现了基于引用计数技术的内存回收机制
- Redis 通过引用计数技术实现对象共享机制
- Redis 的对象带有访问时间记录信息
- Redis 使用对象来表示数据库中的键和值
RedisObject数据结构
typedef struct redisObject {
unsigned type:4;
unsigned encoding:4;
unsigned lru:LRU_BITS; // LRU_BITS为24
int refcount;
void *ptr;
} robj;
- 类型type
Redis的对象有五种类型,分别是string、hash、list、set和zset,type属性就是用来标识着五种数据类型。type占用4个bit位,其取值和类型对应如下:
#define OBJ_STRING 0
#define OBJ_LIST 1
#define OBJ_SET 2
#define OBJ_ZSET 3
#define OBJ_HASH 4
- 编码类型encoding
Redis对象的编码方式由encoding参数指定,也就是表示ptr指向的数据以何种数据结构作为底层实现
#define OBJ_ENCODING_RAW 0 /* Raw representation */
#define OBJ_ENCODING_INT 1 /* Encoded as integer */
#define OBJ_ENCODING_HT 2 /* Encoded as hash table */
#define OBJ_ENCODING_ZIPMAP 3 /* Encoded as zipmap */
#define OBJ_ENCODING_LINKEDLIST 4 /* Encoded as regular linked list */
#define OBJ_ENCODING_ZIPLIST 5 /* Encoded as ziplist */
#define OBJ_ENCODING_INTSET 6 /* Encoded as intset */
#define OBJ_ENCODING_SKIPLIST 7 /* Encoded as skiplist */
#define OBJ_ENCODING_EMBSTR 8 /* Embedded sds string encoding */
#define OBJ_ENCODING_QUICKLIST 9 /* Encoded as linked list of ziplists */
Redis的每一种对象类型可以对应不同的编码方式,这就极大地提升了Redis的灵活性和效率。Redis可以根据不同的使用场景,来选择合适的编码方式,五种对象类型对应的底层编码方式如下表所示:
- 访问时间lru
lru表示该对象最后一次被访问的时间,其占用24个bit位。保存该值的目的是为了计算该对象的空转时长,便于后续根据空转时长来决定是否释放该键,回收内存。 - 引用计数refcount
当创建一个对象时,其引用计数初始化为1;
当这个对象被一个新程序使用时,其引用计数加1;
当这个对象不再被一个程序使用时,其引用计数减1;
当引用计数为0时,释放该对象,回收内存。
总结
Redis为用户提供了五种数据结构,分别是string,hash,list,set和zset,每种数据结构的内部都至少有两种编码方式,不同的编码方式适用于不同的使用场景。Redis的对象带有引用计数功能,当一个对象不再被使用时(即引用计数为0),对象所占的内存就会被自动释放。同时,Redis还会对每一个对象记录其最近被使用的时间,从而计算对象的空转时长,便于程序在适当的时候释放内存