数据库

Redis服务器的所有数据库都保存在redisServer.db数组中,而数据库的数量则由redisServer.dbnum属性保存。

struct redisServer {
    // ..
    
    // 一个数组,保存着服务器中的所有数据库
    redisDb *db;
    
    // 服务器的数据库数量
    int dbnum;
    
    // ...
}

数据库

数据库键空间

Redis是一个键值对数据库服务器,服务器中的每个数据库都由一个redis.h/redisDb结构表示,其中redisDb结构的dict字典保存了数据库中的所有键值对,我们将这个字典称为键空间(key space):

typedef struct redisDb {
    // ..
    
    //数据库键空间,保存着数据库的所有键值对
    dict *dict;
    
    // ..
} redisDb;

数据库键空间

键空间和用词所见的数据库是直接对应的:

  • 键空间的键就是数据库的键,每个键是一个字符串对象。
  • 键空间的值就是数据库的值,每个值可以是字符串对象、列表对象、哈希表对象、集合对象和有序集合对象中的任意一种Redis对象。

键的过期时间

通过EXPIRE命令或者PEXPIRE命令,客户端可以以秒或者毫秒精度为数据库中的某个键设置生存时间(Time To Live,TTL),在经过指定的秒数或者毫秒数之后,服务器就会自动删除生存时间为0的键。

redisDb结构的expires字典保存了数据库中所有键的过期时间,我们称这个字典为过期字典:

  • 过期字典的键是一个指针,指向键空间中的某个键对象。
  • 过期字典的值是一个long,表示此键的过期时间。
typedef struct redisDb {
    // ...
    
    // 过期字典,保存着键的过期时间
    dict *expires;
    
    // ...
} redisDb;

过期字典

过期键删除策略

如果一个键过期了,那么它什么时候被删除?

这个问题可能有三种可能的答案,分别代表了三种不同的删除策略:

三种过期键删除策略

Redis服务器实际使用的是惰性删除和定期删除两种策略:通过配合使用这两种删除策略,服务器可以很好地在合理使用CPU时间和避免浪费内存空间之间取得平衡。

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

RDB对过期键的处理

  • 生成RDB文件:执行SAVE命令或者BGSAVE命令所产生的新RDB文件不会包含已经过期的键。
  • 载入RDB文件:如果服务器是主服务器,载入RDB时程序只会云载入未过期的键;如果服务器是从服务器,载入RDB时全部载入,不过当进行数据同步时,从服务器的数据库就会被清空,所以过期键不会造成影响。

AOF对过期键的处理

  • AOF写入:当过期键被删除后,程序会向AOF文件追加一条DEL命令。
  • AOF重写:程序会对数据库中的键进行检查,已过期的键不会被保存到重写后的AOF文件中。

更多关于AOF和RDB的内容,请查看Redis基础(三)RDB与AOF持久化

复制对过期键的处理

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

  • 主服务器在删除一个过期键后,会显式地向所有从服务器发送一个DEL命令,告知从服务器删除这个过期键。-
  • 从服务器即使发现过期键也不会自作主张地删除它,而是等待主节点发来DEL命令,这种统一、中心化的过期键删除策略可以保证主从服务器数据的一致性。

参考资料

分类:

技术点:

redis