- redis的存储结构从外层往内层依次是redisServer、redisDb、dict、dictht、dictEntry。
- redis的Db默认情况下有16个,每个redisDb内部包含一个dict的数据结构。
- redis的dict内部包含dictht的数组,数组个数为2,主要用于hash扩容使用。
- dictht内部包含dictEntry的数组,可以理解就是hash桶,然后使用链地址法解决冲突。
redisServer的结构如下:struct redisServer { /* General */ //Absolute config file path, or NULL -- 配置文件的绝对路径 char *configfile; //serverCron() calls frequency in hertz -- serverCron()每秒调用的次数 int hz; redisDb *db; // 其他属性 }
redisDb主要包含dict *dict和dict expire两个字典,前者用于保存所有的键值对,后者用于保存键的过期时间,使用TTL指令时,就会从这个字典中去拿对应的失效时间,结构如下:
typedef struct redisDb { //数据字典,保存着数据库中的所有键值对 dict *dict; //过期字典,字典的值为键的过期时间,是一个UNIX时间戳 dict *expires; //正处于阻塞状态的键 dict *blocking_keys; //可以解除阻塞的键 dict *ready_keys; //正在被 WATCH 命令监视的键 dict *watched_keys; //失效池,根据对象lru时间戳保存要被淘汰的对象 struct evictionPoolEntry *eviction_pool; int id; //数据库的键的平均 TTL ,统计信息 long long avg_ttl; } redisDb;
dict字典主要包含dictht数组,它用于存储数据,数组大小为2,其中一个在扩容时使用,结构如下:
typedef struct dict { //类型特定函数 dictType *type; //私有数据 void *privdata; //哈希表 dictht ht[2]; //rehash 索引,当rehash不在进行时,值为 -1 int rehashidx; //目前正在运行的安全迭代器的数量 int iterators; } dict;
dictht是hash表,保存数据的核心数据结构,主要包含dicEntry **table数组,结构如下:
typedef struct dictht { //哈希表数组 dictEntry **table; //哈希表大小 unsigned long size; //哈希表大小掩码,用于计算索引值,总是等于 size - 1 unsigned long sizemask; // 该哈希表已有节点的数量 unsigned long used; } dictht;
dictEntry是字典实体,用于保存设置的键值对对象,key和v都是指向redisobj的指针,结构如下:
typedef struct dictEntry{ //键 void *key; //值 union { void *val; uint64_t u64; int64_t s64; } v; //指向下个哈希表节点的指针 struct dictEntry *next; } dictEntry;
redisObj是redis中最原子的数据结构,一共占据4bits+4bits+24bits+4bytes+8bytes = 16bytes大小,结构如下:
typedef struct redisObject { //类型(REDIS_STRING、REDIS_LIST、REDIS_HASH、REDIS_SET、REDIS_ZSET) int4 type; //存储格式 int4 encoding; //记录LRU信息 int24 lru; //引用次数 int32 refcount; //指向对象的值的指针 void *ptr; } redisObject;
根据上述分析,整个存储结构图如下:
Redis存储结构
最新推荐文章于 2024-05-09 16:48:50 发布