您的位置:首页 > 财经 > 产业 > 施工企业工程施工科目_设计深圳网站制作_网络销售技巧_苏州网站建设优化

施工企业工程施工科目_设计深圳网站制作_网络销售技巧_苏州网站建设优化

2025/6/26 3:05:51 来源:https://blog.csdn.net/wk200411/article/details/147025507  浏览:    关键词:施工企业工程施工科目_设计深圳网站制作_网络销售技巧_苏州网站建设优化
施工企业工程施工科目_设计深圳网站制作_网络销售技巧_苏州网站建设优化

Redis持久化

  • 一.认识持久化
    • 1.简单介绍
    • 2.持久化策略
  • 二.RDB
    • 1.快照
    • 2."定期"
      • fork
    • 3.RDB演示
      • (1)手动执行save&bgsave触发一次生成快照
      • (2)插入key,不手动执行bgsave
      • (3)执行bgsave后,新旧文件的替换
      • (4)通过配置自动生成rdb快照
      • (5)rdb文件内容被故意删改
      • 4.RDB的优缺点
  • 四.AOF
    • 1.AOF的简介
    • 2.AOF是否影响Redis性能
    • 3.缓冲区刷新策略
    • 4.AOF重写机制
      • (1)重写流程
      • (2)重写流程中的问题
    • 5.混合持久化

一.认识持久化

1.简单介绍

持久化简单的理解就是把数据存在硬盘上,这样数据就不会丢失了,但是redis是将数据存储到内存上的,怎么就能够持久化数据呢?这是因为redis在硬盘中也是存储了数据的。

为了保证查询的速度够快,数据肯定是得在内存中的,但是为了持久,就必须存储在硬盘上,此时这两份数据理论上是完全相同的,实际上可能会存在一点差异,差异主要取决于用户如何进行数据的持久化操作的。

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

2.持久化策略

RDB
RDB(Redis Database)简单地说,可以理解为定期备份。

举个栗子:
身为八尺男孩怎么可能会没有一点学习资料嘞,那肯定是有的兄弟,所以呢,我害怕某天我的电脑硬盘炸了,那我的学习资料不就毁于一旦了吗,那可是我目前毕身的心血。

所以我搞了一个移动硬盘,或者搞个网盘也是可以的,我会每周对新找到的学习资料进行上传到我的移动硬盘或者网盘中,这样即使我电脑的硬盘炸了,我的学习资料依旧在我的备份盘中。

AOF
AOF(Append Only File),简单地说,可以理解为实时备份。

举个栗子:
我记得我在同学的苹果手机上看到过,IOS系统上有个iCloud这个玩意儿,我每次看到我同学搞了新照片,这个苹果手机就会对照片啊啥的进行实时备份,也就是说一旦有新的数据进入手机,就会对数据进行备份。

二.RDB

1.快照

RDB定期的把Redis内存中的所有数据都写入硬盘中,生成一个"快照"。

“快照"简单地说就是记录下当前redis给内存中存储的数据,将这些"快照"后的"照片”,生成一个文件,存储到硬盘中。

后续redis重启服务器了(内存数据就会丢失),就可以根据刚才的"快照"就能够把内存中的数据给恢复回来。

2.“定期”

定期的方式有两种,一种是手动触发,另外一种则是自动触发。

手动触发
程序员通过redis客户端,执行特定的命令来触发快照的生成,主要是两个命令,一个是save,另一个是bgsave。

save: 执行save命令后,redis就会全力以赴的快照的生成操作,此时就会阻塞redis的其他客户端的命令,导致类似于keys *的后果,所以一般不建议使用save

bgsave: bg是background的缩写,这个命令执行后则不会影响redis服务器处理其他客户端的请求和命令。此处redis并不是通过多线程的方式进行的并发编程,而是通过多进程的方式实现的并发编程。

bgsave命令的工作流程:

  1. 父进程就是redis的服务器,当接收到bgsave的命令后,会先判断当前是否已经存在其他正在工作的子进程,如果此时已经有子进程正在执行bgsave,此时就直接把当前的bgsave返回。

  2. 如果当前没有其他正在工作的子进程,就通过fork创建一个子进程。

fork

