Redis的持久化

redis是一个内存数据库,是把数据存储在内存中的,而我们知道内存中的数据是不持久的,一旦服务器重启或者进程重启,内存的数据就丢失了.为了让数据达到持久化的效果,就必须把数据写到硬盘上.

redis相对于mysql这样的关系型数据库最明显的优势就是快.所以为了保证速度快,数据还得在内存中,但是为了持久,数据还要想办法存储在硬盘上.

Redis为了应对这样的情况,决定把数据在内存中存储一份,同时在硬盘上也存储一份.这样的两份数据,理论上是完全相同的,实际上可能存在差异,取决于我们具体怎么进行持久化.

当要插入一个新的数据的时候,就需要把这个数据,同时写入内存和硬盘.但说是同时写,实际上怎么写入硬盘是有不同的策略的,应用这些策略,就可以保证redis整体的效率还是足够高的.

当查询某个数据的时候,直接从内存读取.硬盘中的数据只是在redis重启的时候,用来回复内存中的数据的.

代价就是消耗了更多的空间,同一份数据存储了两份,但是硬盘空间毕竟是比较廉价的,这样的开销并不会带来很多的成本.


redis实现持久化的策略

redis实现持久化的整体策略有两种,RDB和AOF.

RDB:Redis DataBase.AOF:Append Only File.

RDB是定期备份,AOF是实时备份.

RDB持久化

RDB持久化是定期的把当前进程数据生成快照保存到硬盘的过程.

后续redis一旦重启了,就可以根据硬盘的中快照把内存中的数据给回复回来.

RDB定期备份的两种方式

1.手动触发

程序员通过redis客户端,执行特定的命令,来触发快照的生成.

save命令,执行save命令的时候,redis服务器会在单线程模型下全力以赴的进行快照生成的操作,此时就会阻塞redis其他客户端的命令,一般不建议使用save.

bgsave,bg是background的缩写,此命令不会影响redis服务器处理其他客户端的请求和命令.此命令是redis通过多进程的方式来完成并发编程从而实现bgsave.

2.自动触发

我们可以在redis配置文件中,设置一下,让redis每隔多长时间以及每产生多少次修改就触发备份操作.

redis生成rdb文件,是存放在redis的工作目录中的,redis的工作目录也是在redis配置文件中进行设置的.

我们不仅可以修改redis的工作目录,也可以修改生成的rdb文件的名字.

dump.rdb是RDB机制生成的镜像文件,redis服务器默认是开启了rdb的.此rdb文件时一个二进制的文件,把内存中的数据,以压缩的形式,保存到这个二进制文件中.(压缩会消耗一定的cpu资源,但是能节省存储空间).

这个二进制文件,我们不能随意修改.redis服务器重新启动,会尝试加载这个rdb文件,如果发现格式错误,就可能会加载数据失败.

需要注意的是,rdb文件,即使我们不去主动修改它,但是也可能会出现一些意外情况,一旦通过一些操作(比如网络传输)引起这个文件被破坏,此时redis服务器也是无法正常启动的.

rdb的持久化操作可以执行多次,当执行生成rdb镜像文件操作的时候,此时就会把要生成的快照数据,先保存到一个临时文件中,当这个快照生成完毕之后,在删除之前的rdb文件,把新生成的rdb临时文件名字改为刚才的dump.rdb,所以自始至终,rdb文件是始终只有一个的.


RDB自动触发的条件

我们可以在redis的配置文件中查看达到自动触发rdb的条件. 

15分钟之后如果至少修改了一次或者5分钟之后至少修改了10次或者1分钟之后至少修改了10000次就会自动触发rdb机制.

注意:时间要满足的同时修改次数也要满足.

此处的数值都可以自行修改.但是修改上述的数据的时候,要有一个基本的原则:生成一个rdb快照,是一个比较高的成本,不能让这个操作执行的太过频繁.

也正是因为rdb生成的不能太过频繁,这就导致,快照里的数据,和当前实际的数据情况可能是存在偏差的.


