IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 对于redis持久化的一些思考 -> 正文阅读

[大数据]对于redis持久化的一些思考

对于redis持久化的一些思考

前言

去了一趟上海,感概不愧是大城市,连快递都用上缓存了。

在这里插入图片描述

AOF

redis 作为内存数据库,利用内存读写速度快来提高系统的性能。那么暂存在内存中的数据,必然存在丢失的风险,redis 给出了两种解决方案。AOF(Append Only File) 持久化功能的工作流程如下

在这里插入图片描述
Q:为什么要先执行写命令,再记录操作日志?
我的理解是,如果先记录操作日志,那就需要做 redis 指令的语法校验,会耗费时间和性能。如果不做校验,那么在 redis 从 aof 文件恢复时,会重复执行语法错误的指令,这是没有必要的无效操作。
Q:AOF文件内容是什么样的?
以set city xiamen 为例

*3
$3
set
$4
city
$6
xiamen

*代表是 aof 格式的文件,*3代表这个指令有三个部分,$后跟的就是指令的长度了。

从上图就可以发现 redis 可能存在丢数据的节点了。比如主进程刚执行完写命令,还没记录日志就宕机了。也能发现 redis 的性能瓶颈会发生在硬盘上,假如硬盘的 I/O 负荷较大,那么记录操作日志的同步操作就会阻塞到下一个 redis 指令的执行。

当然记录操作日志也没那么简单,具体流程如下
在这里插入图片描述
redis 提供的三种回写策略针对的是写入内核缓冲区后,何时写入硬盘。三种策略位 Always、Everysec、No,无非就是对于性能和数据丢失率的取舍,这里不细说。深究一下源码来分析这三种策略到底有什么不同。其实区别就在于这三种策略调用**fsync()**的时机。

Always:每次写入 aof文件数据后,就执行 fsync() 函数
Everysec:会创建一个异步任务来执行 fsync() 函数
No:永不执行 fsync() 函数,交给操作系统来决定何时调用

AOF重写

当 redis 重启时,如果从 aof 文件恢复的话,就需要把文件中的所有指令都执行一次,那么如果文件太大的话必然会影响恢复的速度,并且可能会存在无效的操作指令,比如同个 key 操作了多次,那么只需要执行最后一次即可。所以 AOF 的重写必然会去合并相同 key 的操作指令。那么当主进程 fork 生成 bgrewriteaof 子进程去执行 AOF 重写时会发生什么呢?
在这里插入图片描述
主进程在通过 fork 系统调用生成 bgrewriteaof 子进程时,操作系统会把主进程的页表复制一份给子进程,这个页表记录着虚拟地址和物理地址映射关系,而不会复制物理内存,也就是说,两者的虚拟空间不同,但其对应的物理空间是同一个。

Q:如果此时对父进程内存中的数据进行修改,会发生什么?
创建 bgrewriteaof 子进程之后,redis 会设置一个 AOF 重写缓冲区,在重写期间,父进程发生写操作时,会同时向 AOF 缓冲区和 AOF 重写缓冲区进行输出。当 bgrewriteaof 子进程扫描完所有数据,逐一把内存数据的键值对转换成一条命令,再将命令记录到重写日志后,会将 AOF 重写缓冲区的数据也写入到 AOF 重写文件中,最后在将重写后的 aof 文件覆盖原来的 aof 文件。

RDB

redis 提供了两种指令来生成 rdb 文件。分别是 save 和 bgsave,这两者的区别在于是否在主线程进行快照的记录。因为 RDB 是做全量的快照,如果用 bgsave 进行 RDB 快照的话,在创建子进程的时候,会因为复制太大的页表而导致 redis 阻塞在fork() 函数,主线程无法继续执行,相当于停顿了。所以当 rdb 文件太大时,建议使用 save 的方式。

Q:执行快照时,数据能被修改吗?
在这里插入图片描述
能。当内存数据发生修改时会触发写时复制(Copy-On-Write),所以子进程读到的还是修改前的内存数据。这样也会引发一些问题。比如,修改的数据在父子进程中值不同,这种情况就只能等待下次 bgsave 时才能将最新的数据记录到 rdb 文件中,当然如果在触发下次 RDB 之前就宕机了,那么最新的修改值就丢失了。如果生产环境采用 RDB 的持久化方式的话,需要注意一点,如果所有的共享内存都被修改,则此时的内存占用是原先的两倍。所以,针对写操作多的场景,我们要留意下快照过程中内存的变化,防止内存被占满了。

总结

AOF 和 RDB 都是在平衡性能和数据丢失率的问题,两者都有优点和缺点,所以就有了 RDB 和 AOF 的合体混合持久化。这个方法是在 Redis4. 0提出的。当开启了混合持久化时,在 AOF 重写日志时,fork 出来的重写子进程会先将与主线程共享的内存数据以 RDB 方式写入到 aof 文件,然后主线程处理的操作命令会被记录在重写缓冲区里,重写缓冲区里的增量命令会以 AOF 方式写入到 aof 文件,写入完成后通知主进程将新的含有 RDB 格式和 AOF 格式的 aof 文件替换旧的的 aof 文件。也就是说,使用了混合持久化,aof 文件的前半部分是 RDB 格式的全量数据,后半部分是 AOF 格式的增量数据。

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-11-05 00:34:29  更:2022-11-05 00:37:09 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年4日历 -2025/4/22 8:47:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码