(fork:是Linux系统提供的一个创建子进程的API,但是在其他系统中创建子进程就不是fork。fork创建子进程是通过简单粗暴地复制方式来创建子进程的。一旦复制完成,父子进程就是两个独立的进程,各自就会执行各自的)

fork中的复制一份,会将父进程中的pcb,虚拟地址空间,文件描述符表……都会完全的复制。此时redis服务器中原本就有若干的变量而且也保存了一些键值对数据,因为fork的执行,子进程的这个内存里也会存在和刚才父进程中一模一样的变量。

因此,通过子进程执行持久化操作,也就相当于把父进程本体的内存数据进行了持久化了。如果父进程打开一个文件还进行了fork,那么子进程也是可以使用这个文件,也就导致了子进程持久化写入的那个文件和父进程的本来要写的文件是同一个。

如果,当前redis 服务器中存储的数据很多,内存消耗特别大,此时进行上述的复制操作,性能的开销其实不是很大,因为fork在进行内存拷贝的时候,不是简单的直接把所有数据都拷贝一遍,而是通过“写时拷贝”的机制来完成的。

如果子进程内存里的内存数据和父进程的内存数据完全一样,此时就不会真正的触发拷贝动作,而是两个进程共用同一份的数据。因为这两个进程的内存空间是相互独立的,只有当某一个进程的内存数据修改了之后才会触发真正物理内存上的数据拷贝。

  1. 子进程负责进行写文件,生成快照的过程,父进程继续接收客户端的请求,继续正常的提供服务。
  2. 子进程完成整体的持久化过程之后,就会通知父进程已经执行完毕,于是父进程就会更新一些统计信息,子进程就可以销毁了。
    在这里插入图片描述

RDB的镜像文件

redis生成的RDB文件是存放在redis的工作目录中的,所谓的工作目录也是在redis 的配置文件中进行设置的。

存放的目录:在这里插入图片描述
这个目录下会有一个rdb机制生成的镜像文件(redis服务器是默认开启了rdb的),当执行了生成rdb镜像操作的时候,此时就会把要生成的快照数据,先保存到一个临时文件中,当这个快照生成完毕之后,再删除之前的rdb文件,再把新生成的临时rdb文件名改成刚才的文件名。

3.RDB演示

(1)手动执行save&bgsave触发一次生成快照

插入数据后进行了手动的备份生成了快照:
在这里插入图片描述
先通过cd /etc/redis/的命令后,在通过 vim redis.conf找到rdb文件,在通过cd /var/lib/redis 和 vim dump.rdb文件查看里面的快照信息:
在这里插入图片描述
重启后服务器,通过rdb恢复了之前的数据:在这里插入图片描述

(2)插入key,不手动执行bgsave

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

此时再插入一条key,并且没有执行bgsave操作:
在这里插入图片描述
此时重启服务器后,key4的仍然存在:
redis生成快照的操作,不仅仅是手动执行命令才触发的,也可以自动触发。
在这里插入图片描述

1)可以通过配置文件中save执行M时间内,修改N次的方式进行自动触发。在这里插入图片描述

2)通过shutdown命令(redis的命令)关闭redis服务器也会触发。(service redis-server restart属于正常关闭)

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

此时在插入一条key,此时直接使用kill杀死redis服务器

此时通过将原来的redis服务器的端口号进行杀死,虽然此时redis服务器换了其他的端口号存在,但是这时的redis服务器属于重新启动了。

在这里插入图片描述
此时模拟redis服务器崩溃后,重新进入redis客户端,此时key5就不存在在这里插入图片描述

(3)执行bgsave后,新旧文件的替换

通过Linux的stat命令,查看文件的inode编号,就可以知道文件是否改变。

执行bgsave之前的inode
在这里插入图片描述
执行bgsave后的inode
在这里插入图片描述
此时文件已经不是同一个文件了,只不过内容是一样的,因为inode就类似于文件的身份标识符。如果上述操作使用的命令是save,则不会触发子进程和文件替换的逻辑,而是直接在当前进程中,往刚才的同一个文件中写入数据了。

Linux的文件系统典型的组织方式(ext4),主要是把这个文件系统分成了三个大的部分

  1. 超级块(放的是一些管理信息)
  2. inode区(存放inode节点,每个文件都会分配一个inode数据结构,包含了文件的各种元数据)
  3. block区,存放文件的数据内容。