手动执行bgsave触发一次生成快照

由于这里的数据比较少,执行bgsave瞬间就完成了,立即查看应该是有结果的.如果这里的数据比较多,执行bgsave就可能需要消耗一定的时间,立即查看不一定就是生成完毕了.

在rdb镜像文件里可以隐约的看到我们的插入的key.

我们重启redis服务器,再次进入redis客户端查看数据.

通过上述操作,就可以看到,redis服务器在重启的时候,加载了rdb文件的内容,恢复了之前内存中的数据状态.


插入新的key,不手动执行bgsave

我们插入一个新的key之后,重新启动redis服务器,再次查看内容.

可以看到我们新插入的key4依然存在,但是我们并没有手动执行bgsave,同时也没有达到自动触发的条件,这是什么原因呢?

这是因为如果是通过正常流程重新启动redis服务器,此时redis服务器会在退出的时候自动触发生成rdb的操作.但是如果是异常重启(kill -9或者服务器掉电),此时redis服务器来不及生成rdb,内存中尚未保存的数据就会随着redis启动而真的丢失了!!!

所以redis自动触发rdb会在多个场景中存在:

1.在配置文件中配置save 时间 次数,表示在多长时间之后,执行次数达到多少,才触发.

2.通过shutdown命令(不带参数),关闭redis服务器,此处的关闭属于是正常关闭,也会触发生成rdb快照的操作.我们上述的service redis-server restart也属于是正常关闭.

3.redis进行主从复制的时候,主节点也会自动生成rdb快照,然后把rdb快照文件内容传输给从节点.

如果正常情况的关闭,我们是不必担心内存数据丢失的情况,在实际开发中我们更担心异常情况的出现导致redis服务器异常关闭.比如使用kill命令(kill -9 redis进程id)的方式来直接杀死redis进程,此时就会导致新插入的数据的丢失.

注意在ubuntu系统下,由于我们是通过service的方式来启动redis,所以会存在一个守护进程来时刻检测redis的情况,当redis服务器挂掉之后,会迅速在拉起一个redis,所以虽然kill掉了redis进程,但是查看进程信息redis还存在,但是此时的进程id已经不一致了.


bgsave操作流程是创建子进程,由子进程完成持久化操作.

持久化会把数据写入到一个新的临时文件中,最后使用新的文件来代替旧的文件.

如果直接使用save命令,此时是不会创建子进程和进行文件替换的.save命令是直接在当前进程中,往同一个文件中写入数据,不会创建新的文件.

inode相当于是文件的标识,inode不同,说明文件已经不是同一个文件了.


通过配置自动生成rdb快照

我们可以在配置文件中修改save来设置自动生成快照的条件.对于redis来说,修改配置文件之后,一定要重启服务器,才能生效,如果想要立即生效,也可以通过命令的方式修改.

save " "是用来关闭自动生成快照的.


当我们把rdb的文件改坏了,会发生什么

手动的把rdb的文件改坏,然后一定是通过kill进程方式,重新启动redis服务器.

如果是通过service redis-server restart重启,就会在服务器退出的时候,重新生成rdb快照,就把刚才改坏掉的文件替换掉了,所以要使用kill的方式.

由于rdb文件时二进制的,直接把改坏掉的rdb文件交给redis服务器去使用,得到的结果是不可预期的.

如果改的地方正好是文件末尾,对前面的内容没有影响,可能redis再次启动还是可以恢复正常的数据的.

对于rdb文件损坏,可能redis服务器启动得到的数据正确性可能有问题,也可能redis服务器直接就启动失败了.

redis也提供了rdb文件的检查工具,可以先通过检查工具,检查一下rdb的文件格式是否是符合要求的.


AOF

当开启aof的时候,rdb就不生效了,reids服务器启动的时候就不再读取rdb文件的内容了.

会把用户的每个操作都记录到文件中.当redis重新启动的时候,就会读取这个aof文件中的内容,用来恢复数据.

aof默认一般是关闭状态,修改配置文件,来开启aof功能.

