源码下载:RedisSourceCodesLearning: redis源码学习 (gitee.com)
1、首先对于redis首先看看在server.h文件里的这个RedisDb:
typedef struct redisDb {
dict *dict; /* The keyspace for this DB */
dict *expires; /* Timeout of keys with a timeout set */
dict *blocking_keys; /* Keys with clients waiting for data (BLPOP)*/
dict *ready_keys; /* Blocked keys that received a PUSH */
dict *watched_keys; /* WATCHED keys for MULTI/EXEC CAS */
int id; /* Database ID */
long long avg_ttl; /* Average TTL, just for stats */
unsigned long expires_cursor; /* Cursor of the active expire cycle. */
list *defrag_later; /* List of key names to attempt to defrag one by one, gradually. */
} redisDb;
RedisDb表示的意思是0~15的某一个数据库,看到id的注解就知道了,每个db就会有dict这个字典,字典有2个一个是dict *dict
,另一个是dict *expires
,dict是记录了key-val的字典,而对于设置了ttl的键,那么怎么存储ttl呢?同样使用key-val键值对存储即可,不过这里的va存储的是ttl罢了,于是这些设置了ttl的键值对就放到expires这个字典里存储。看expires的注解也可以知道了。
2、下面来看看dict.h文件的dict
typedef struct dict {
dictType *type;
void *privdata;
dictht ht[2];
long rehashidx; /* rehashing not in progress if rehashidx == -1 */
int16_t pauserehash; /* If >0 rehashing is paused (<0 indicates coding error) */
} dict;
这里dict就是字典,字典有2个dictht:dictht ht[2]
,这个dictht一个是主用,应该是进行数据迁移时使用的。数据迁移说的就是渐进式哈希。
dictht这玩意是什么?去看看:
3、dict.h文件里的dictht
typedef struct dictht {
dictEntry **table;
unsigned long size;
unsigned long sizemask;
unsigned long used;
} dictht;
这里就有table了,存储的是dictEntry的指针的指针,也就是一个table有很多dictEntry的指针
4、dict.h文件里的dictEntry
typedef struct dictEntry {
void *key;
union {
void *val;
uint64_t u64;
int64_t s64;
double d;
} v;
struct dictEntry *next;
} dictEntry;
看到dictEntry也不是直接存储键和值的数据的,而是存储键值对各自的指针。
5、redisObject
之前看到有robj,这个是什么呢?可以去server.h看看:
typedef struct redisObject {
unsigned type:4;
unsigned encoding:4;
unsigned lru:LRU_BITS; /* LRU time (relative to global lru_clock) or
* LFU data (least significant 8 bits frequency
* and most significant 16 bits access time). */
int refcount;
void *ptr;
} robj;
这个redisObject实际上是value的类型,为什么会有这个呢?我们知道redis的数据是以键值对存储,也就是dictEntry,键的话使用字符串存储即可,也就是用sds,而对于value实际上是有很多类型的,于是需要找一个通用的数据结构来存储value,然后就产生了redisObject.
这个redisObject就是value的通用数据结构。
value有很多类型,那么有什么类型呢?有很多,比如说sds、set、sorted set、hash、ziplist、quicklist、skiplist等。
而这些实际的数据的指针就是ptr,ptr指向实际类型的数据结构。也就是说ptr是多种value的某一种类型。