(4)通过配置自动生成rdb快照

通过配置文件中自动生成rdb的属性进行更改,更改后,还需要重新启动服务器

如果设置成save ""则关闭自动生成快照

在这里插入图片描述
此时在进行插入2个数据后,等待60秒后观察dump.rdb文件信息:
在这里插入图片描述
在这里插入图片描述

(5)rdb文件内容被故意删改

将rdb文件内容随便删改后,需要通过kill -9的方式来进行重启服务器,不然redis的服务器通过restart的命令则会在结束服务器的时候重新生成一个快照(rdb)文件,此时原来修改过的rdb文件则被覆盖了。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

此时更改了rdb文件的内容,如果是更改的末尾,一般来说还是能够获取到key的值的,但是如果更改的是文件写好的内容,此时就会导致redis 的服务器没办法重启了.
在这里插入图片描述
在这里插入图片描述

此时可以通过查看redis 的日志来观察报错信息。查看redis的日志信息,通过cd /var/log/redis,在通过ll 就能看到redis的日志文件,日志文件中,带有gz的是压缩包,所以直接vim redis-server.log就能够查看日志里面的信息了:
在这里插入图片描述
在这里插入图片描述

rdb文件是二进制的,直接就把改崩了的rdb文件交给redis服务器去使用,得到的结果是不可预期的,可能redis服务器能启动,但是得到的数据可能正确也可能有问题,也可能redis服务器直接启动失败。

redis也提供了rdb文件的检查工具,可以先通过检查工具,检查一下rdb文件格式是否符合要求,在把rdb文件交给服务器。

先通过cd /usr/bin进入检查工具的文件中,在使用**ll redis-***就可以看到redis中提供的检查工具了:

通过上述的指令输入后,就能够得到此时的rdb是存在问题的:
在这里插入图片描述

4.RDB的优缺点

RDB是⼀个紧凑压缩的⼆进制文件,代表Redis在某个时间点上的数据快照。非常适用于备份,全量复制等场景。

比如每6小时执行bgsave备份,并把RDB文件复制到远程机器或者文件系统中(如hdfs)用于灾备。

  • Redis加载RDB恢复数据远远快于AOF的方式。
  • RDB方式数据没办法做到实时持久化/秒级持久化。因为bgsave每次运行都要执行fork创建子进程,属于重量级操作,频繁执行成本过高。
  • RDB文件使用特定二进制格式保存,Redis版本演进过程中有多个RDB版本,兼容性可能有风险

四.AOF

1.AOF的简介

AOF类似于MySQL中的binlog,会把用户的每个操作,都记录到文件中,当redis重新启动的时候,就会读取这个AOF文件中的内容,用来恢复数据,当AOF开启时,RDB就不在生效了。

AOF的功能是默认关闭的,所以需要手动打开,先使用cd /etc/redis后,再使用vim redis.conf进入配置文件,将appendonly no的no改成yes即可,红色的字体是
在这里插入图片描述

此时设置一些key,就可以在AOF的文本文件中找到(通过cd /var/lib/redis进入这个目录中,在通过vim appendonly.aof进入到AOF文件中,因为此时AOF已经开启了,所以即使dump.drb文件是该崩溃的,也没有关系 ):
在这里插入图片描述
即使此时将redis服务器使用kill杀死,在重新启动redis服务器后,数据还是会存在:
在这里插入图片描述

2.AOF是否影响Redis性能

AOF机制并没有降低redis处理请求的速度,因为AOF机制并非是直接让工作线程把数据写入硬盘,而是先写入一个内存中的缓存区,积累一波之后,再统一写入硬盘。

AOF的内存缓存区降低了写硬盘的次数,并且AOF是把每次新的操作写入到原有文件的末尾,属于顺序写入,而不是随机访问,这样速度就不会很慢,但是还是比内存的速度要慢很多。

在这里插入图片描述

3.缓冲区刷新策略

如果把数据写入到缓存区里,本质还是在内存中,此时如果进程突然挂了或者主机掉电了,缓存区的数据就会丢失。