修改为yes开启.

aof文件所在的位置和rdb文件在同一目录下.(/var/lib/redis)

aof是一个文本文件,每次进行的操作都会记录到文本文件中,通过一些特殊符号作为分隔符,对命令的细节做出区分.

引入aof之后,既要写内存又要写硬盘,redis是不是就变慢了?

redis是一个单线程的服务器,速度很快(快就快在直接操作内存).引入aof之后,实际上对于redis来说,是没有影响的.并没有影响redis处理请求的速度.原因有两点:

1.aof机制并非是直接让工作线程将数据写入硬盘,而是先写入一个内存中的缓冲区,当缓冲区的数据积累到一定量之后,在统一写入内存.引入缓冲区之后,就大大降低了写硬盘的次数.写硬盘的时候,写入硬盘数据的多少,对于性能的影响不是很大,关键是写硬盘的次数多了,影响就比较大了.

2.硬盘上读写数据,顺序读写的速度是比较快的,随机访问速度是比较慢的.aof是每次把新的操作写入到原有的文件的末尾,属于是顺序写入.


如果把数据写入到缓冲区里,本质还是在内存中,如果这个时候,进程突然崩溃或者主机掉电,缓冲区中的数据还没来得及写入到硬盘中,那么这一部分数据就丢失了.

所以,redis给出了一些选项,来取舍刷新频率和性能.

刷新频率越高,那么对性能的影响就越大,但是数据的可靠性就越高.

刷新频率越低,性能影响的越小,但是数据的可靠性就越低.


aof重写机制

当aof文件持续增长,体积就会越来越大,会影响到redis下次启动时的启动时间.

为了解决这个问题,就出现了重写机制.

重写机制是因为在zof文件中,有一些内容是冗余的,比如对一个key修改了多次,但是我们在下次启动的时候,只是关注这个key的最终结果的,至于它是修改了几次我们是不关注的,比如删除一个key,或者set了多个key我们可以用mset命令.

重写其实就是对aof文件进行整理操作,这个整理能够提出其中的冗余操作,并且合并一些操作,达到给aof文件瘦身的效果.

AOF 重写过程可以⼿动触发和⾃动触发:
• ⼿动触发:调⽤ bgrewriteaof 命令。
• ⾃动触发:根据 auto-aof-rewrite-min-size 和 auto-aof-rewrite-percentage 参数确定⾃动触发时
机。
auto-aof-rewrite-min-size:表⽰触发重写时 AOF 的最⼩⽂件⼤⼩,默认为 64MB。
auto-aof-rewrite-percentage:代表当前 AOF 占⽤⼤⼩相⽐较上次重写时增加的⽐例.


aof重写流程

父进程通过fork操作创建出子进程.

父进程仍然负责接收请求,子进程负责针对aof文件重写.在重写的时候,不关心aof文件中原来的内容,只是关心内存中最终的数据状态.

子进程只需要把内存中当前的数据,获取出来,以aof的格式,写入到一个新的aof文件中.(内存中的数据状态,就已经相当于是aof文件结果整理后的模样了).

子进程写新的aof文件的同时,父进程仍然在不停的接收客户端的请求,父进程还是会把这些请求产生的aof数据先写入到缓冲区,在刷新到原有的aof文件中.

在创建子进程的瞬间,子进程就继承了当前父进程的内存状态.因此,子进程里的内存数据是父进程fork之前的状态,fork之后,新来的请求对内存造成的影响,是子进程感知不到的.

所以,此时父进程又准备了一个aof_rewrite_buf缓冲区,专门用来存放fork之后收到的数据.当子进程把aof数据写完之后,会通过信号通知父进程,父进程在把aof_rewrite_buf中的内容也写入到新的aof文件里.

此时就可以用新的aof文件代替旧的文件了.


如果在执行bgrewriteaof的时候,当前reids已经在进行aof重写了,此时就不会再次执行aof重写了,会直接返回.

如果,在执行bgrewriteaof的时候,当前redis正在生成rdb文件的快照,那么aof操作就会等待,等到rdb快照生成完毕之后,在进行执行aof操作.

rdb对于fork之后的数据,就直接置之不理了.aof则对于fork之后的数据,采取了aof_rewrite_buf缓冲区的方式来处理.这也很符合它们的设计理念.rdb只是用来定期备份(定期备份就难以和最新的数据保持一致),aof则是实时备份.

父进程fork完毕之后,就已经让子进程写新的aof文件了,并且一段时间过后,子进程很快的完成了工作,新的文件代替旧的文件.那么,父进程还有必要继续写这个即将被替换的旧的文件吗?

是有必要的.考虑到极端情况,假设在重写过程中,重写到一半,服务器崩溃了,子进程内存的数据就丢失了,而新的aof文件内容还不完整,所以如果父进程不坚持写旧的aof文件,在这种情况下,reids重启就无法保证数据的完整性了.


混合持久化

aof本来是按照文本的方式来写入文件的,但是文本的方式写文件,后续加载的成本是比较高的.

此时redis就引入了混合持久化的方式,结合rdb和aof的特点.

按照aof的方式,每一个请求或者操作都会记录到文件中.

在触发aof重写之后,就会把当前的内存状态按照rdb的二进制格式写入到新的aof文件,后续再进行的操作,仍然是按照aof文本的方式追加到aof文件后面.

yes表示开启混合持久化.


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/160101.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

动态跳过测试用例

动态跳过测试用例 说明 我们可以通过指定环境变量来动态判断是否执行指定的测试用例设置环境变量有很多种方法,例如命令行方式,格式:--env keyval1,key2val2 ,若需要指定多个环境变量则需要逗号来隔开,而不是空格 t…

Live800:企业提升客户互动体验,有哪些关键因素?

如今,随着信息时代的不断发展,企业已经不再是单向的商业机构,他们需要与客户进行及时的沟通与反馈,从而更好地提升客户互动体验,达到营销和用户体验的双赢局面。那么,企业如何提升客户互动体验呢&#xff1…

设计模式——RBAC 模型详解

1.什么是 RBAC 呢? RBAC 即基于角色的权限访问控制(Role-Based Access Control)。这是一种通过角色关联权限,角色同时又关联用户的授权方式。 简单地说:一个用户可以拥有若干角色,每一个角色又可以被分配…

Linux程序之可变参数选项那些事!

一、linux应用程序如何接收参数? 1. argc、argv Linux应用程序执行时,我们往往通过命令行带入参数给程序,比如 ls /dev/ -l 其中参数 /dev/ 、-l都是作为参数传递给命令 ls 应用程序又是如何接收这些参数的? 通常应用程序都…

Raspberry Pi 5 新一代单板计算机:树莓派5代 (介绍、入门、解疑)

树莓派5代正式发布后,硬件和性能的全面升级让众多开发者们都想入手感受一波,外观上Raspberry Pi 5 与前代产品非常相似,不过,在保留信用卡大小的整体尺寸的同时,也更新了一些设计元素,以适应新芯片组的功能…

python实现调和反距离空间插值法AIDW

1 简介 AIDW 主要是针对 IDW 的缺点进行了改进,考虑了样本点与预测点的位置,即方向和距离,具体见下图: 2 改进 IDW 公式: 从IDW算法可看出,插值点的估算值仅与插值样本距插值点的远近相关,并未…

贝叶斯AB测试

AB测试是用来评估变更效果的有效方法,但很多时候会运行大量AB测试,如果能够在测试中复用之前测试的结果,将有效提升AB测试的效率和有效性。原文: Bayesian AB Testing[1] 随机实验,又称AB测试,是行业中评估因果效应的既…

【Mysql】[Err] 1293 - Incorrect table definition;

