三、redis数据库

alt

alt

redis服务器使用数据库保存所有键值对及键值对的过期时间,在redis服务器状态redisServer结构中的redisDb类型的db数组用于记录服务器中的所有数据库,db数组大小由redisServer结构中的dbnum属性决定,而dbnum属性由服务器配置选项databases属性决定,该属性默认大小16,即默认创建16个数据库。

redis客户端状态redisClient结构中的redisDb类型的db属性是一个指向redisServer.db数组中某个元素的指针,用于记录该客户端的目标数据库,默认0号数据库。

redisDb

dict字典

redisDb结构中的dict字典类型的dict属性,记录数据库中所有的键值对,称呼该dict字典为键空间。

键空间中的每一个键都是一个字符串对象,对应数据库中某个键值对的key值;

键空间中每一个值可以是对象系统中的任意一种对象, 对应数据库中某个键值对的value值;

因此对数据库键的所有操作都是通过对键空间进行读写完成的,除此之外,redis服务器还会执行额外的维护动作,包括:

redis服务器读取一个键时,根据键是否存在来更新redisServer结构中的键命中次数hit、键未命中次数miss;
redis服务器读取一个键时,更新该键的lru属性(最后一次被访问的时间);
redis服务器读取一个键时,会对键进行过期检查,如果过期,立即执行删除动作;否则不做任何处理。
redis服务器修改一个键时,更新redisServer结构中的dirty计数器,该计数器用于触发持久化操作和复制操作;
如果客户端使用WATCH命令监视了某个数据库键,redis服务器将对应的键修改后,立即将其标记为DIRTY状态,以便让事务程序注意到该键已经发生了修改;
如果redis服务器开启了数据库通知功能,修改键后,会按照配置发送相应的数据库通知;

expire字典

可以通过EXPIRE命令、EXPIREEAT命令、PEXPIRE命令、PEXPIREEAT为数据库中的键设置过期时间;通过TTL命令或PTTL命令查看键的剩余生存时间;

redis服务器将所有带有过期时间的键值对的过期时间保存在redisDb结构中的expire字典中,字典中的每一个键都是指向键空间中某个键的指针,字典中的每一个值都是一个long long类型的整数,代表该键的过期时间。

redis服务器检查某个键是否过期:

检查该键是否存在于expire过期字典中,如果不存在,则没有过期时间;如果存在,取出该键的过期时间;
获取当前系统时间戳,如果大于该键过期时间,说明该键还没有过期;否则已经过期,需要执行对键的删除动作;

过期键处理策略

定时删除策略:

为某个键设置过期时间的同时,创建一个定时器。定时器到期时,立即执行对该键的删除动作;

优点:对内存友好,一个键过期时能够被迅速的删除;

缺点:对CPU不友好。短时间内大量键过期,会让CPU忙于处理与当前任务无关的过期键删除动作,降低CPU的吞吐量和响应时间;

redis服务器想要实现定时删除策略,需要创建大量的定时器,现阶段不现实,并没有实现;

惰性删除策略:

放任过期键不处理,只有再次访问某个键时,对其进行过期检查。如果过期,立即执行对键的删除动作;

优点:对CPU友好,CPU只需处理与当前任务有关的数据库键;

缺点:对内存不友好,大量过期键后续不再被访问造成内存空间浪费,这种情况甚至可以看做一种内存泄漏;

redis服务器对惰性删除策略的实现:

redis服务器每次访问一个键时,都会调用expireIfNeeded函数对键进行过期检查,如果过期,立即执行对键的删除动作;否则不做任何处理继续执行;
redis服务器访问的数据库键可能存在,也可能不存在,expireIfNeeded函数能够同时处理键存在、键不存在两种情况;

定期删除策略:

实际是对前两种方案的整合和折中,通过限制执行时长和执行频率,减少对CPU的影响,又能确保有足够的内存可用。

redis服务器对定期删除策略的实现:

redis周期性时间事件serverCron函数默认每100毫秒执行一次,用于对正在运行的服务器进行维护。serverCron函数运行时,会调用activeExpireCycle函数,该函数的作用是在规定的时间内,分多次遍历服务器中的各个数据库,按照一定的算法抽取一定数量的数据库键,对其进行过期检查,然后将过期键删除;

持久化、复制操作对过期键的处理:

创建RDB文件时,

会对数据库中的所有键值对进行过期检查,只有未过期的键值对会被添加到RDB文件中;

载入RDB文件时,

如果以主服务模式运行,则对RDB文件中的所有键值对进行过期检查,只有未过期的键被载入到数据库状态中;

如果以从服务区模式运行,则不进行过期检查,将RDB文件中的所有键值对统统载入。因为在主从服务器数据同步时,从服务器会被清空,所以影响可以忽略;

AOF文件写入时,

如果某个键已经过期,但还没有被惰性删除或定期删除,则不对AOF文件产生任何影响;

如果通过惰性删除或定期删除将某个键删除,立即向AOF文件追加一条DEL命令,显式的记录该键已经被删除;

AOF文件重写时,

和生成RDB文件一样,对数据库中的所有键值对进行过期检查,只有未过期的键才会被重写至AOF文件;

执行复制操作时,

以主服务器模式运行时,将某个键删除后,向其属下的所有从服务器发送一条DEL命令;

以从服务器模式运行时,接收到客户端发送的和数据库见有关的命令时,不对其进行过期检查,即便已经过期,仍然按照没有过期进行处理;

从服务器只有在接受到主服务器发送的DEL命令时,才会将对应键删除。保证了主从服务器的数据一致性;

数据库通知功能

某个键执行了什么命令,这一类的通知称为键空间通知;

某个命令被什么键执行了,这一类的通知称为键事件通知;

redis客户端可以通过订阅给定的频道或模式,监视数据库中某个键的变化或某个命令的执行情况。

数据库通知功能由notifyKeySpaceEvent函数实现,该函数有四个参数:

type。事件类型;

event。产生的事件名称;

key。产生事件的键;

dbid。产生事件的数据库号码;

#redis数据库#
redis 文章被收录于专栏

redis20000字笔记(含思维导图版本-大纲版本)

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务