【Redis】Redis持久化策略

目录

策略

  1. RDB => Redis DataBase 相当于定期的方式实现持久化
  2. AOF => Append Only File 相当于实时的方式实现持久化

RDB

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

Redis给内存中当前存储的这些数据,赶紧拍个照片,生成一个文件,存储在硬盘中~~

后续Redis一旦重启了,就可以根据刚才的"快照"就能把内存中的数据给恢复回来~
"定期"具体来说,又有两种方式:

1.手动触发.

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

save

bgsave

2.自动触发.

在Redis配置文件中,设置一下,让Redis每隔多长时间/每产生多少次修改就触发。
save:执行save的时候,redis就会全力以赴的进行"快照生成"操作,此时就会阻塞redis的其他客户端的命令~导致类似于keys*的效果

一般不建议使用save

bgsave:bg=>background 不会影响Redis服务器处理其他客户端的请求和命令

Redis咋做到的?是不是搞了个多线程啥的?

并非如此!!

并发编程的场景.此处redis使用的是"多进程"的方式,来完成的并发编程,来完成的bgsave的实现。

bgsave执行流程

1.判断当前是否存在其他正在工作的子进程。

比如现在已经有一个子进程正在执行bgsave,此时就直接把当前的bgsave返回~

2.如果没有其他的工作子进程,就通过fork这样的系统调用创建一个子进程来~

fork是linux系统提供的一个创建子进程的api(系统调用)

fork创建子进程,简单粗暴,直接把当前的进程(父进程)复制一份,作为子进程~

一旦复制完成了,父子进程就是两个独立的进程,就各自执行各自的了~~

3.子进程负责进行写文件,生成快照的过程.

父进程继续接收客户端的请求,继续正常提供服务.

4.子进程完成整体的持久化过程之后,就会通知父进程,干完了,父进程就会更新一些统计信息,子进程就可以结束销毁了。

RDB效果演示




rdb文件中的数据,不是你这边插入了数据,就会立即更新的!!


1.手动执行save&bgsave触发一次快照

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



通过上述操作,就可以看到,redis服务器在重新启动的时候,加载了rdb文件的内容,恢复了内存中之前的状态。
2.插入新的key,不手动执行bgsave


发现没有,重新启动redis服务器

发现就有了,redis生成快照操作,不仅仅是手动执行命令才触发,也可以自动触发!!

1)通过刚才配置文件中save执行M时间内,修改N次

2)通过shutdown命令(redis里的一个命令)关闭redis服务器,也会触发。

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

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

3.bgsave操作流程是创建子进程,子进程完成持久化操作.
持久化会把数据写入新的文件中,然后使用新的文件替换旧的文件.

liunx文件系统.

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

1.超级块(放的是一些管理信息)

2.inode区(存放inode节点,每个文件都会分配一个inode数据结构,包含了文件的各种元数据)

3.block区,存放文件的数据内容了。
4.通过配置自动生成rdb快照

执行FLUSHALL也会清空rdb文件

5.如果把rdb文件,故意改坏了,会咋样?

手动的把rdb文件内容改坏.

然后一定是通过kill进程的方式,重新启动redis服务器.

如果通过service redis-server restart重启,就会在redis服务器退出的时候,重新生成rdb快照。

就把咱门刚才改坏了的文件给替换了~~

RDB优缺点

  • RDB是一个紧凑压缩的二进制文件,代表Redis在某个时间点上的数据快照。非常适用于备份,全量复制等场景,比如每6小时执行bgsave备份,并把RDB文件复制到远程机器或者文件系统中用于灾备。

  • Redis加载RDB恢复数据远远快于AOF的方式。

  • RDB方式数据没办法做到实时持久化/秒级持久化。因为bgsave每次运行都要执行fork创建子进程,属于重量级操作,频繁执行成本过高。

  • RDB文件使用特定二进制格式保存,Redis版本演进过程中有多个RDB版本,兼容性可能有风险。

AOF

类似于mysql的binlog,就会把用户的每个操作,都记录到文件中。

当redis重新启动的时候,就会读取这个aof文件中的内容,用来恢复数据~

开启aof的时候,rdb就不生效了~

