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设计与实现