您的位置:首页 > 数据库 > Redis

Redis 设计与实现 1:数据库 redisDb

2020-12-25 11:05 274 查看

服务器中的数据库

Redis 服务器将绝大部分的信息都保存在

server.h/redisServer
。redis 的数据是保存在
redisServer
中的
redisDb
结构中。

struct redisServer {
// ...
redisDb *db; // 数据库列表
// ...
int dbnum;   // 数据库数量
// ...
}
  • db
    中每个redisDb结构代表一个数据库。
  • 在初始化服务器时,程序会根据服务器状态的
    dbnum
    属性来决定应该创建多少个数据库。
  • dbnum
    属性的值由服务器配置的
    database
    选项决定,默认情况下,该选项的值为16,所以Redis服务器默认会创建16个数据库。

数据库键空间

Redis 是一个键值对数据库服务器,服务器中的每个数据库都由一个

server.h/redisDb
结构表示.
其中,
redisDb
dict
字典属性保存了数据库中的所有键值对,我们将这个字典称为键空间(key space):

typedef struct redisDb {
dict *dict;
// ...
} redisDb;

dict 中的数据跟我们平常操作的键值对是一一对应的:

  • dict 的 key 就是数据库中的 key,字符串类型
  • dict 的 值 就是数据库中的 值,这个值可以是
    string
    hash
    zset
    set
    list
    中的任何一种

示例

如果我们在数据库中,执行以下命令:

redis > SET str_key str_value
OK
redis > RPUSH list_key a b c
(integer) 3

新添加的两个 key 的结构如下图所示:

从上面的示例图可以很清晰地知道 Redis 数据是如何组织的,增删改查也就是对 dict 的操作而已,此处就不详细说了。

Key 的过期时间

1. 数据结构

redisDb 中的

expires
属性保存了所有
key
的过期时间,我们姑且就称它为过期字典吧。

  • 过期字典中的键,是一个指针,指向了真实数据的
    key
    ,不会浪费空间多保存一次
  • 过期字典中的值,存的是具体的过期时间点,精确到毫秒的时间戳
typedef struct redisDb {
// ...
// 保存了所有 key 的过期时间
dict *expires;
// ...
} redisDb;

命令

TTL
PTTL
都是去查这个过期字典的过期时间,然后减去当前时间,得到的就是剩余的时间啦。

2. 过期 key 的删除策略

一个 key 过期时间到了之后,是如何进行删除的呢?Redis 使用了一下两种策略:惰性删除、定期删除

惰性删除

惰性删除策略指的是:key 在过期之后,没有立即删除,而是在读写 key 的时候,才对过期的 key 进行删除。
代码实现在

db.c/expireIfNeeded
方法中。所有 key 的读写之前,都会先调用
expireIfNeeded
对 key 进行检查,如果已过期,则删除。

定期删除

定期删除策略指的是:Redis 每隔一段时间,随机从数据库中取出一定量的 key 进行检查,如果已过期,则进行删除。
代码实现在

expire.c/activeExpireCycle
方法中。

本文的分析没有特殊说明都是基于 Redis 6.0 版本源码
redis 6.0 源码:https://github.com/redis/redis/tree/6.0

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: