Redis-单机数据库的实现-数据库原理

目录

1. 服务器中的数据库

2. 数据库键空间

2.1. 读写空间时的维护操作

3. 过期时间

4. 过期删除策略

4.1. 定时删除

4.2. 惰性删除

4.3. 定期删除

4.4. Redis删除策略

5. AOF、RDB和复制功能对对过期键的处理

5.1. RDB

5.2. AOF

5.3. 复制

6. 数据库通知


1. 服务器中的数据库

Redis也是个程序,用C语言写的,那么保存数据是需要一个数据结构的,那么Redis中的数据库是什么结构呢

大概的样子如上图所示

RedisServer通过dbnum来确定初始化的时候,需要新建多少个数据库,也就是db数组

而redisClient连接的时候需要选定操作是那个数据库,默认是0号库,也能通过select命令选择使用那个数据库,例如select 1,选择了1号库,那么这个时候就如上图所示

每一个client连接到server,都会再server保存一个client实例

2. 数据库键空间

数据库键是一个字符串对象

数据库值可以是字符串对象,列表,集合,哈希对象等等,任意一种Redis对象

如下图所示

“xx” 表示一个字符串对象

可以看出,数据库的底层是用dict,也就是哈希对象实现的

2.1. 读写空间时的维护操作

当使用Redis命令对数据库进行读写时候,服务器不仅会对键空间执行指定的读写操作,还会执行一项额外的维护操作

  • 读取键之后,会根据键是否存在更新键空间命中(hit)次数和键空间不命中(miss)次数,可以通过info stats命令查看
  • 读取之后,会更新键LRU时间
  • 如果服务器发现读取一个键时间这个键已经过期,会先删除这个键,然后再执行余下操作
  • 如果客户端使用了watch命令监视某个键,那么服务器对被监视的键进行修改,会将这个键标注为赃读
  • 服务器修改一个键后,赃读+1,这个计数器引发持久化操作
  • 如果服务器开启通知功能,那么对键修改后,会发生相应的数据库通知

 

 

3. 过期时间

expire命令和pexpire命令

前者是设置秒,后者是设置毫秒

本质上是通过将秒转换为时间戳实现的,例如expire  5  这样会将当期时间+5算到时间戳,当时间戳的时间来临就过期

pexpireat  <key> <时间戳>  所有设置过期时间的命令都是用这个命令实现的  这个时间戳是毫秒级别,对应有个expireat秒级别

这个过期时间保存地方如下图所示

这里过期时间的expires中的key和dict中的key是同一个对象,redis做了复用,不会造成2倍的内存消耗

 

 

4. 过期删除策略

一般来说删除策略分为3种

  1. 定时删除
  2. 惰性删除
  3. 定期删除

 

4.1. 定时删除

对内存最友好,通过定时器实现,保证过期键会尽可能快的被删除,并释放过期键所占用的内存,缺点就是对CPU不友好,过期键很多情况下,删除过期键会占用很多CPU,容易造成吞吐量影响

Redis创建定时器需要用到Redis服务器中的时间事件,时间事件的实现方式无序列表,时间复杂度是O(n)

而且对每个键都创建个定时器,也不正常,不现实

 

4.2. 惰性删除

对CPU最友好,程序只会在取出键的时候检查,判断是否过期,同理对内存不友好,可能过期之后,长期没有访问,一直存在,可以看成是一种内存泄漏

 

4.3. 定期删除

定期删除可以看成上面两种的折中

定期删除的策略是每隔一段时间执行一次删除过期键的操作,并通过限制操作执行频率和时长减少对CPU影响,简单来说,限制时间,限制删除键数量来操作

 

4.4. Redis删除策略

Redis采用定期删除和惰性删除两种策略配合使用

惰性删除

Redis在调用读写命令之前都会判断键是否过期,过期就删除

定期删除

在规定时间内,分多次遍历服务器中各个数据库,从数据库的expires字典中随机拿出一部分键的过期时间,检查是否过期,并删除过期键

有个全局变量记录当前操作那个数据库,当执行完最后一个数据库时候,计数器归0,从新开始

每次开始的操作时候,有两个变量控制,时间,清除过期键梳理,如果在操作过程中,时间到期,则操作结束,如果时间没有到期,但是清除了规定的键梳理,操作也结束

 

5. AOF、RDB和复制功能对对过期键的处理

5.1. RDB

过期键在生成RDB文件时候,不会保存进RDB文件中

在载入RDB文件时候,主服务器会根据键是否过期来判断是否载入这个键,从服务器则载入所有,不管是否过期,但是主从同步数据之后,过期键还是会被删除

 

5.2. AOF

当一个键过期了,会追加一条DEL命令进AOF文件

重写AOF时候,会判断键是否过期,过期的键会被忽略

 

5.3. 复制

在主从模式下,从服务器的过期键删除动作由主服务器控制

主服务器删除一个键,显示向所有服务器发送一个DEL命令,告知所有从服务器这个键被删除

