单机数据库
服务器中的数据库
Redis服务器将所有数据库都保存在服务器状态redis.h/redisServer
结构的db数组中,db数组的每个项都是一个redis.h/redisDb
结构,每个redisDb
结构代表一个数据库
struct redisServer{
//...
//一个数组,保存服务器中所有数据库
redisDb *db;
//...
};
在初始化服务器时,程序会根据服务器状态的dbnum属性来决定应该创建多少个数据库(默认为16个)
struct redisServer{
//...
//服务器的数据库数量
int dbnum;
//...
}
切换数据库
每个Redis客户端都有自己的目标数据库,每当客户端执行数据库写/读命令时,目标数据库会成为这些命令的操作对象
默认情况下,Redis客户端的目标数据库是0号数据库,可以通过SELECT
命令来切换目标数据库
实际上
在服务器内部,客户端状态redisClient
结构的db
属性记录了客户端当前的目标数据库,db
是一个指向redisDb
结构的指针
typedef struct redisClient{
//...
//记录客户端当前正在使用的数据库
redisDb *db;
//...
}redisClient;
通过修改redisClient.db
指针,让它指向服务器中的不同数据库,从而实现切换数据库的功能,这就是SELECT
命令的实现原理
数据库键空间
Redis是一个键值对数据库服务器
服务器中的每个数据库都由一个redis.h/redisDb
结构表示,其中,redisDb
结构的dict
字典保存了数据库中的所有键值对,我们将这个字典称为键空间
typedef struct redisDb{
//...
//数据库键空间,保存着数据库中的所有键值对
dict *dict;
//...
}redisDb;
- 键空间的键也就是数据库的键,每个键都是一个字符串对象
- 键空间的值也就是数据库的值,每个值可以是5种基本对象中的任何一种
基本操作
SET,GET,DEL
分别代表 添加/更新,取得,删除
FLUSHDB
清空当前数据库
EXPIRE/PEXPIRE
客户端可以通过这些命令,以秒/毫秒为精度为数据库中的某个键设置生存时间(TTL)
过期时间是一个UNIX时间戳,当键的过期时间来临,服务器会自动从数据库中删除这个键
过期键删除策略
- 定时删除
- 在设置键的过期时间的同时,创建一个定时器,让定时器在键的过期时间来临时,立即执行对键的删除操作
- 惰性删除
- 放任键过期不管,但是每次从键空间获取键时,都检查取得的键是否过期,如果过期则删除
- 定期删除
- 每隔一段时间,程序对数据库进行一次检查,删除里面的过期键,至于要删除多少过期键,以及要检查多少数据库,由算法决定
Redis一般使用惰性删除+定期删除
数据库主要由dict expires
两个字典构成,其中dict
字典负责保存键值对,expires
字典则负责保存键的过期时间
AOF/RDB
生成RDB文件
在执行SAVE或者BGSAVE命令创建一个新的RDB文件时,程序会对数据库中的键进行检查,已过期的键不会被保存到新创建的RDB文件中
因此,数据库中包含过期键不会对生成新的RDB文件造成影响
载入RDB文件
- 主服务器:载入RDB文件时,程序会对文件中保存的键进行检查,未过期的键载入数据库,过期键被忽略
- 从服务器:载入RDB文件时,文件中保存的所有键全部载入到数据库,在后面的主从服务器数据同步时,从服务器的数据库被清空
AOF文件写入
服务器以AOF持久化模式运行时,如果某个键已过期,同时没有被删除,AOF文件不会因为这个过期键产生任何影响
在过期键被惰性删除或定期删除后,程序会向AOF文件追加(append)一条DEL
命令显示的记录该键已被删除
AOF重写
在执行AOF重写的过程中,程序会对数据库中的键做检查,已过期的键不会保存到重写后的AOF文件中
所谓重写:就是过滤重复语句
例如
RPUSH list "a" "b"
RPUSH list "c"
RPUSH list "d" "e"
重写后
RPUSH list "a" "b" "c" "d" "e"
过滤了部分重复语句,节省了AOF文件空间
复制
当服务器运行在复制模式下时,从服务器的过期键删除动作由主服务器控制
- 主服务器在删除一个过期键后,会显式的向所有从服务器发送一个
DEL
命令,告知从服务器删除这个过期键 - 从服务器在执行客户端发送的读命令时,即使碰到过期键也不会主动将其删除,而是继续处理
- 从服务器只有在街道主服务器发送的
DEL
命令后,采后删除过期键
如此,通过主服务器控制从服务器统一地删除过期键,可以保证主从服务器的一致性
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!