redis源码解析(1):redisObject对象说明

Redis在实现键值对数据库时,并没有直接使用数据结构,而是基于已有的数据结构创建了一个对象系统,每种对象至少包含一种数据结构。

redis3.0 中对象结构:

typedef struct redisObject {
    unsigned type:4;
    unsigned encoding:4;
    unsigned lru:REDIS_LRU_BITS; /* lru time (relative to server.lruclock) */
    int refcount;
    void *ptr;
} robj;

这个系统包含字符串对象,列表对象,哈希对象,集合对象和有序集合对象5中类型的对象。

使用对象有什么好处?

1:根据对象的类型来判断一个对象是否可以执行给定的命令。

2:针对不同的数据场景,为对象设置多种不同的数据结构实现,从而优化在不同场景的使用效率。

3:对象系统还实现了基于应用计数的内存回收机制

4:Redis的对象带有访问时间记录的信息,如果该键的空转时长较大那么会优先删除掉


对象中的 type 类型:

/* Object types */
#define REDIS_STRING 0   /*字符串对象*/
#define REDIS_LIST 1     /*列表对象*/
#define REDIS_SET 2      /*集合对象*/
#define REDIS_ZSET 3     /*有序集合对象*/
#define REDIS_HASH 4     /*哈希对象*/

可以用 type 命令查看对象的类型


encoding 编码:

#define REDIS_ENCODING_RAW 0     /* Raw representation 简单动态字符串*/
#define REDIS_ENCODING_INT 1     /* Encoded as integer long 类型的整数*/
#define REDIS_ENCODING_HT 2      /* Encoded as hash table 字典*/
#define REDIS_ENCODING_ZIPMAP 3  /* Encoded as zipmap 压缩map*/
#define REDIS_ENCODING_LINKEDLIST 4 /* Encoded as regular linked list 双端链表*/
#define REDIS_ENCODING_ZIPLIST 5 /* Encoded as ziplist 压缩列表*/
#define REDIS_ENCODING_INTSET 6  /* Encoded as intset 整数集合*/
#define REDIS_ENCODING_SKIPLIST 7  /* Encoded as skiplist 跳跃表*/
#define REDIS_ENCODING_EMBSTR 8  /* Embedded sds string encoding embstr编码的简单动态字符串*/

raw 编码 和 embstr编码的区别:

1:如果字符串对象保存都是一个字符串值,并且这个字符串值长度小于等于32字节,那么使用embstr编码方式保存值,也就是说 embstr是用来保存短字符串的值

这样做有什么好处呢?

1:raw编码会调用2次内存分配函数分别创建redisObject结构和sdshdr结构, 而embstr编码则通过调用 1 次内存分配函数分配一块连续的空间,空间会包含redisObject和sdshdr结构。

2:那么释放的时候raw要释放2次, 而embstr只释放一次内存空间。


refcount 属性:

Redis为对象系统构建了一个引用计数,就是这个字段,目的是来实现内存回收机制。


ptr 属性:

存储的值


lru 属性:

这个属性记录了对象最后一次呗命令程序访问的时间

我们可以用这个属性来计算给定键多长时间没有被访问了。

命令: object idletime 健名

还有一个用处:

如果服务器设置打开了maxmemory选项,并且服务器回收内存算法为volatile-lru或者allkeys-lru,那么当服务器的内存超过了maxmemory设置的上限时,没有被访问的时间越长的键就越有限被服务器释放,从而回收内存

原文地址:https://www.cnblogs.com/jiujuan/p/10514246.html