• 【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这样的方式可以传输任意的数据~
      因此,像上述父子进程场景中,子进程表达“我干完了”

  • 相关阅读:
    【YOLO格式的数据标签,目标检测】
    STM32实战总结:HAL之DAC
    在 Ubuntu 20.04 上,将 Subversion 从默认的 1.13.0 降级到 1.9.7。 解决svn无法保存密码问题
    UVM driver和sequencer握手机制 get_next_item() 和 get() and put()
    Java集合部分总结
    CTF训练 web安全SQl注入(X-Forwarded-For报文头)
    【工具】Git-码农“吃饭的碗”要拿好
    Redis的事务
    【新书推荐】当 Python 遇到 ChatGPT —— 自动化办公落地
    智慧工地施工如何应用室内定位uwb技术
  • 原文地址:https://blog.csdn.net/weixin_61341342/article/details/133851911