一文读懂Redis的数据持久化策略:RDB和AOF
nanshan 2024-10-20 07:34 21 浏览 0 评论
1. 背景
Redis的数据全部存储在内存,如果机器突然宕机,那么数据就会全部丢失,因此必须有一种机制来保证 Redis 的数据不会因为故障而丢失,这种机制就是 Redis 的持久化机制。Redis为我们提供了两种持久化方案,一种是基于快照RDB(Redis DataBase),另外一种是基于 AOF (Append Only File)日志 。Redis也可以同时支持 AOF 持久化和 RDB 持久化。在这种情况下,当 AOF 重启时,会优先使用 AOF 文件去恢复原始数据。因为 AOF 中保存的数据通常比 RDB 中保存的数据更加完整。
2. RDB 详解
RDB 是 Redis 默认的持久化方案。RDB通过快照的形式将数据保存到磁盘中。所谓快照,可以理解为在某一时间点将数据集的一个快照。在指定的时间间隔内,执行指定次数的写操作,则会将内存中的数据写入到磁盘中。即在指定目录下生成一个dump.rdb文件。Redis 重启会通过加载dump.rdb文件恢复数据。
2.1. RDB配置参数
打开 redis.conf 文件,RDB的规则配置
save <seconds> <changes>
# save ""
# 在 900 秒(15分钟)之后,如果至少有 1 个 key 发生变化,Redis 就会自动触发 BGSAVE 命令创建快照
save 900 1
# 在 300 秒(5分钟)之后,如果至少有 10 个 key 发生变化,Redis 就会自动触发 BGSAVE 命令创建快照
save 300 10
# 在 60 秒(1分钟)之后,如果至少有 10000 个 key 发生变化,Redis 就会自动触发 BGSAVE命令创建快照
save 60 10000
1. 参数说明:
save <指定时间间隔> <执行指定次数更新操作>
满足条件就将内存中的数据同步到硬盘中。默认配置是 900秒内有1个更改,300秒内有10个更改以及60秒内有10000个更改,则将内存中的数据快照写入磁盘。
若想关闭RDB,可以把 save "" 的注释打开,其他关闭。
2 自定义本地数据库文件,默认认名词 dump.rdb
dbfilename dump.rdb
3 指定生成文件的路径。一般也用默认配置
dir ./
4 是否开启数据压缩
rdbcompression yes
参数说明:
配置存储至本地数据库时是否压缩数据,默认为yes。Redis采用LZF压缩方式,会占用部分CPU的时间。若关闭该选项,但会导致数据库文件变的巨大,建议开启。
2.2 生成RDB
生成RDB的步骤:
1 配置规则执行指定次数的写操作
2 执行save(同步阻塞) 或者是bgsave (异步)命令
3 执行flushall 命令,清空数据库所有数据。
4 执行shutdown 命令,保证服务器正常关闭且不丢失任何数据。
2.3 通过RDB恢复数据
将生成的本地dump.rdb 文件拷贝到redis的安装目录的bin目录下,重启redis服务会自动加载RDB。在实际开发中,一般会选择网络存储设备,比如对象存储,NAS或者云盘。
2.4 RDB 的优缺点
优点:
1 适合大规模的数据恢复,一般建议Redis单实例小于10GB。
2 如果追求系统的高可用和数据的高要求,RDB并不是很好的选择。
缺点:
1 数据的完整性和一致性不高,因为RDB可能在最后一次备份时宕机了。
2 备份时占用内存,因为Redis 在备份时会独立创建一个子进程,将数据写入到一个临时文件(此时内存中的数据是原来的两倍哦),最后再将临时文件替换之前的备份文件,不过这个问题在最新版的Redis已经优化为异步任务。
当我们生成RDB的过程中有新的写入,那么如何保障数据的一致性呢?这就是下午要展开讲的COW机制。
2.5 COW
我们先看两个函数:fork()和exec()。需要说明的是exec()并不是一个特定的函数, 它是一组函数的统称, 它包括了execl()、execlp()、execv()、execle()、execve()、execvp()。
fork是类Unix操作系统上创建进程的主要方法。fork用于创建子进程(等同于当前进程的副本)。Linux下init进程是所有进程的父进程。exec函数的作用就是:装载一个新的程序(可执行映像)覆盖当前进程内存空间中的映像,从而执行不同的任务。
由于进程之前的内存空间是隔离的,如果fork后直接copy父进程数据到子进程,那么后写入的数据就会丢失。很多时候我们直接复制给子进程的数据是无效的,于是就需要Copy On Write(COW)技术了,它的原理如下:
- fork()执行后,kernel把父进程中所有的内存页的权限都设为read-only,然后子进程的地址空间指向父进程。
- 当某个进程更新内存时,CPU硬件检测到内存页是read-only的,于是触发页异常中断(page-fault),陷入kernel的一个中断程序。
- 在中断程序中,kernel就会把触发的异常的页复制一份,于是父子进程各自持有独立的一份。
Copy On Write的好处:
- COW技术可减少分配和复制大量资源时带来的瞬间延时。
- COW技术可减少不必要的资源分配。比如fork进程时,并不是所有的页面都需要复制,父进程的代码段和只读数据段都不被允许修改,所以无需复制。
Copy On Write的缺点:
如果在fork()之后,父子进程都还需要继续进行写操作,那么会产生大量的分页错误(页异常中断page-fault),这样就得不偿失。
3. AOF 详解
AOF :Redis 默认不开启。它的目的是为了解决生成RDB后数据不能实时一致的问题,所以它采用日志的形式来记录每个写操作,并追加到文件中。Redis 重启的会根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。
AOF持久化功能的实现可以分为命令追加(append)、文件写入、 文件同步(sync)三个步骤。下面详细说明其中的步骤:
a.命令追加:服务器在执行完一个写命令之后,会以协议格式将被执行的写命令追加到服务器状态的aof_buf缓冲区的末尾。
举个栗子,如果执行以下指令:
redis> SET
VALUE
OK
1212
那么会将以下协议内容追加到 aof_buf缓冲区的末尾:
*3\r\n$3\r\nSET\r\n$3\r\nAGE\r\n$5\r\
\r\n
11
b.文件写入:通过 write() 系统调用,将 aof_buf 缓冲区的数据写入到 AOF 文件,此时数据并没有写入到硬盘,而是拷贝到了内核缓冲区 page cache,等待内核将数据写入硬盘;具体内核缓冲区的数据什么时候写入到硬盘,由内核决定。
c.文件同步
如果由内核决定将数据写入硬盘的话,如果服务器宕机,那么就会有数据丢失的风险。为了解决这个问题,系统提供了fsync和fdatasync两个同步函数和三种写回策略,它们可以强制让操作系统立即将缓冲区中的数据写入到硬盘里面,从而确保写入数据的安全性。
在 redis.conf 配置文件中的 appendfsync 配置项可以有以下 3 种参数可填:
- always:服务器在每次写操作后都将 aof_buf缓冲区中的所有内容写入到AOF文件,然后立即执行fsync()函数同步AOF文件到磁盘,所以always的效率是最低,但也是最安全的。可靠性高,性能低。
- everysec:服务器在每次写操作后都要 将aof_buf缓冲区中的所有内容写入到AOF文件,并且每隔一秒就要在子线程中对AOF文件进行一次同步,创建一个异步任务执行fsync()函数。可靠性和性能都适中。
- no:将缓冲区的内容写入AOF文件后,何时进行同步由操作系统控制,不执行fsync()函数。性能好,可靠性低,宕机可能会丢失较多数据。
3.1 配置AOF
打开 redis.conf 文件,找到 APPEND ONLY MODE 对应内容
1 yes开启,默认不开启
appendonly yes
2 自定义本地数据库文件名,默认值为 appendonly.aof
appendfilename "appendonly.aof"
3 自定义更新日志条件
# appendfsync always
appendfsync everysec
# appendfsync no
参数说明:
always:同步持久化,每次发生数据变化会立刻写入到磁盘中。性能较差当数据完整性比较好(慢,安全)
everysec:默认推荐,每秒异步记录一次(默认值)
no:不同步
4 配置重写触发机制
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
参数说明:当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发。一般都设置为3G,默认的64M太小。
3.2 生成AOF
根据配置文件触发,可以是每次执行触发,可以是每秒触发,可以不同步。
3.3 根据AOF恢复数据
正常情况下,将appendonly.aof 文件拷贝到redis的安装目录的bin目录下,重启redis服务即可。在实际开发中,文件也会存储在网络设备上,保障数据高可靠。如果因为某些原因导致appendonly.aof 文件格式异常,从而导致数据还原失败,可以通过命令redis-check-aof --fix appendonly.aof
进行修复 。
3.4 AOF的重写压缩机制
AOF的工作原理是将写操作追加到文件中,文件的冗余内容会越来越多。所以Redis 新增了重写机制。
AOF重写可以生成一个新的AOF文件,新文件和老文件所保存的信息一样,但体积更小,还可以做命令的合并,进而节省了 Redis 的存储空间。比如对一个list里面的元素写了又删,我就可以合并多条为一条新命令 → LPUSH v2 v3…。
AOF重写的目的
解决AOF文件越来越大产生性能问题:
- Linux文件系统对单文件大小有限制,无法保存过大的文件。
- 如果文件太大,之后再往里面追加命令记录的话,效率也会变低。
- 如果发生宕机,AOF中记录的命令要一个个被重新执行,用于故障恢复。如果日志文件太大,整个恢复过程就会非常缓慢,影响到 Redis 的正常使用。
AOF重写流程
AOF重写不会阻塞主线程,其重写过程是由后台子进程 bgrewriteaof 来完成的,从而避免了性能下降。具体流程如下:
- 把主线程的内存拷贝一份给fork出来的 bgrewriteaof 子进程,这里面包含了Redis中最新的数据。
- 子进程将其中的数据进行重写。
- 主线程维护一个AOF缓冲区(实际上无论重不重写都有这个缓冲区,因为AOF日志写入是 → AOF缓冲区 → AOF文件),如果此时有写操作,则会写入到AOF缓冲区以及AOF日志中,保证数据完整。
- 主线程在重写时维护一个AOF重写缓冲区,将重写过程中的写操作记入其中,保证重写后的AOF日志也能记录在重写过程中产生的新数据。
- 用新AOF替换老AOF日志。
AOF重写为什么不采用覆盖写:父子进程写同一个文件必然会产生竞争,如果控制竞争就意味着会影响父进程的性能。如果AOF重写失败,那么原本的AOF文件相当于被污染了,就直接废了。而采用覆盖的方式则不会有这种负面影响。
3.5 AOF 的优缺点
优点:数据的完整性和一致性更高
缺点:因为AOF记录的内容多,文件会越来越大,数据恢复也会越来越慢。
4.总结
- Redis 默认开启RDB持久化方式,在指定的时间间隔内,执行指定次数的写操作,则将内存中的数据写入到磁盘中。RDB 持久化适合大规模的数据恢复但它的数据一致性和完整性较差。采用COW可以保障数据一致,单高频写入会引发缺页中断。
- Redis 需要手动开启AOF持久化方式,默认是每秒将写操作日志追加到AOF文件中。AOF 的数据完整性比RDB高,但记录内容多了,会影响数据恢复的效率。Redis 针对 AOF文件大的问题,提供重写的瘦身机制。
- 若只打算用Redis 做缓存,可以关闭持久化。
- 若打算使用Redis 的持久化。建议RDB和AOF都开启。
相关推荐
- 如何为MySQL服务器和客户机启用SSL?
-
用户想要与MySQL服务器建立一条安全连接时,常常依赖VPN隧道或SSH隧道。不过,获得MySQL连接的另一个办法是,启用MySQL服务器上的SSL封装器(SSLwrapper)。这每一种方法各有其...
- Mysql5.7 出现大量 unauthenticated user
-
线上环境mysql5.7突然出现大量unauthenticateduser,进mysql,showprocesslist;解决办法有:在/etc/hosts中添加客户端ip,如192.16...
- MySQL 在 Windows 系统下的安装(mysql安装教程windows)
-
更多技术文章MySQL在Windows系统下的安装1.下载mysql和Framework链接链接:百度网盘请输入提取码提取码:6w3p双击mysql-installer-communit...
- MySql5.7.21.zip绿色版安装(mysql数据库绿色版安装)
-
1、去网上下载满足系统要求的版本(mysql-5.7.21-winx64.zip)2、直接解压3、mysql的初始化(1)以管理员身份运行cmd,在mysql中的bin目录下shift+右键-在...
- MySQL(8.0)中文全文检索 (亲测有效)
-
在一堆文字中找到含有关键字的应用。当然也可以用以下语句实现:SELECT*FROM<表名>WHERE<字段名>like‘%ABC%’但是它的效率太低,是全盘扫描。...
- 新手教程,Linux系统下MySQL的安装
-
看了两三个教程。终于在哔哩哔哩找到一个简单高效的教程,成功安装,up主名叫bili逍遥bili,感兴趣可以去看看。下面这个是我总结的安装方法环境:CentOS764位1.下载安装包,个人觉得在...
- 麒麟服务器操作系统安装 MySQL 8 实战指南
-
原文连接:「链接」Hello,大家好啊,今天给大家带来一篇麒麟服务器操作系统上安装MySQL8的文章,欢迎大家分享点赞,点个在看和关注吧!MySQL作为主流开源数据库之一,被广泛应用于各种业务...
- 用Python玩转MySQL的全攻略,从环境搭建到项目实战全解析
-
这是一篇关于“MySQL数据库入门实战-Python版”的教程,结合了案例实战分析,帮助初学者快速掌握如何使用Python操作MySQL数据库。一、环境准备1.安装Python访问Pytho...
- 安装MySQL(中标麒麟 安装mysql)
-
安装MySQL注意:一定要用root用户操作如下步骤;先卸载MySQL再安装1.安装包准备(1)查看MySQL是否安装rpm-qa|grepmysql(2)如果安装了MySQL,就先卸载rpm-...
- Mysql最全笔记,快速入门,干货满满,爆肝
-
目录一、MySQL的重要性二、MySQL介绍三、软件的服务架构四、MySQL的安装五、SQL语句六、数据库相关(DDL)七、表相关八、DML相关(表中数据)九、DQL(重点)十、数据完...
- MAC电脑安装MySQL操作步骤(mac安装mysqldb)
-
1、在官网下载MySQL:https://dev.mysql.com/downloads/mysql/根据自己的macOS版本,选择适配的MySQL版本根据自己需求选择相应的安装包,我这里选择macO...
- mysql主从(mysql主从切换)
-
1、本章面试题什么是mysql主从,主从有什么好处什么是读写分离,有什么好处,使用mycat如何实现2、知识点2.1、课程回顾dubboORM->MVC->RPC->SOApro...
- 【linux学习】以MySQL为例,带你了解数据库
-
做运维的小伙伴在日常工作中难免需要接触到数据库,不管是MySQL,mariadb,达梦还是瀚高等其实命令都差不多,下面我就以MySQL为例带大家一起来了解下数据库。有兴趣的小伙伴不妨评论区一起交流下...
- 玩玩WordPress - 环境简介(0)(玩玩网络科技有限公司)
-
简介提到开源博客系统,一般都会直接想到WordPress!WordPress是使用PHP开发的,数据库使用的是MySQL,一般会在Linux上运行,Nginx作为前端。这时候就需要有一套LNMP(Li...
- 服务器常用端口都有哪些?(服务器端使用的端口号范围)
-
下面为大家介绍一下,服务器常用的一些默认端口,以及他们的作用: 21:FTP服务所开放的端口,用于上传、下载文件。 22:SSH端口,用于通过命令行模式远程连接Linux服务器或vps。 23:...
你 发表评论:
欢迎- 一周热门
-
-
极空间如何无损移机,新Z4 Pro又有哪些升级?极空间Z4 Pro深度体验
-
如何在安装前及安装后修改黑群晖的Mac地址和Sn系列号
-
UOS服务器操作系统防火墙设置(uos20关闭防火墙)
-
日本海上自卫队的军衔制度(日本海上自卫队的军衔制度是什么)
-
爱折腾的特斯拉车主必看!手把手教你TESLAMATE的备份和恢复
-
如何修复用户配置文件服务在 WINDOWS 上登录失败的问题
-
10个免费文件中转服务站,分享文件简单方便,你知道几个?
-
手机如何设置与显示准确时间的详细指南
-
【系统配置】信创终端挂载NAS共享全攻略:一步到位!
-
[常用工具] OpenCV_contrib库在windows下编译使用指南
-
- 最近发表
- 标签列表
-
- linux 查询端口号 (58)
- docker映射容器目录到宿主机 (66)
- 杀端口 (60)
- yum更换阿里源 (62)
- internet explorer 增强的安全配置已启用 (65)
- linux自动挂载 (56)
- 禁用selinux (55)
- sysv-rc-conf (69)
- ubuntu防火墙状态查看 (64)
- windows server 2022激活密钥 (56)
- 无法与服务器建立安全连接是什么意思 (74)
- 443/80端口被占用怎么解决 (56)
- ping无法访问目标主机怎么解决 (58)
- fdatasync (59)
- 405 not allowed (56)
- 免备案虚拟主机zxhost (55)
- linux根据pid查看进程 (60)
- dhcp工具 (62)
- mysql 1045 (57)
- 宝塔远程工具 (56)
- ssh服务器拒绝了密码 请再试一次 (56)
- ubuntu卸载docker (56)
- linux查看nginx状态 (63)
- tomcat 乱码 (76)
- 2008r2激活序列号 (65)