启动的时候不再读取rdb文件内容了~

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

AOF是一个文本文件.

每次进行的操作,都会被记录到文本文件中~

通过一些特殊符号作为分隔符,来对命令的细节做出区分~

AOF缓冲区刷新策略

实际上,是没有影响的!并没有直接影响到redis处理请求的速度~

1.AOF机制 并非是直接让工作线程把数据写入硬盘,而是先写入一个内存中的缓冲区,积累一波之后,再统一写入硬盘

2.硬盘上读写数据,顺序读写的速度是比较快的

随机访问则速度是比较慢的。

AOF是每次把新的操作写入到原有文件的末尾,属于顺序写入~

如果把数据写入到缓冲区里,本质还是在内存冲呀~

万一这个时候,突然进程挂了,或者主机掉点了,咋办?是不是缓冲区中的数据就丢了??

是的!!缓冲区中没来得及写入硬盘的数据是会丢的~

redis给出了一些选项,让程序员,根据实际情况来决定怎么取舍~缓冲区的刷新策略 ~

刷新频率越高,性能影响就越大,同时数据的可靠性就越高.

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

AOF的重写机制

AOF文件持续增长,体积越来越大~

会影响到,redis下次启动的启动时间~

redis启动的时候要读取aof文件的内容

注意!!上述aof中的文件,有一些内容是冗余的!

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

AOF重写机制的触发机制

  1. 手动触发:调用bgrewriteaof命令
  2. 自动触发:根据auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数确定自动触发时机

AOF重写流程

创建子进程fork

父进程仍然负责接收请求.

子进程负责针对aof文件进行重写~

注意!重写的时候,不关心aof文件中原来都有啥~

只关心内存中最终的数据状态~

子进程只需要把内存中给当前的数据,获取出来,以AOF的格式写入一个新的AOF文件中!!

此处子进程写数据的过程,非常类似于RDB生成一个镜像快照~

只不过RDB这里是按照二进制的方式生成的

AOF重写,则是按照AOF这里要求的文本格式来生成的.

子进程写新aof文件的同时,父进程仍然在不停的接收客户端新的请求。

父进程还是会写把这些请求产生的AOF数据写入到缓冲区,再刷新到原有的AOF文件里~

子进程这边,把aof数据写完之后,会通过信号通知一下父进程,父进程再把aof_rewrite_buf缓冲区中的内容也写入到新AOF文件里~








混合持久化

AOF本来是按照文本方式来写入文件的.

但是文本的方式写文件,后续加载的成本是比较高的~

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

按照aof的方式,每一个请求/操作,都记录入文件。在触发aof重写之后,就会把当前内存的状态按照rdb的二进制格式写入到新的aof文件中。

后续再进行的操作,仍然是按照aof文本的方式追加到文件后面。

这个选项为yes就是开启混合持久化。

同时存在aof和rdb快照,以谁为主?

以aof为主!

信号

信号这个东西,可以认为是Linux的神经系统~

进程之间的互相作用

但是Java生态并不鼓励使用多进程模型编程~

信号能表达的信息有限,并非像socket这样的方式可以传输任意的数据~

因此,像上述父子进程场景中,子进程表达"我干完了"

相关推荐
ImomoTo42 分钟前
HarmonyOS学习(十三)——数据管理(二) 关系型数据库
数据库·学习·harmonyos·arkts·鸿蒙
机器视觉知识推荐、就业指导3 小时前
Qt/C++事件过滤器与控件响应重写的使用、场景的不同
开发语言·数据库·c++·qt
jnrjian3 小时前
export rman 备份会占用buff/cache 导致内存压力
数据库·oracle
isNotNullX4 小时前
一文解读OLAP的工具和应用软件
大数据·数据库·etl
小诸葛的博客6 小时前
pg入门1——使用容器启动一个pg
数据库
大熊程序猿6 小时前
python 读取excel数据存储到mysql
数据库·python·mysql
落落落sss7 小时前
sharding-jdbc分库分表
android·java·开发语言·数据库·servlet·oracle
jnrjian7 小时前
Oracle 启动动态采样 自适应执行计划
数据库·oracle
lamb张7 小时前
MySQL锁
数据库·mysql