美文网首页
Redis源码研究之redisObject

Redis源码研究之redisObject

作者: wenmingxing | 来源:发表于2018-04-26 14:41 被阅读43次

本文主要说明Redis key-value结构中封装五种value的redisObject结构。

I、上帝视角

redisObject结构主要说明value对象的底层编码方式,以及实际指向等内容:

/*src/redis.h/redisObject */
typedef struct redisObject {
    // 刚刚好32 bits
    // 对象的类型,字符串/列表/集合/哈希表
    unsigned type:4;
    // 未使用的两个位
    unsigned notused:2; /* Not used */

    // 编码的方式,Redis 为了节省空间,提供多种方式来保存一个数据
    // 譬如:“123456789” 会被存储为整数123456789
    unsigned encoding:4;

    // 当内存紧张,淘汰数据的时候用到
    unsigned lru:22; /* lru time (relative to server.lruclock) */

    // 引用计数
    int refcount;

    // 数据指针,指向真正的数据
    void *ptr;
} robj;  

下面对以上属性进行一一说明。

II、type属性

redisObject数据结构将对象属性与对象的数据分开,这样做有良好的特性,可以先根据属性进行检查判断等操作,这些都不需要直接访问数据本身。

其中type属相标记了value对象的数据类型:

/* Object types */
#define REDIS_STRING 0
#define REDIS_LIST 1
#define REDIS_SET 2
#define REDIS_ZSET 3
#define REDIS_HASH 4  

III、encoding属性

Redis为优化内存,对每种type类型都至少会有两种底层实现方式,如zset就可以是ziplist与skiplist。

redisObject结构中的encoding属性就标记了对象使用的是那种底层数据结构:

/* Objects encoding. Some kind of objects like Strings and Hashes can be
* internally represented in multiple ways. The 'encoding' field of the object
* is set to one of this fields for this object. */
#define REDIS_ENCODING_RAW 0 /* Raw representation */
#define REDIS_ENCODING_INT 1 /* Encoded as integer */
#define REDIS_ENCODING_HT 2 /* Encoded as hash table */
#define REDIS_ENCODING_ZIPMAP 3 /* Encoded as zipmap,已经淘汰 */
#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 */    

IV、refcount属性

Redis中为了更好的优化内存空间,对数字字符串进行了共享内存的操作,并以引用计数方式进行管理。

下面的函数为增加引用及减少应用的操作:

// 增加 Redis 对象引用
void incrRefCount(robj *o) {
    o->refcount++;
 }
// 减少 Redis 对象引用。需要判断是否需要进行析构
void decrRefCount(robj *o) {
    if (o->refcount <= 0) redisPanic("decrRefCount against refcount <= 0");
    // 如果取消的是最后一个引用,则释放资源
    if (o->refcount == 1) {
    // 不同数据类型,销毁操作不同
    switch(o->type) {
        case REDIS_STRING: freeStringObject(o); break;
        case REDIS_LIST: freeListObject(o); break;
        case REDIS_SET: freeSetObject(o); break;
        case REDIS_ZSET: freeZsetObject(o); break;
        case REDIS_HASH: freeHashObject(o); break;
        default: redisPanic("Unknown object type"); break;
    }
    zfree(o);
  } else {
      o->refcount--;
  }
}  

对于这里的引用计数来说,因为Redis是单线程工作模式的,所以引用计数的增加和减少不比保证原子性

V、lru属性

Redis对数据集占用内存的大小由周期性的计算,当超出限制时,会淘汰超时的数据。即淘汰的标准为:oversize & overtime。

【参考】
[1] 《Redis设计与实现》
[2] 《Redis源码日志》

相关文章

  • Redis源码研究之redisObject

    本文主要说明Redis key-value结构中封装五种value的redisObject结构。 I、上帝视角 r...

  • Redis源码剖析之robj(redisObject)

    我们在之前的文章[https://xindoo.blog.csdn.net/article/details/108...

  • 基本数据类型

    redisObject redis中用redisObject包装数据类型,其中 type:表示redis对外支持的...

  • [redis 源码走读] 对象(redisObject)

    redis 对象 redis 对数据的处理用对象进行管理,目前有5种类型。每种对象类型并不是用单一的编码类型实现,...

  • Redis 存储对象信息是用 Hash 还是 String

    Redis 内部使用一个 RedisObject 对象来表示所有的 key 和 value,RedisObject...

  • Redis redisObject

    简介 redisObjet其实就是对应用类型的封装。简介面向对象的思想。实现对数据的统一管理保存 数据结构 这一块...

  • Redis内存优化

    一.redisObject对象 Redis存储的所有值对象在内部定义为redisObject结构体,内部结构如下图...

  • Redis 源码研究之dict

    本文主要记录在阅读Redis源码中dict部分的一些函数和实现的巧妙之处。 建议阅读: 1、Redis字典实现的理...

  • Redis 源码研究之skiplist

    本文主要记录Redis源码中skiplist数据结构的一些函数实现。 建议阅读: 1、Redis中跳跃表的理论说...

  • redis zset内部实现

    Redis对象Redis对象由redisObject结构体表示。 Redis中的每个键值对的键和值都是一个redi...

网友评论

      本文标题:Redis源码研究之redisObject

      本文链接:https://www.haomeiwen.com/subject/dhoplftx.html