asp网站后台失效,免费企业网站模板下载,做网站是买服务器还是买cdn,php网站开发目的文章目录 服务器中的数据库切换数据库数据库键空间读写键空间时的维护操作 设置键的生存时间或过期时间保存过期时间过期键的判定过期键删除策略清性删除策略的实现定期删除策略的实现 总结 服务器中的数据库
Redis服务器将所有数据库都保存在服务器状态redis.h/redisServer结… 文章目录 服务器中的数据库切换数据库数据库键空间读写键空间时的维护操作 设置键的生存时间或过期时间保存过期时间过期键的判定过期键删除策略清性删除策略的实现定期删除策略的实现 总结 服务器中的数据库
Redis服务器将所有数据库都保存在服务器状态redis.h/redisServer结构的db数组中db数组的每个项都是一个redis.h/redisDb结构每个redisDb结构代表一个数据库 struct RedisServer{
// 一个数组保存着服务器中的所有数据库 redisDb *db
//服务器的数据库数量 int dbnum;
} donum 属性的值由服务器配置的database选项决定默认情况下该选项的值为16所以Redis服务器默认会创建16个数据库
RedisServer这个对象是非常重要的因为在本篇的所有内容都是根据这个对象内的各个属性来展开讲解的。这和上篇redis对象有异曲同工之处。
切换数据库
每个Redis客户端都有自已的目标数据库每当客户端执行数据库写命令或者数据库读命令的时候日标数据库就会成为这些命令的操作对象。
默认情况下Redis客户端的目标数据库为0号数据库但客户端可以通过执行SELECT命令来切换日标数据库。
在服务器内部客户端状态redisclient结构的db属性记录了客户端当前的目标数锯库这个属性是一个指向redisDb结构的指针 typedef struct redisClient {
//记录客户端当前正在使用的数据库 redisDb *db ;
} 通过修改redisclient.db指针让它指向服务器中的不同数据库从而实现切换目标数据库的功能这就是SELECT命令的实现原理。
数据库键空间
Redis是一个键值对key-valuepair数据库服务器服务器中的每个数据库都由一个redis.h/redisDb结构表示其中redisDb结构的dict字典保存了数据库中的所有键值对我们将这个字典称为键空间keyspace typedef stxuct redisDb{
// 数据库键空间保存着数据库中的所有键值对 dict *dict
}redisDb ;
建空间和用户所见的数据库是直接对应的
键空间的键也就是数据库的键每个键都是一个字符串对象。键空间的值也就是数据库的值每个值可以是字符串对象、列表对象、哈希表对象、集合对象和有序集合对象中的任意一种Redis对象。
让我们通过图来直观的了解键空间如何存储数据 因为数据库的键空间是一个字典所以所有针对数据库的操作比如添加一个键值对到数据库或者从数据库中删除一个键值对又或者在数据库中获取某个键值对等实际上都是通过对键空间字典进行操作来实现的。数据库的添加、删除、更新、取值等操作的实现原理其实就是来对这个键空间进行相应的操作而上篇提到的命令多态你可以理解为是redis代码内对命令进行的校验校验通过后就来到了键空间进行对应的操作。
读写键空间时的维护操作
当使用Redis命令对数据库进行读写时服务器不仅会对键空间执行指定的读写操作还会执行一些额外的维护操作其中包括
在读取一个键之后读操作和写操作都要对键进行读取服务器会根据键是否存在来更新服务器的键空间命中hit次数或键空间不命中miss次数这两个值可以在INFOstats命令的keyspace_hits属性和keyspace_misses属性中香看。在读取一个键之后服务器会更新键的LRU最后一次使用时间这个值可以用于计算键的闲置时间使用OBJECTiletime命令可以查看键key的闲置时间。如果服务器在读取一个键时发现该键已经过期那么服务器会先删除这个过期键然后才执行余下的其他操作本章稍后对过期键的讨论会详细说明这一点。如果有客户端使用WATCH命令监视了某个键那么服务器在对被监视的键进行修改之后会将这个键标记为脏dirty从而让事务程序注意到这个键已经被修改过。服务器每次修改一个键之后都会对脏dirty键计数器的值增1这个计数器会触发服务器的持久化以及复制操作。如果服务器开启了数据库通知功能那么在对键进行修改之后服务器将按配置发送相应的数据库通知。
设置键的生存时间或过期时间
通过EXPIRE命令或者PEXPPIRE命令客户端可以以秒或者毫秒精度为数据库中的某个键设置生存时间Time To LiveTTL)在经过指定的秒数或者毫秒数之后服务器就会自动删除生存时间为0的键。
保存过期时间
redisDb结构的expires字典保存了数据库中所有键的过期时间我们称这个字典为过期字典
过期字典的键是一个指针这个指针指向键空间中的某个键对象也即是某个数据库键。
过期字典的值是一个longlong类型的整数这个整数保存了键所指向的数据库健的过期时间个毫秒精度的UNIX时间截。 typedef struct redisDb {
//过期字典保存着键的过期时间 dict *expires ; } 我们还是通过一张图来直观的了解我们所描述的内容
过期时间的操作添加、删除、修改其实就是对expires字典进行操作。
过期键的判定
通过过期字典程序可以用以下步骤检查一个给定键是否过期
1检查给定键是否存在于过期字典如果存在那么取得键的过期时间。2检查当前UNIX时间截是否大于键的过期时间如果是的话那么键已经过期否则的话键未过期。
过期键删除策略
redis服务器实际使用的是情性删除和定期删除两种策略通过配合使用这两种删除策略服务器可以很好地在合理使用CPU时间和避免浪费内存空间之间取得平衡。
清性删除策略的实现
过期键的情性删除策略由db.c/expireIfNeeded函数实现所有读写数据库的Redis命令在执行之前都会调用expireIfNeeded函数对输人键进行检查
如果输人键已经过期那么expireIENeeded函数将输入键从数据库中删除。如果输人键未过期那么expireifNeeded函数不做动作。
如图所示展示了使用expireIfNeeded函数的过程 定期删除策略的实现
过期键的定期删除策略由redis.c/activeExpirecycle函数实现每当Redis的服务器周期性操作redis.c/serverCron函数执行时activeExpirecycle区函数就会被调用它在规定的时间内分多次遍历服务器中的各个数据库从数据库的expires字典中随机检查一部分键的过期时间并删除其中的过期键。
activeExpirecycle函数执行过程
函数每次运行时都从一定数量的数据库中取出一定数量的随机键进行检查并删除其中的过期键。全局变量current_db会记录当前activeExpirecycle函数检查的进度开在下一次activeExpirecycle函数调用时接着上一次的进度进行处理。比如说如果当前activeExpireCycle函数在遍历10号数据库时返回了那么下次activeExpireCycle函数执行时将从11号数据库开始查找并删除过期键。随着activeExpireCycle函数的不断执行服务器中的所有数据库都会被检查一遍这时函数将currentdb变量重置为0然后再次开始新一轮的检查工作。
总结
Redis服务器的所有数据库都保存在redisServer.db数组中而数据库的数量则由redisServer.dbnum属性保存。客户端通过修改目标数据库指针让它指向redisServer.db数组中的不同元素来切换不同的数据库。数据库主要由dict和expires两个字典构成其中dict字典负责保存键值对而expires学典则负责保存键的过期时间。因为数据库由字典构成所以对数据库的操作都是建立在字典操作之上的。数据库的键总是一个字符串对象而值则可以是任意一种Redis对象类型包括字符串对象、哈希表对象、集合对象、列表对象和有序集合对象分别对应字符串键、哈希表键、集合键、列表键和有序集合键。expires字典的键指向数据库中的某个键而值则记录了数据库键的过期时间过期时间是一个以毫秒为单位的UNIX时间截。Redis使用情性删除和定期删除两种策略来删除过期的键情性删除策略只在碰到过期键时才进行删除操作定期删除策略则每隔一段时间主动查找并删除过期键。