服务器中的数据库
redis服务器将所有数据库都保存在服务器状态redisServer结构的db数组中,db数组的每个项都是一个redisDb结构,每个redisDb结构代表一个数据库:
struct redisServer {
//...
//一个数组,保存着服务器中所有数据库
redisDb *db;
// 服务器的数据库数量
int dbnum;
//...
}
在初始化服务器时,程序会根据服务器状态的dbnum属性来决定创建多少个数据库。
默认情况下,dbnum属性的值为16。
切换数据库
每个redis客户端都有自己的目标数据库,每当客户端执行数据库写命令或者数据库读命令的时候,目标数据库就会成为这些命令的操作对象。
默认情况下,redis客户端的目标数据库为0号数据库,但客户端可以通过执行SELECT命令来切换目标数据库。
客户端状态redisClient结构的db属性记录了客户端当前的目标数据库,这个属性是一个指向redisDb结构的指针:
typedef struct redisClient {
//...
//记录客户端当前正在使用的数据库
redisDb *db;
//...
} redisClient;
设置键的生存时间或过期时间
通过EXPIRE命令或者PEXPIRE命令,客户端可以以秒或者毫秒精度为数据库中的某个键设置生存空间。
EXPIRE 的参数为 秒。
PEXPIRE的参数为 毫秒。
与EXPIRE命令类似,也可以通过EXPIREAT或PEXPIREAT命令。
EXPIREAT为秒的时间戳。
PEXPIREAT为毫秒的时间戳。
TTL命令和PTTL命令接受一个带有生存时间或者过期时间的键,返回这个键的剩余时间。
TTL 返回秒为单位的剩余时间。
PTTL 返回毫秒为单位的剩余时间。
过期键删除策略
定时删除:在设置键的过期时间的同时,创建一个定时器,让定时器在键的过期时间来临时,立即执行对键的操作。
惰性删除:放任键过期不管,但是每次从键空间获取键时,都检查取得键是否过期,过期则删除,未过期则返回。
定期删除:每隔一段时间,程序就对数据库进行检查,删除里面过期的键。
总结
Redis服务器的所有数据库都保存在redisServer.db数组中,而数据库的数量则由redisServer.dbnum保存。
客户端通过修改目标数据库指针,让它指向redisServer.db数组中的不同元素来切换不同的数据库。
数据库主要由dict和expires两个字典构成,其中dict字典负责保存键值对,而expires字典则负责保存键的过期时间。
数据库的键总是一个字符串对象,而值可以是字符串、哈希表、集合、列表、有序列表对象。
expires字典的键指向数据库中的某个键,而值则记录了数据库键的过期时间,过期时间是一个以毫秒为单位的unix时间戳。
redis使用惰性删除和定期删除两种策略来删除过期键:惰性删除策略只在碰到过期键时才删除,定期删除策略则每隔一段时间主动查找并删除过期键。