• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

redis当中数据库的实现

redis 海叔叔 3小时前 3次浏览 已收录 0个评论

redis服务器将所有数据库都保存在服务器状态redisServer结构的db数组中,db数组的每个项都是一个redisDb机构,每个redisDb结构代表一个数据库

其中dbnum属性的值由服务器配置选项决定。
每个redis客户端都有自己的目标数据库,每当客户端执行数据库读写命令的时候,目标数据库就会成为这些命令的操作对象。默认情况下,redis客户端的目标数据库为0号数据库,但客户端可以通过执行SELECT命令来切换目标数据库。
在服务器内部,客户端状态redisClient结构的db属性记录了客户端当前的目标数据库,这个属性是一个指向redisDb结构的指针

通过修改redisClient.db指针,让它执行服务器中的不同数据库,从而实现切换目标数据库的功能,这就是SELECT命令的实现原理

redis是一个键值对数据库服务器,服务器中的每个数据库都由一个redisDb结构表示,其中dict字典当中保存了数据库中的所有键值对,我们将这个字典称为键空间:
1. 键空间的键也就是数据库的键,每个键都是一个字符串对象
2. 键空间的值也就是数据库的值,每个值可以是字符串对象、列表对象、哈希表对象、集合对象和有序集合对象中的任意一种。

redisDb结构当中的expires字典保存了数据库中所有键的过期时间:
1. 过期字典的键是一个指针,这个指针指向键空间中的某个键对象
2. 过期字典的值是个long long类型的整数,这个整数保存了键所指向的数据库键的过期时间——一个毫秒精度的UNIX时间戳(epoch)

如果一个键过期了,有三种不同的删除策略来删除对应的键与关联的时间
1. 定时删除:在设置键的过期时间的同时,创建一个定时器,让定时器在键的过期时间来临时,立即执行删除操作
2. 惰性删除:放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键;如果没有过期,就返回该键。redis当中的实现是:所有读写数据库的redis命令在执行之前都会调用expireIfNeeded函数对输入键进行检查,如果已经过期,则删除,如果没有过期,则不做动作
3. 定期删除:每隔一段时间,程序就对数据库进行一次检查,删除里面的过期键。redis里面,每当redis的服务器周期性操作serverCron函数执行时,activeExpireCycle函数就会被调用,它在规定的时间内,分多次遍历服务器中的各个数据库,从数据库的expires字典中随机检查一部分键的过期时间,并删除其中的过期键,会有全局变量记录当前activeExpireCycle函数检查的进度,以便在下一次运行时继续,
在redis服务器中使用的是惰性删除和定期删除两种策略:通过配合使用这两种删除策略,服务器可以很好的在合理使用CPU时间和避免浪费内存空间之间的平衡

当服务器运行在复制模式下时,从服务器的过期键删除动作由主服务器控制,只要主服务器没有发送DEL命令,即使有客户端向从服务器请求一个过期的键,也会如愿返回。

数据库通知可以让客户端通过订阅给定的频道或者模式,来获知数据库中键的变化,以及数据库中命令的执行情况。其中,某个键执行了什么命令的通知称为键空间(key-space)通知,另一类某个命令被什么键执行了的通知称为键事件(key-event)通知
服务器配置的notify-keyspace-events选项决定了服务器所发送通知的类型,具体见官方文档。具体实现是由函数notifyKeyspaceEvent来实现的,它会根据选项设置的值,选择通知类型type,然后检测是否允许发送键空间通知,最后检测是否允许发送键事件通知


喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址