Redisの数据库设计
redis的结构图如下:
下面,分别对各个数据结构进行介绍
RedisServer
众所周知,redis的配置文件是redis.conf,redis在启动时会加载配置文件。那么配置文件的配置项都加载在哪里呢?
阅读redis源码,会看到Redis将配置文件的配置数据加载到数据结构redisServer,并将所有的数据库保存在db数组中。根据配置文件中的database,决定要创建多少个数据库dbnum。
struct redisServer {
//其余配置...
// 数据库
redisDb *db;
//数据库的数量
int dbnum;
//其余配置...
};
默认情况下,redis会创建16个数据库。
RedisClient
RedisClient的数据结构如下,可以看到,每个Redis客户端都有自己的目标数据库。db是一个指向了redisDb的指针,记录了客户端当前的目标数据库。当执行读、写等命令时,redis客户端就是通过操作目标数据库来执行这些命令的。
当执行select来切换数据库时,redisClent通过修改db指针,让它指向不同的数据库。
struct redisClient {
//其余配置...
// 客户端正在使用的数据库
redisDb *db;
//其余配置...
};
redisDb
redisDb的数据结构如下。dict(字典)保存了这个数据库所有的键值对,称为键空间。本质上,redis是个k-v数据库服务器。
dict和我们见到的数据库是直接对应的,dict可以理解为是个hashtable,它的key是字符串对象,值就是数据库的值,可以是字符串对象、列表对象、哈希表对象、集合或者有序集合,任意一种redis对象。
typedef struct redisDb {
// 数据库键空间,保存着数据库中的所有键值对
dict *dict; /* The keyspace for this DB */
// 键的过期时间,字典的键为键,字典的值为过期事件 UNIX 时间戳
dict *expires; /* Timeout of keys with a timeout set */
// 正处于阻塞状态的键
dict *blocking_keys; /* Keys with clients waiting for data (BLPOP) */
// 可以解除阻塞的键
dict *ready_keys