首页 > 代码库 > redis 数据库
redis 数据库
redis server有很多个数据库空间
如下如所示
dbnum表示的是数据库的数量,db指针指向的是一个redisdb数组,默认都是16个,每一个都是一个redisdb结构的数据库,redis client结构里面会有一个redisdb的指针,指向的就是其中的一个数据库
每一个redisdb里面都有一个字典,指向的就是kv结构。
过期时间和生存时间的问题,我们可以通过设置EXPIRE,PEXPIRE 设置时生存时间,精度分别为秒和毫秒
我们也可以通过EEXPIREAT和PEXPIREAT设置过期时间,精度类似
通过TTL和PTTL我们可以知道我们的key的剩余时间
上面4中设置生存和过期的时间,其实最后都是在不断的转换,调用的PEXPIREAT
redisdb中通过expire字典保存了过期时间,键是一个指针,指向redisdb中的键,值是一个longlong,表示的就是unix时间戳。
上图只是一个简化,实际中dict和expires中相同的键只有一个,之间会通过指针指向。节约了内存空间
PERSIST表示的是移除,就是把过期时间删除
过期键的删除策略
(1)定时删除:创建一个定时器,让定时器在键的过期时间来的时候,立刻执行删除操作
节省内存,占用cpu
(2)惰性删除:放任不管,但是当每次操作的时候,都先检查一下,是否过期了,如果过期了就删除
不会对cpu是、产生什么影响,但是大大的浪费了内存,对于一些非常依赖内存的server来说,这是不友好的。如果某些键一直不会被访问,他会一直存在数据库里面,这其实是一种内存泄漏
(3)定期删除:每隔一段时间,都会检查一部分数据库,如果过期就删除
定期删除其实看着可以解决上面两个存在的问题,但是难点在于设置时长和频率,如果设置的长,其实浪费cpu,如果设置的段,其实还会造成内存占用的问题
定期会有一个全局变量current_db表示遍历到了那个数据库,如果全部便利完了,会重置为0,
AOF,RDB复制对过期键的处理
执行SAVE和BGSAVE的时候,我们会生成一个新的RBD,如果键过期的话,不会保存到里面
在启动server的时候,如果server开启了RDB功能,那么在集群中,如果服务器以主服务器模式启动的话,对于过期的不会载入数据库,如果以从服务器模式运行的话,如果数据库键过期的话, 会被载入到数据库中
复制模式下过期键的处理,如果主服务器的键过期了,但是没有指定del,那么从服务器仍然存在,client范文主服务器的过期键没有,但是访问从服务器的过期键还是有的,只有主服务器删除了,才会向所有从服务发一个del命令,所有的从服务器收到了这个命令后,才会删除自己的过期键,这样的话,就实现主从一致的问题
redis 数据库