一文读懂Redis的数据持久化策略:RDB和AOF
nanshan 2024-10-20 07:34 22 浏览 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数据库中,我们知道binlog日志记录了我们对数据库的所有操作,所以...
- 数据库告警不可用,增删改受阻(数据库限制删除)
-
前言:昨晚,突然出现服务不可用告警,查看日志上线报文入库到数据库很慢并受阻,出现数据不同步问题。排查问题查看发现服务都是在执行update、insert这些DML命令的时候,报的数据库执行超时。经过一...
- Binlog实现MySQL复制,5个关键步骤,务必掌握!
-
复制是MySQL最重要的功能之一,MySQL集群的高可用、负载均衡和读写分离都是基于复制来实现的。Binlog就是实现主从复制的关键,主数据库将修改操作记录到Binlog中,从数据库通过解...
- MySQL数据实时增量同步到Elasticsearch
-
Mysql到Elasticsearch的数据同步,一般用ETL来实现,但性能并不理想,目前大部分的ETL是定时查询Mysql数据库有没有新增数据或者修改数据,如果数据量小影响不大,但如果几百万上千万的...
- MySQL 数据库恢复:如何执行时间点恢复(PITR)以挽救受损数据?
-
天津鸿萌科贸发展有限公司从事数据安全服务二十余年,致力于为各领域客户提供专业的数据恢复、数据备份、数据取证、数据迁移、网络安全、数据清除等解决方案,并针对企业面临的数据安全风险,提供专业的相关数据安全...
- 阿里面试:MySQL Binlog有哪些格式?底层原理?优缺点?
-
binlog的格式也有三种:STATEMENT、ROW、MIXED,下面我详解binlog三种模式@mikechenStatement模式Statement模式:是基于SQL语句的复制(statem...
- 快速带你读懂MySQL的binlog写入机制
-
深入讲解MySQL中的重要日志binlog的写入机制以及影响IO性能的关键配置,并且介绍了如何利用binlog去恢复数据,保证MySQL的可靠性。Q:binlog写入时机binlog的写入逻辑并...
- MySQL 误删除数据恢复全攻略:基于 Binlog 的实战指南
-
在MySQL的世界里,二进制日志(Binlog)就是我们的"时光机"。它默默记录着数据库的每一个重要变更,就像一位忠实的史官,为我们在数据灾难中提供最后的救命稻草。本文将带您深入掌握如...
- 一文了解MySQL Binlog(一文了解肝脏有益和有害的食物)
-
MySQL的Binlog日志是一种二进制格式的日志,Binlog记录所有的DDL和DML语句(除了数据查询语句SELECT、SHOW等),以Event的形式记录,同时记录语句执行时...
- 数据丢失?别慌!MySQL备份恢复攻略
-
想象一下,某个晴朗的午后,你正享受着咖啡,突然接到紧急电话:你的网站或APP彻底挂了!系统崩溃,界面全白。虽然心头一紧,但你或许还能安慰自己:系统崩溃只是暂停服务,数据还在,修复修复就好了。然而,如果...
- Mysql中的bin log、redo log、undo log的区别
-
最近在整理面试题,在看mvcc的时候看到了undolog,今天索性把这三个log都记录一遍。MySQL的逻辑架构说之前先说一下MySQL的基本架构,MySQL主要分为两层:Server层和存储引...
- binlog日志定时清理(binlog清理规则)
-
binlog日志binlog是MySQL数据库的一种日志文件,用于记录所有对数据的修改操作。binlog全称为binarylog,它以二进制格式记录MySQL服务器上所有的修改操作,包括对哪个数据库...
- 茶水间炸锅了!菜鸟误删用户表,运维老张的MySQL救命三招!
-
(公司茶水间,运维老张、开发小王和新人小李围着咖啡机)小李:(紧张兮兮)张哥!我...我好像把测试库的用户表删了!下午演示咋办啊?老张:(淡定喝咖啡)慌啥?昨晚的备份是吃干饭的?走,教你恢复!一、基础...
- 解决运维痛点,提高运维安全性-雷池 SafeLine WAF新功能身份认证
-
雷池介绍使用雷池SafeLineWAF已经两年多了,在1.5.x版本时就已经开始测试使用,并在推出LTS版本后转入LTS分支。近期雷池SafeLineWAF重点更新了身份认证功能,并提供了SS...
- 【Docker 新手入门指南】第十五章:常见故障排除
-
一、前期准备:收集关键信息在排查问题前,建议先获取以下系统数据,便于精准定位故障:1.系统基础信息#查看Docker版本(确认是否为最新稳定版)dockerversion#查看...
你 发表评论:
欢迎- 一周热门
-
-
极空间如何无损移机,新Z4 Pro又有哪些升级?极空间Z4 Pro深度体验
-
UOS服务器操作系统防火墙设置(uos20关闭防火墙)
-
如何修复用户配置文件服务在 WINDOWS 上登录失败的问题
-
手机如何设置与显示准确时间的详细指南
-
如何在安装前及安装后修改黑群晖的Mac地址和Sn系列号
-
日本海上自卫队的军衔制度(日本海上自卫队的军衔制度是什么)
-
爱折腾的特斯拉车主必看!手把手教你TESLAMATE的备份和恢复
-
10个免费文件中转服务站,分享文件简单方便,你知道几个?
-
NAS:DS video/DS file/DS photo等群晖移动端APP远程访问的教程
-
FANUC 0i-TF数据备份方法(fanuc系统备份教程)
-
- 最近发表
- 标签列表
-
- 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)