我们都知道Redis是一种高性能的内存数据库,正是由于它存在于内存中,不像MySQL数据库等存在于磁盘里,Redis常常作为MySQL与我们后端程序之间的中间层来使用。这篇文章就是来谈谈Redis是怎么在内存里存储的。
最上层———数据库结构
Redis作为C语言写出来的内存数据库,它的最上层数据库结构是这样的:
typedef struct redisDb {
dict *dict; // 键空间(核心字典),存储所有键值对
dict *expires; // 过期字典,存储键的过期时间
dict *blocking_keys; // 处于阻塞状态的键(如 BLPOP)
dict *ready_keys; // 解除阻塞的键
dict *watched_keys; // 被 WATCH 命令监视的键(用于事务)
int id; // 数据库编号(0-15)
long long avg_ttl; // 平均生存时间,用于统计
unsigned long expires_cursor; // 过期扫描游标
list *defrag_later; // 后续进行内存碎片整理的键列表
} redisDb;
首先我们最关注的也是最重要的就是键空间dict,它存储了我们使用Redis存储的所有键值对, dict结构源码:
typedef struct dict {
dictType *type; // 类型特定函数
void *privdata; // 私有数据
dictht ht[2]; // 两个哈希表,用于渐进式rehash
long rehashidx; // rehash进度索引,-1表示未进行rehash
unsigned long iterators; // 当前正在运行的迭代器数量
} dict;
其次其中的expires也同样不能忽略,它存储着过期键,如果你给某个键值对设置了过期时间,那么这个时间戳就会存储在expires(当然expirse字典里的键还是与dict一样都是指向同一个位置的指针)。
所以我们可以这样来形象化展示: