Redis单机数据库 - ZhenLinTechnologySalon/- GitHub Wiki

Redis单机数据库


服务器中数据库与数据库选择

Redis服务器将所有数据库都保存在服务器状态redisServer结构中的db数组中, db数组中每一个项都是一个redisDb结构,代表一个数据库

redisServer结构中有个dbnum属性默认值16,在服务器初始化的时候决定创建多少个数据库。

客户端状态redisClient结构的db属性记录客户端当前目标数据库,是一个指向当前数据库的指针。 也就是说redisClient.db指针指向redisServer.db数组中的一个元素,如下图:

通过select [index] 命令可以改变目标数据库,让redisClient.db指针指向不同的目标数据库


数据库键空间

我们知道,Redis是一个键值对数据库服务器,每一个键值对,实际存放在redisDb结构中的dict字典中,我们将此字典称为键空间。 键空间和用户所见的数据库是对应的:

  • 键空间的键就是数据库的键,每个键都是一个字符串对象
  • 键空间的值就是数据库的值,每一个值可能是一个字符串对象、列表对象、哈希表对象、集合对象、有序集合对象

例子:

redis>set message "hello world"
OK

redis>rpush alphabet "a" "b" "c"
(integer)3

redis>hset book name "Redis in Action"
(integer)1

redis>hset book author "Josiah L . Carlson"
(integer)1

redis>hset book publisher "Manning"
(integer)1

这些命令执行完后,数据库键空间如图:

所以,对数据库添加一个键值对,删除一个键值对,都是对数据库键空间的操作。


设置过期时间

命令 用处
expire 将key生存时间设置为ttl秒
pexpire 将key生存时间设置为ttl毫秒
expireat 将key生存时间设置为指定的秒数时间戳
pexpireat 将key生存时间设置为指定的毫秒数时间戳

上三个命令在底层最终转化成pexpireat来执行

redisDb结构中expires字典保存了数据库所有键的过期时间。这个字典就是过期字典

  • 过期字典的键是一个指针,指向键空间的某个键
  • 过期字典的值是一个long类型的整数----毫秒精度的UNIX时间戳

通过过期字典,检查给定键是否在过期字典中,如果在,取得过期时间检查是否超过当前时间,来判定该键是否过期。


过期键删除策略

定时删除

定期删除就是每隔一段时间执行删除过期键的操作,服务器根据情况,合理配置删除操作的时长和频率

定期删除依靠 activeExpireCycle,当redis周期性操作serverCron 函数执行时,就会调用activeExpireCycle ,在规定时间内遍历服务器的各个数据库,在过期字典中随机检查一部分键的过期时间并删除其中过期键。

惰性删除

惰性删除就是在取值时再检查是否过期并删除,惰性删除对cpu是最友好的,但是会造成内存浪费的情况。

惰性删除依靠 expireIfNeeded,所有读写数据库的命令之前都会调用expireIfNeeded,犹如一个过滤器

  • 如果输入键已过期,则删除
  • 如果输入键未过期,不做操作

AOF,RDB和复制功能对过期键的处理

生成rdb文件

在执行save命令或bgsave时会创建一个新的rdb文件,过期键不会保存到新的rdb文件中。

载入rdb文件

启动redis服务器时,如果开启了rdb功能,将会载入rdb文件:

  • 如果服务器以主服务器模式运行,程序检查rdb中的键,只有未过期的键加载进数据库。
  • 如果服务器以从服务器模式运行,载入rdb文件中,会载入所有键,但是主从同步时,还是会删除过期键。
AOF文件写入

在过期键被惰性删除或定期删除后,AOF会追加一条del命令,显示记录该键被删除。

AOF重写

和生成rdb文件类型,重写时会对过期键进行检查,已过期的键不会加入到重写后的AOF文件中去。


复制

服务器运行在复制模式下时,从服务器的过期键删除由主服务器控制:

  • 主服务器删除一个键的时候,会显式的向所有服务器发送一个del命令;
  • 从服务器在执行客户端发送的读命令时,即是碰到过期键也不会删除;
  • 从服务器只有在接到主服务器的del命令时,才删除 通过由主服务器控制服务器统一删除,保证主从服务器的一致性。

数据库通知

//待补充