当前位置: 首页 > backend >正文

Redis持久化存储

        我们知道Redis是将数据放在内存中的,那怎么做到持久化存储呢?很简单,就是内存存一份,硬盘也存一份.那么两个地方都存会不会影响效率?答案是影响是不大的,要看具体的策略.同时也要注意内存的数据和硬盘中的数据可能会有一点不同.这也是取决于策略的不同.

        Redis持久化存储的两个策略:     

 1. RDB:定期备份

 2. AOF:实时备份

        我们先说第一种策略RDB
        Redis会定期将数据内存中的所有数据写入到硬盘之中,生成一个快照,将这些文件存储到一个文件中,如果电脑重启了,会根据这个文件来恢复数据.
         定期又有两种方式:一个是手动和通过配置文件来实现.
        手动方式有两个命令,一个是save,另一个是bgsave.其中save几乎不用,如果执行这个命令,redis会全力生成一个快照,很大可能会阻塞其他命令的执行,相当于keys *的效果.我们一般是用
bgsave这个命令,它不会产生阻塞,使用并发编程实现的,我们前面一直说redis是单线程,怎么会有并发编程,注意这里的并发编程是用进程实现的,不是线程.
        我们来说一下bgsave的原理,当执行这个命令的时候,会创建一个子进程,这个子进程和redis主进程里存储的数据几乎一模一样.可以理解为复制来的.
下面说一下创建子进程的机制,父进程会fork一个子进程,就主要来说一下这个fork.
       fork是linux系统提供的创建子进程的api(系统调用),这也就说明了redis只支持linux系统,在windows系统下是不支持的(我说的是以前,现在已经支持,但是linux更稳定,所以一般都是再linux使用redis).fork子进程的时候会将文件描述符表,pcb,虚拟地址空间(内存中的数据).
      fork在进行内存拷贝的时候不是无脑的直接把所有的数据都拷贝一遍,而是'写时拷贝'的机制来完成的.如果子进程和父进程的内存数据相同,则不会触发拷贝这个动作.

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

先打开redis的配置文件,找到dir 后面的路径就是rdb的路径.就是上面这个

我们再切换到这个路径下

打开这个文件
里面的内容我们是看不懂的.

下面再补充一张图,是关于bgsave的

这个图我们可以结合我上面说的来看

上面我们看的那个镜像文件我们看看就行了,千万不要乱改,要是改了重要的部分,我们下次启动redis的时候就会启动失败.

还有要补充的一点就是,rdb镜像文件自始至终只有一份,就是生成快照可能会有多次,会把生成的快照放到一个临时文件中,等快照生成完成就会将原来的rdb文件给替换掉.

下面就是说rdb的触发时机
rdb中的数据不是这边修改就会更新的.我们可以在配置文件中设置更新时间,其实我们使用默认的就好.太慢保证不了数据的准确性,太快则会影响性能
我们还是看一下redis配置文件是怎么写的吧.

可以自行阅读一下.
再说一下RDB的优缺点:

1.存在版本兼容问题
2.适合备份全量的数据
3.redis加载恢复数据RDB远高于AOF
4.无法做到实时持久化
 

AOF
aof做的事情就是将用户的每一个操作都记录再文件中,当开启aof的时候就会关闭rdb这个不用担心两者冲突的问题.
我们现在想一下,AOF是否会影响redis的性能?
引人aof后又要写内存,又要写硬盘,还能和之前一样快了吗?
这里说一下,并没有影响redis的性能
1.aof机制并非直接让工作线程把数据写入硬盘,而是先写入一个内存缓冲区,积累一波后,再统一写入硬盘.
2.硬盘上顺序读取数据的速度还是挺快的(当然还是比内存慢)
那么下面就说一下缓冲区的刷新策略
所谓的缓冲区,本质还是在内存中,如果是突然断电之类的,还是会丢失.所以redis提供了选项让我们选择就是配置文件中的appendfsync 三个选项分别是always,everysec,no

就是这个默认是everysec,我们在平时自己开发的过程中使用默认就好,不用修改.

好,下面介绍aof的重写机制
也是分为手动触发和自动触发(配置文件)

流程:
AOF重写的流程和RDB非常的相似,也是创建一个子进程,重写的时候,并不关心原来的aof文件中有啥,只关注内存中最终的数据状态.
子进程只需要把内存中数据获取出来,以aof的格式写入新的aof文件中,注意内存中的数据状态,就已经是相当于把aof文件结果整理后的样子了.
子进程写新的aof文件的同时父进程仍然会不停的接收客户端的请求,父进程还是会将在这些请求产生的aof数据先写入到缓冲区,再刷新到原有的aof文件中.
子进程被创建的瞬间就继承了父进程当前的内存数据.
因此,子进程里的内存数据是父进程fork之前的状态,fork之后,对内存中造成的修改,子进程是不知道的,此时,父进程这里又准备了一个aof_rewrite_buf缓冲区.
专门放fork之后收到的数据,子进程这边,把aof数据写完之后会通过信号通知一下父进程.父进程再把aof_rewrite_buf缓冲区的内容也会写到新aof文件中,最后替换掉原来的aof文件,就完成了.

下面是流程图

我们从上面的流程图思考一个问题.就是父进程fork完毕之后,就已经让子进程写新的aof文件了,并且随着时间的推移,很快就写完了新的文件,让新文件替换旧文件,父进程还要继续写这个即将消亡的旧文件吗?

这里要清醒,不能不写,如果崩了,依照旧的aof文件还可以恢复数据.

以上就是redis持久化机制.

http://www.xdnf.cn/news/6228.html

相关文章:

  • 软件测试--入门
  • unity 鼠标更换指定图标
  • MongoDB 的核心概念(文档、集合、数据库、BSON)是什么?
  • 如何选择合适的企业级商城系统前端状态管理方案?
  • 【NLP 困惑度解析和python实现】
  • 并查集原理及实现:路径压缩,按秩合并
  • 【AAAI 2025】 Local Conditional Controlling for Text-to-Image Diffusion Models
  • 《P2345 [USACO04OPEN] MooFest G》
  • 深度学习Dropout实现
  • Linux 内核 IPv4 协议栈中的协议注册机制解析
  • 在 Angular 中, `if...else if...else`
  • 默认打开程序配置错误怎么办?Windows 默认打开文件类型设置
  • 一致性哈希
  • 数据结构:ArrayList简单实现与常见操作实例详解
  • C#高级编程:加密解密
  • 自动化测试避坑指南:5大常见问题与应对策略
  • Java面向对象三大特性深度解析
  • Pass-the-Hash攻击原理与防御实战指南
  • 进程间通信(Windows事件)
  • 【教程】Docker方式本地部署Overleaf
  • 内存划分包括 Flash存储器、SRAM 和 外设寄存器
  • nginx 出现大量connect reset by peer
  • 第二章日志分析-apache日志分析
  • 秒删node_modules[无废话版]
  • 数据结构(八)——查找
  • 达梦数据库 【-6111: 字符串转换出错】问题处理
  • HVV蓝队实战面试题
  • 全新开发-iVX图形化编程VS完整IDE
  • 有关多线程
  • vue中,created和mounted两个钩子之间调用时差值受什么影响