Redis数据库结构
源码:server.h 在server.h里有个redisServer 结构,它的属性db数组,存储数据库信息
struct redisServer {
...
redisDb *db;
int dbnum;
...
};
切换数据库:
127.0.0.1:6379> set msg hello
OK
127.0.0.1:6379> get msg
"hello"
127.0.0.1:6379[2]> select 1
OK
127.0.0.1:6379[1]> get msg
(nil)
127.0.0.1:6379[1]> select 0
OK
127.0.0.1:6379> get msg
"hello"
每个client都一个db属性指向redisDb。
结构图:
redisDb属性:
typedef struct redisDb {
dict *dict;
dict *expires;
dict *blocking_keys;
dict *ready_keys;
dict *watched_keys;
int id;
long long avg_ttl;
unsigned long expires_cursor;
list *defrag_later;
clusterSlotToKeyMapping *slots_to_keys;
} redisDb;
dict字典保存数据库的所有键值对,叫做键空间。key是数据库的键,是字符串对象,键空间的值也是数据库中键的值对象(可以是列表,哈希表等)。
结构图:
对键的增删改查都是操作的键空间。
查询的时候发现键过期了,会先删除。watch了摸个键,键被修改的时候会标记为脏(dirty)。
设置过期键和查看过期事件:
127.0.0.1:6379> ttl msg
(integer) -1
127.0.0.1:6379> expire msg 5
(integer) 1
127.0.0.1:6379> ttl msg
(integer) 3
127.0.0.1:6379> ttl msg
(integer) -2
127.0.0.1:6379> get msg
(nil)
expire命令:
redisDb 的expires字典保存键的过期时间。
过期键删除策略: 我们知道过期键的过期时间都保存在过期字典中,那么什么时候删除? 1、定时删除 创建一个定时器,过期就删除 2、惰性删除 过期了不管,再次查询时,检测到过期,再去删除 3、定期删除 每隔一段时间,对数据库进行一次扫描,删除过期的。
db.c的expireIfNeeded函数实现惰性删除。
执行save或bgsave时,会对键进行过期检查,如果过期,就不会保存到rdb中。
载入rdb时,如果是主服务器,也会对键进行过期检查。要是从服务器,不会对过期键进行检查,但是主从同步会清空从数据库的数据。
如果是aof模式,在写入时不会对过期键进行检查,而是等过期后,追加一个DEL命令。载入时会对键进行过期检查。
复制时,主服务器删除一个过期键时,会显示发送给从服务器一个DEL,从服务在遇到过期键时,也不会删除,直到遇到DEL命令才删除。
|