服务器中的数据库
Redis服务器将所有数据库都保存在服务器状态redis.h/redisServer结构的db数组中,db数组的每个项都是一个redis.h/redisDb结构,每个redisDb结构代表一个数据库。
struct redisServer {
// ```
// 一个数组,保存着服务器中的所有数据库
redisDb *db;
// ```
};
在初始化服务器时,程序会根据服务器状态的dbnum属性来决定应该创建多少个数据库:
struct redisServer {
// ```
// 服务器的数据库数量
int dbnum;
// ```
};
dbnum属性的值由服务器配置的database选项决定,默认情况下,该选项的值为16,所以Redis服务器默认会创建16个数据库。
切换数据库
每个Redis客户端都有自己的目标数据库,每当客户端执行数据库写命令或者数据库读命令的时候,目标数据库就会成为这些命令的操作对象。
默认情况下,Redis客户端的目标数据库为0号数据库,但客户端可以通过执行SELECT命令来切换目标数据库。
读写键空间时的维护操作
当使用Redis命令对数据库进行读写时,服务器不仅会对键空间执行指定的读写操作,还会执行一些额外的维护操作,其中包括:
- 在读取一个键之后,服务器会根据键是否存在来更新服务器的键空间命中次数或键空间不命中次数。
- 在读取一个键之后,服务器会更新键的LRU时间,这个值可以用于计算键的闲置时间。
- 如果服务器在读取一个键时发现该键已经过期,那么服务器会先删除这个过期键,然后才执行余下的其他操作。
- 如果客户端使用WATCH命令监视了某个键,那么服务器在对被监视的键进行修改之后,会将这个键标记为脏,从而让事务程序注意到这个键已经被修改过。
设置键的生存时间或过期时间
通过EXPIRE命令或者PEXPIRE命令,客户端可以以秒或者毫秒精度为数据库中的某个键设置生存时间,在经过指定的秒数或者毫秒树之后,服务器就会自动删除生存时间为0的键。
保存过期时间
redisDb结构的expires字典保存了数据库中所有键的过期时间,我们称这个字典为过期字典。
过期键的判定
通过过期字典,程序可以用以下步骤检查一个给定键是否过期:
(1)、检查给定键是否存在于过期字典,如果存在,那么取得键的过期时间
(2)、检查当前UNIX时间戳是否大于键的过期时间,如果是的话,那么键已经过期,否则的话,键未过期
过期键删除策略
过期键的删除策略分为三种:
- 定时删除:在设置键的过期时间的同时,创建一个定时器,让定时器在键的过期时间来临时立即执行对键的删除操作。
- 惰性删除:放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键;如果没有过期,就返回该键。
- 定期删除:每隔一段时间,程序就会数据库进行一次检查,删除里面的过期键。至于要删除多少过期键,以及要检查多少个数据库,则有算法决定。
Redis的过期键删除策略
Redis服务器实际使用的是惰性删除和定期删除两种策略:通过配合使用这两种删除策略,服务器可以很好地在合理使用CPU时间和避免浪费内存空间之间取得平衡。