从服务器在执行客户端读命令,遇见过期键也不会删除

 

6. 数据库通知

当Redis命令对数据库进行了修改之后,服务器会根据配置向客户端发送数据库通知,包含事件名称,产生事件的键,产生事件的数据库编号确定事件内容

 

全部评论

相关推荐

04-24 13:51
已编辑
西安电子科技大学 Java
👋个人背景:211计算机混子,代码能力一般,春招急头白脸参加央国企最后拿下这两个offer👏offer1:中广核工程公司驻陆丰仪控调试,待遇19+4,离家1800km💯offer2:张家口卷烟厂待遇未知,应该有13个(猜测),离家500km牛油们帮忙选一下,家里人不是很喜欢卷烟厂这个offer,但是蜀黍烟草局下岸了
鸿雁于飞:先说offer1:中广核工程公司驻陆丰仪控调试(待遇19+4) 中广核这艘央企大船还是很稳的,集团综合效益稳居央企前列。但你得搞清楚,这个19+4的"19"是总包,不是到手数——招聘宣传待遇里把所有能算的都算进去了,饭卡福利积分啥的全包含,有牛油分享实际到手大概打七折。试用期到手可能就四五千的水平,转正后基本工资4800左右,其余靠绩效、年终、大修费撑着。不过核电的工作环境有点"牢笼感"——核电站位置偏僻,远离繁华都市。工程公司是承包商性质,干活比业主公司累,而且大概率要经常出差,有的岗位年出差天数100天以上。最大问题是你这1800km的距离过于离谱,核电员工工作强度最小的时候一周也就回一次家,离得远回家成本高,夫妻感情和亲子关系都是现实考验。说白了:高薪是拿青春和生活换的。 再来看offer2:张家口卷烟厂(待遇约13个) 张家口卷烟厂是河北中烟下属三家卷烟厂之一,河北中烟主打的"荷花"系列连续多年位居全国高端卷烟品牌销量前列。烟草系统薪资由基本工资+绩效+年终奖构成,综合年薪普遍显著高于当地平均水平,六险二金齐全,福利拉满。有人问"13个是不是太平平无奇了"——关键张家口是四线城市,生活成本低,这13万的购买力相当于深圳的二十多万。离家500km,开车半天到家,周末回趟家完全可行,幸福感直接上两个档次。中广核的牛油说了句大实话: "哪个核电站好?永远是离家近的那个最好。" 选烟厂同理。 但是,卷烟厂的坑你得清楚: 首先卷烟厂和烟草局不一样,卷烟厂是生产操作类岗位,很多要三班倒。报考条件明确写了要能"胜任夜班工作和长时间站立工作"。一线操作工每天盯着流水线卷烟,工作内容高度重复,有入职的人描述为"食之无味弃之可惜"。有牛油直言"卷烟厂和商业性质的烟草公司不一样,前者很坑很累"。其次你家里人不是不喜欢,而是担心你这211计算机科班出身,进了烟厂干操作工,技能会快速退化,未来如果行业改革,技术壁垒不高,转行比较困难。等你干两年再跳出来,技术栈全忘干净了,回头再去敲代码,发现连应届生都卷不过。 老牛油的灵魂三问: 1. 你是更怕穷,还是更怕想家? 如果特别恋家的人跑1800km之外,第一年哭鼻子的概率高达80%。陆丰那地方偏僻单调,核电基地又远又闷,闲下来除了打游戏没啥娱乐,社交圈也窄。找个对象都费劲——牛油亲测核电站"狼多肉少"。 2. 你的代码能力有多"一般"? 如果真的一般,仪控调试和你专业匹配度不算高,这活儿主要是工程改造设计、现场实施管理、在建机组设计审查等,偏工程向而非纯软开。干两年后跳回互联网赛道,竞争力不一定有明显提升。反倒是烟厂不需要你写代码,进去就是稳定躺平。 3. 烟草局下岸这事儿会不会让你耿耿于怀? 如果烟草局是你第一志愿,烟厂只是plan B,那得想清楚:进去了可能每天看着天花板想"如果当初去了烟草局该多好",这种内耗比钱少还折磨人。如果你能接受"反正都是烟草系统,先进去再说"的心态,那倒无所谓。 一句话总结: 如果年轻想拼想闯做技术积累,中广核虽然累和远,但简历上央企核电的金字招牌确实有含金量,加上到手收入在这两个选项里确实更高,考虑到你个人经济情况和家庭状况,假如家里不需要你常回去照顾,家里有兄弟姐妹帮手分担,那先去核电待三四年,积累经验再跳槽也不失为一步棋。 如果想安稳过日子离家近当"人上人",烟厂低线生活成本加持,加上稳定的编制和福利体系,在张家***得滋润,幸福感吊打陆丰。尤其家里人是那种离不开你的,有烟厂的稳定且离家近,比任何高薪都实在。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务