于是redis给出了一些选项,可以让用户根据实际情况做出取舍,这也就诞生了缓冲区的刷新策略,在redis中的配置文件(redis.conf)修改appendfsync参数来控制不同值下的缓冲区刷新策略:
在这里插入图片描述

  1. always:频率最高,数据可靠性最高,但是性能最低。
  2. everysec:频率会低一些,数据可靠性也会低一些,但是性能提高了一些。
  3. no:频率最低,数据可靠性最低,性能最高。

4.AOF重写机制

AOF文件持续增长,体积就会越来越大,这样会影响到redis下次启动的启动时间,因为redis启动的时候要读取AOF文件的内容,但是AOF中的文件,会有一些冗余内容。

于是redis就存在了一个重写机制来针对AOF文件进行了整理操作,这个整理能够剔除其中的冗余操作,并且合并一些操作,达到给AOF文件瘦身的效果。

AOF的重写机制也分成两种,一种手动触发,一种自动触发

手动触发是通过bgrewriteaof

自动触发是通过配置文件根据auto-aof-rewrite-min-sizeauto-aof-rewrite-percentage参数确定自动触发时机。

  • auto-aof-rewrite-min-size:表示触发重写时AOF的最小文件大小,默认为64MB。
  • auto-aof-rewrite-percentage:代表当前AOF占用大小相比较上次重写时增加的比例

(1)重写流程

自动和手动触发的流程图差不多:
在这里插入图片描述

创建子进程的fork和RDB中是一样的,此处不再过多赘述,父进程也是仍然负责接收请求,子进程负责针对AOF文件进行重写。重写的时候不会关心AOF文件中原来存在那些数据,只关心内存中最终的数据状态。

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

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

在创建子进程的一瞬间,子进程就继承了当前父进程的内存状态,因此,子进程力的内存数据是父进程fork之前的状态,fork之后,父进程收到的新请求导致对内存造成的修改,子进程是不知道的。

此时父进程在又准备了一个aof_rewrite_buf缓冲区,专门放fork之后接收到的数据,子进程把AOF数据写完之后会通过信号通知父进程。父进程再把aof_rewrite_buf缓冲区中的内容也写到新的AOF文件中,此时新的AOF文件就可以替代旧的AOF文件了。

(2)重写流程中的问题

如果在执行bgrewriteaof的时候,当前redis正在进行AOF重写,此时就不会再次执行AOF重写,直接就返回了。但如果redis是在生成rdb文件的快照,此时AOF重写操作就会进行等待,当rdb快照生成完毕之后,在执行AOF重写。

rdb对于fork之后的新数据就直接不做处理,AOF则对于fork之后的新数据,采取了aof_rewrite_buf缓冲区的方式来处理。

这不过只是因为rdb本身的设计理念就是定期备份,定期备份肯定没办法想实时更新的备份一样和原数据进行保持一致。

父进程fork完毕之后,已经让子进程写新的AOF文件了,随着时间的推移,子进程很快就写完了新的文件,于是让新的AOF文件代替旧的。此时父进程还在继续写即将消亡的旧文件是有意义的。

如果在重写过程中,这个过程只执行了一半,此时服务器挂了,子进程内存的数据就会丢失,新的AOF文件内容还不是完整的,所以如果父进程不坚持写旧的AOF文件,重启就没办法保证数据的完整性了。

5.混合持久化

AOF原本是按照文本的方式写入文件的,但是文本的方式写文件,后续加载的成本是比较高的,于是redis就引入了混合持久化的方式,结合了rdb和aof的特点。

按照AOF的方式,每一个请求/操作都记录入文件中,在触发AOF重写之后,就会把当前内存的状态按照RDB的二进制文件格式写入到新的AOF文件中,后续在进行的操作仍然是按照AOF文本的方式追加到文件后面。

此时创建几条数据后,AOF还是文本数据类型:在这里插入图片描述

在这里插入图片描述

此时启动bgrewriteaof就开始实时备份数据:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如果此时再加入一个数据,此时后续添加的也是文本数据:
在这里插入图片描述

上述的混合持久化可以通过配置文件中的aop-use-rdb-preamble yes中的yes改成no则不会进行混合持久化操作了,如果修改了之后就需要重启服务器。

redis同时存在AOF文件和RDB文件,此时还是以AOF为主,下图是解释图:
在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com