基本情况 SQL文件描述 /* Navicat MySQL Data TransferSource Server : cm4生产-200 Source Server Version : 50725 Source Host : 192.168.1.200:3306 Source Database : db_wmsTarget Server Type : MYSQL Target Server Version : 50725 File…

vxe编辑保存表格

业务需求: 1、需要点击编辑时,全部表格显示编辑框,点击保存,全部保存。 2、因为位置问题,产品经理把24小时分成了两行,开发就得分两个表格。列标题是写死的,文字偏移也是写死的,其他…

服务器主机安全的重要性及防护策略

在数字化时代,服务器主机安全是任何组织都必须高度重视的问题。无论是大型企业还是小型企业,无论是政府机构还是个人用户,都需要确保其服务器主机的安全,以防止数据泄露、网络攻击和系统瘫痪等严重后果。 一、服务器主机安全的重…

__int128类型movaps指令crash

结论 在使用__int128时,如果__int128类型的内存起始地址不是按16字节对齐的话,有些汇编指令会抛出SIGSEGV使程序crash。 malloc在64位系统中申请的内存地址,是按16字节对齐的,但一般使用时经常会申请一块内存自己切割使用&#…

static和extern

1.extern extern 是⽤来声明外部符号的,如果⼀个全局的符号在A⽂件中定义的,在B⽂件中想使⽤,就可以使⽤ extern 进⾏声明,然后使⽤。 即在一个源文件中想要使用另一个源文件,即可通过这个extern来声明使用。 2.st…

未来制造业的新引擎:工业机器人控制解决方案

制造业正经历着一场革命性的变革 在这个变革的浪潮中,工业机器人成为推动制造业高效生产的关键力量。然而,要发挥机器人的最大潜力,一个强大而智能的控制系统是必不可少的。在这个领域,新一代的工业机器人控制解决方案正崭露头角&…

学习MySQL先有全局观,细说其发展历程及特点

学习MySQL先有全局观,细说其发展历程及特点 一、枝繁叶茂的MySQL家族1. 发展历程2. 分支版本 二、特点分析1. 常用数据库2. 选型角度及场景 三、三大组成部分四、总结 相信很多同学在接触编程之初,就接触过数据库,而对于其中关系型数据库中的…

这样写postman实现参数化,阿里p8都直呼牛逼

什么时候会用到参数化 比如:一个模块要用多组不同数据进行测试 验证业务的正确性 Login模块:正确的用户名,密码 成功;错误的用户名,正确的密码 失败 postman实现参数化 在实际的接口测试中,部分参数…

你的关联申请已发起,请等待企业微信的管理员确认你的申请

微信支付对接时,需要申请AppID,具体在下面的位置: 关联AppID,发起申请时,会提示这么一句话: 此时需要登录企业微信网页版,使用注册人的企业微信扫码登录进去,然后按照下面的步骤操作即可。 点击…

iEnglish全国ETP大赛:教育游戏助力英语习得

“seesaw,abacus,sword,feather,frog,lion,mouse……”11月18日,经过3局的激烈较量,“以过客之名队”的胡玲、黄长翔、林家慷率先晋级“玩转英语,用iEnglish”第三届全国ETP大赛的16强,在过去的周末中,还有TIK徘徊者队、不负昭华队、温柔杀戮者队先后晋级。据悉,根据活动规则,在…

电脑内存升级

ddr代兼容 自从DDR内存时代开启之后,只要满足内存的插槽规格相同(DDR3或DDR4或DDR5即为内存规格)这一条件,不同品牌、不同频率以及不同容量的茶品都可以一起使用,除了品牌和容量的影响之外,不同频率的搭配可能会造成性能方面的影…

面试官:什么是三色标记

程序员的公众号:源1024,获取更多资料,无加密无套路! 最近整理了一波电子书籍资料,包含《Effective Java中文版 第2版》《深入JAVA虚拟机》,《重构改善既有代码设计》,《MySQL高性能-第3版》&…

HCIA-实验命令基础学习:

视频学习: 第一部分:基础学习。 19——子网掩码。 27——防火墙配置: 32——企业级路由器配置: 基础实验完成:(完成以下目录对应的实验,第一部分基础实验就完成。) 方法&#xff…