Redis——数据库

本文介绍了Redis中数据库的使用,包括切换数据库、操作键空间(添加、删除键)以及维护键空间的操作。重点讨论了键的生存时间和过期时间设置,以及三种过期键删除策略:定时删除、惰性删除和定期删除,强调了每种策略的优缺点和Redis的默认实现策略。
摘要由CSDN通过智能技术生成

服务器中的数据库

struct redisServer {
  	// 一个数组,保存着服务器中的所有数据库
    redisDb *db;
    
    // 服务器的数据库数量
    // 值由服务器配置的database选项决定,默认情况下是16个数据库
    int dbnum;
};

切换数据库

默认情况下,redis客户端的目标数据库为0号数据库,可以通过SELECT命令来切换数据库

redis> SET msg "hello world"
OK

redis> GET msg
"hello world"

redis> SELECT 2
OK

redis[2]> GET msg
(nil)

客户端状态redisClient结构的db属性记录了客户端当前的目标数据库,这是属性是一个指向redisDb结构的指针

typedef struct redisClient {
    // 记录客户端当前正在使用的数据库
    redisDb *db;
} redisClient;

通过修改redisClient.db指针,可以实现数据库的切换,即SELECT命令的实现

数据库键空间

redisDb结构的dict字典保存了数据库中所有键值对

typedef struct redisDb {
    dict *dict;
}

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

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

添加新键

添加一个新键值对到数据库,实际上就是将一个新键值对添加到键空间字典里面

删除键

删除数据库中的一个键,实际上就是在键空间里面删除键所对应的键值对对象

DEL key [...]

其他键空间操作

FLUSHDB:清空整个数据库

RANDOMKEY:随机返回一个键

DBSIZE:数据库键数量

读写键空间时的维护操作

  • 在读取一个键之后(读操作和写操作都要对键进行读取), 服务器会根据键是否存在, 以此来更新服务器的键空间命中(hit)次数或键空间不命中(miss)次数, 这两个值可以在 INFO stats 命令的 keyspace_hits 属性和 keyspace_misses 属性中查看。
  • 在读取一个键之后, 服务器会更新键的 LRU (最后一次使用)时间, 这个值可以用于计算键的闲置时间, 使用命令 OBJECT idletime 命令可以查看键 key 的闲置时间。
  • 如果服务器在读取一个键时, 发现该键已经过期, 那么服务器会先删除这个过期键, 然后才执行余下的其他操作。
  • 如果有客户端使用 WATCH 命令监视了某个键, 那么服务器在对被监视的键进行修改之后, 会将这个键标记为脏(dirty), 从而让事务程序注意到这个键已经被修改过。
  • 服务器每次修改一个键之后, 都会对脏(dirty)键计数器的值增一, 这个计数器会触发服务器的持久化以及复制操作执行。
  • 如果服务器开启了数据库通知功能, 那么在对键进行修改之后, 服务器将按配置发送相应的数据库通知。

设置键的生存时间或过期时间

EXPIRE:设置生存时间,单位:秒。EXPIRE <key> <ttl>

SET key value
// 五秒的生存时间
EXPIRE key 5

PEXPIRE:设置生存时间,单位:毫秒。PEXPIRE <key> <ttl>

EXPIREAT:设置过期时间,单位秒(时间戳)EXPIREAT <key> <timestamp>

PEXPIREAT:设置过期时间,单位毫秒。PEXPIREAT <key> <timestamp>

上面四个命令最后都是使用PEXPIREAT命令来实现的

TTL:接受一个带有生存时间的键,返回这个键的剩余生存时间

PTTL:接受一个带有过期时间的键,返回这个键的剩余生存时间

保存过期时间

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

  • 过期字典的键是一个指针,指向键空间中某个键对象。
  • 过期字典的值是一个long long类型的整数,即过期时间,是一个毫秒精度的UNIX时间戳
typedef struct redisDb {
    // 过期字典,保存键的过期时间
    dict *expires;
} redisDb;

移除过期时间

PERSIST <key>

过期键的判定

通过过期字典,检查以下步骤

  1. 判断键是否在过期字典中,如果存在则返回过期时间
  2. 判断当前UNIX时间戳是否大于键的过期时间,如果是,那么键已经过期

过期键删除策略

定时删除

在设置键的过期时间的同时,创建一个定时器,让定时器在键的过期时间来临时,立即执行对键的删除操作

  1. 对内存友好,尽快释放过期键占用的内存
  2. 对CPU不友好,特别在过期键比较多的情况下

惰性删除

每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键,如果没过期,就返回该键

  1. 对CPU友好
  2. 对内存不友好,特别是有很多过期键但又没有访问的时候

定期删除

每隔一段时间,程序就对数据库进行一次检查,删除里面的过期键。

最主要的是合理地设置删除操作的执行时长和执行频率

Redis的过期键删除策略

惰性删除策略的实现

过期键的惰性删除策略由db.c/expireIfNeeded函数实现,所有读写数据库的Redis命令在执行之前都会调用该函数对输入键进行检查:


参考:Redis设计与实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值