一、数据库的结构
数据库的数据结构如下
typedef struct redisDb {
// 数据库键空间
dict *dict;
// 键的过期时间,字典的键为键,字典的值为过期事件 UNIX 时间戳
dict *expires;
// 正处于阻塞状态的键
dict *blocking_keys;
// 可以解除阻塞的键
dict *ready_keys;
// 监视事务的键
dict *watched_keys;
struct evictionPoolEntry *eviction_pool; /* Eviction pool of keys */
// 数据库id
int id;
// 数据库的键的平均 TTL ,仅仅是统计信息
long long avg_ttl;
} redisDb;
而这些主要是通过redisServer调用的
struct redisServer{
redisDb *db; //redisDb数组,保存着服务器中的所有数据库
int dbnum; //数据库的数量,默认值位16
}
二、有关数据库的操作
1.键空间的操作
每个redis客户端都有自己的目标数据库,每当客户端执行数据库写命令或目标数据库就会称为命令的对象。默认情况下,redis客户端的目标数据库为0号数据库,但客户端可以通过执行SELECT命令来切换目标数据库
添加一个新键值对到数据库,实际上就是将一个新键值对添加到键空间字典里面,其中键为字符串对象,而值为任意一种类型的redis对象。同理删除,更新键以及取值
就是在键空间里对键空间的字典操作。
当使用redis命令对数据库进行读写时,服务器不仅会对键空间执行指定的 读写操作,还会执行一些其它的额外的维护操作,其中包括:
- 在读取一个键以后,服务器会根据键是否存在来更新服务器的键空间命中和不命中次数。
- 在读取一个键之后,服务器会更新键的LRU时间,这个值可以用于计算键的闲置时间,使用OBJECT idletime <key> 来查看键的闲置时间
- 如果服务器在读取一个键时发现该键已经过期,那么服务器会先删除这个过期键,然后才执行余下的操作
- 如果有客户端使用WATCH命令监视了某个键,那么服务器在对被监视的键进行修改之后,会将这个键标记为脏。
- 服务每修改一个键后,都会对脏键计数器的值增1,这个计数器会触发服务器的持久化以及复制操作
- 如果服务器开启了数据库通知功能,那么在对键进行修改之后,服务器将按配置发送到相应的数据库通知
2.键的生存时间或过期时间
redis 有四个不同的命令可以用于设置键的生存空间(键可以存在多久):
- expire [key] [ttl] 用于将key的生存时间设置为ttl毫秒
- pexpire [key] [ttl] 命令将键的过期时间设置为ttl毫秒
- expireat [key] [timestamp] 命令用于将键key的过期时间设置为timestamp所指定的毫秒的时间戳
- pexpireat [key] [timestamp] 命令将键key的过期时间设置为timestamp所指定毫秒时间戳
虽然有多种不同单位和不同形式的设置命令,但实际上expire,pexpire, expireat命令都是使用pexpireat命令来实现的
redisDb结构中的expires字典中保存了数据库中所有键的过期时间,我们称之为过期字典。过期字典的键为一个指针,而值是一个long long类型的整数,这个整数保存了键所指向的数据库的过期时间。
我们通过TTL或者PTTL两个命令来计算键的剩余生存时间,TTL返回值单位为秒,PTTL返回值单位为毫秒
3.过期键的删除
键的过期删除策略有三种:
- 定时删除:在设置键的过期时间的同时,创建一个定时器,让定时器在键的过期时间来临时,立即执行对键的删除操作。
- 惰性删除:放任键过期不管,但是每次从键空间中获取键时检查是否过期,过期删除,未过期则返回该键。
- 定期删除:每隔一段时间,程序就对数据库进行一次检查,删除里面的过期键。
4.AOF、RDB对过期键的处理
在执行SAVE命令或者是BGSAVE命令创建一个新的RDB文件时,程序会对数据库中的键进行检查,已过期的键不会保存到新船舰的RDB文件当中。
在启动redis服务器对rdb文件载入时,如果服务器以主服务器运行时,载入RDB时只有未过期的会被载入到数据库中。如果时从服务器,那么无论是否过期都会被载入到数据库中。
当服务器以AOF持久化模式运行时,如果数据库中的某个键已经过期,但它还没有被惰性删除或定期删除,那么AOF文件不会因为这个过期键而产生过期影响。当键惰性删除或者定期删除后,程序会向AOF文件追加一条DEL命令来显示的表达已经被删除
当AOF重写时,程序会对数据库中的键进行排查,已过期的键不会被保存到重写后的AOF文件中
4.复制
当服务器运行在复制模式下,从服务器的过期删除动作由主服务器控制:
- 主服务器在删除一个过期键之后,会显式的向所有服务器发送一个DEL命令,通知所有从服务器删除这个过期键。
- 从服务器在执行客户端发送的命令时,即使碰到过期键也不会将过期键删除
- 从服务器只有在接到主服务器发来的DEL命令时才会删除过期键。