Redis存储模型详解

x33g5p2x  于11个月前 转载在 Redis  
字(1.8k)|赞(0)|评价(0)|浏览(160)

简介

Redis是一个基于Key-Value的内存模型。

Key的数据类型只有string,Value有String、Hash、Set、List、Zset五种类型。

存储模型详解

1、redisServer

RedisServer中对应着redisServer的对象,一个redisServer中可以存在多个数据库实例。

struct redisServer {
    // ...
    
    // redisDb数组,一个redisDb代表着一个redis数据库
    redisDb *db;
    
    // 一个RedisServer中包含的redis数据库个数,可以自定义,默认是16
    int dbnum;
    
};

2、redisDb

一个redisDb对应着一个redis数据库实例。

typedef struct redisDb {
    //词典,内部使用了hash表的结构,用来存放数据
    dict *dict;                 
    //词典,用来存放key的过期时间数据
    dict *expires;              
    
    dict *blocking_keys;        /* Keys with clients waiting for data (BLPOP)*///一些同步的keys
    dict *ready_keys;           /* Blocked keys that received a PUSH */
    dict *watched_keys;         /* WATCHED keys for MULTI/EXEC CAS */
    //redisDb的编号
    int id;                     /* Database ID */Redis默认有16个数据库
    long long avg_ttl;          /* Average TTL, just for stats */
} redisDb;

3、dict

dict中存放了一个dictht数组,长度为2。dictht是一个哈希表。ht[0]用来存放当前数据,ht[1]用于扩容和收缩。

typedef struct dict {
    // 特定于类型的处理函数
    dictType *type;

    // 类型处理函数的私有数据
    void *privdata;

    // 哈希表(2 个),ht[0]用来存放当前数据,ht[1]用于扩容和收缩。
    dictht ht[2];

    // 记录 rehash 进度的标志,值为 -1 表示 rehash 未进行
    int rehashidx;

    // 当前正在运作的安全迭代器数量
    int iterators;
} dict;

4、dictht

dictht是一个哈希表,对应的节点叫做dictEntry。

typedef struct dictht {

    // 哈希表节点
    dictEntry **table;

    // 哈希表的大小
    unsigned long size;

    // size-1,将hashcode和sizemask做&,达到快速取模的效果,就得到存储的下标
    unsigned long sizemask;

    // 存储元素个数
    unsigned long used;

} dictht;

5、dictEntry

具体存放数据的实际节点,里面存放了key和val。

typedef struct dictEntry {
    // 键
    void *key;

    // 值
    union {
        void *val;
        uint64_t u64;
        int64_t s64;
    } v;

    // 后继节点,当发生hash冲突的时候,用于拉链
    struct dictEntry *next;
} dictEntry;

6、redisObject

typedef struct redisObject {

    //数据类型
    unsigned type:4;

    //数据编码
    unsigned encoding:4;

    // 对象最后一次被访问的时间
    unsigned lru:REDIS_LRU_BITS; 

    // 引用计数
    int refcount;

    // 没有直接存放数据,而是数据的指针
    void *ptr;

} robj;

总结

1、redisServer: redis服务器,默认包含了16个redis数据库实例。

2、redisDb: redis数据库实例,包含了了两个词典dict,一个是实际数据词典dict、一个是过期时间词典expires。

3、dict: 词典,用来存放数据,是对哈希表dictht的一个包装。因为涉及到扩容和收缩, 包含了一个长度为2的dictht[],ht[0]负责存放数据,ht[1]负责扩容和收缩。

4、dictht: 哈希表,用来存放数据。利用拉链法来解决哈希冲突。对应的底层节点是dictEntry

5、dictEntry: 哈表表节点。包含了一个key和value,还有后继节点,用于拉链。

6、redisObject: 用来存放value,包含了value的数据类型,编码格式、引用数、以及具体数据的存放指针。

相关文章

热门文章

更多