为什么要持久化
Redis是内存数据库,宕机后数据会消失,Redis重启后快速恢复数据,所以Redis为我们提供了持久化机制,分别是RDB(Redis DataBase)和AOF(Append Only File)。
Redis的两种持久化方式:RDB和AOF
Redis持久化不保证数据的完整性,有可能会丢数据。当Redis用作DB时,DB数据要完整,所以一定要有一个完整的数据源(文件、mysql),在系统启动时,从这个完整的数据源中将数据load到Redis中。
AOF:将每一个收到的写命令都通过write函数追加到文件中
RDB(Redis DataBase)
在指定的时间间隔内将内存中的数据集快照写入磁盘, 即 Snapshot 快照,恢复时是将快照文件直接读到内存里。
RDB(Redis DataBase),是redis默认的存储方式,RDB方式是通过快照( snapshotting )完成的。它保存的是某一时刻的数据并不关注过程。RDB保存redis某一时刻的数据的快照
触发快照的方式
- 符合自定义配置的快照规则;
- 执行save或者bgsave命令;
- 执行flushall命令;
- 执行主从复制操作 (第一次)。
RDB持久化触发策略
RDB 持久化提供了两种触发策略:一种是手动触发,另一种是自动触发。
自动触发策略,是指 Redis 在指定的时间内,数据发生了多少次变化时,会自动执行BGSAVE命令。自动触发的条件包含在了 Redis 的配置文件中
上图所示, save m n
的含义是在时间 m 秒内,如果 Redis 数据至少发生了 n 次变化,那么就自动执行BGSAVE
命令。配置策略说明如下:
save 900 1
表示在 900 秒内,至少更新了 1 条数据,Redis 自动触发 BGSAVE 命令,将数据保存到硬盘。
save 300 10
表示在 300 秒内,至少更新了 10 条数据,Redis 自动触 BGSAVE 命令,将数据保存到硬盘。
save 60 10000
表示 60 秒内,至少更新了 10000 条数据,Redis 自动触发 BGSAVE 命令,将数据保存到硬盘。
只要上述三个条件任意满足一个,服务器就会自动执行BGSAVE
命令。当然也可以根据实际情况自己调整触发策略。
注意:每次创建 RDB 文件之后,Redis
服务器为实现自动持久化而设置的时间计数和次数计数就会被清零,并重新开始计数,因此多个策略的效果不会叠加。
此处redis自动触发策略参考文章Redis RDB持久化详解(原理+配置策略)
配置参数定期执行
在redis.conf
中配置:save 多少秒内数据变了多少,可以配置多个条件,漏斗设计满足其中一个条件就会触发生成快照, 提搞性能
Redis 会单独创建一个子进程(fork)来进行持久化。
先将数据写入到一个临时文件中,待持久化过程完成后,再将这个临时文件内容覆盖到 dump.rdb。
整个过程中,主进程是不进行任何 IO 操作的,这就确保了极高的性能。如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那 RDB 方式要比 AOF 方式更加的高效。
RDB 的缺点是最后一次持久化后的数据可能丢失。
注意
: redis中的数据有个很重要的注意事项, 就是必须要考虑, 如果redis里面的数据完全丢失了, 程序的行为还能正常与否, 也就是确保redis数据丢失后还能再恢复过来, 此时我们才可以考虑将数据存储到redis中。
Fork
- 作用是复制一个与当前进程一样的进程。新进程的所有数据(变量、环境变量、程序计数器等) 数值都和原进程一致,但是是一个全新的进程,并作为原进程的子进程
- 在 Linux 程序中,fork() 会产生一个和父进程完全相同的子进程,但子进程在此后多会 exec 系统调用,出于效率考虑,Linux 中引入了 写时复制技术
- 一般情况父进程和子进程会共用同一段物理内存,只有进程空间的各段的内容要发生变化时,才会将父进程的内容复制一份给子进程
配置
dump 文件名字
在 redis.conf 中配置文件名称,默认为 dump.rdb。
dump 保存位置
rdb 文件的保存路径可以修改。默认为 Redis
/var/lib/redis/
stop-writes-on-bgsave-error
即当 redis 无法写入磁盘,关闭 redis 的写入操作。
rdbcompression
持久化的文件是否进行压缩存储。
rdbchecksum
完整性的检查,即数据是否完整性、准确性。
优点
- 适合大规模的数据恢复;
- 对数据完整性和一致性要求不高更适合使用;
- 性能好:RDB方式在数据持久化时,将内存中的数据以快照的形式保存到磁盘,写操作不会对磁盘进行频繁的写入,因此性能较高。
- 数据文件紧凑,节省磁盘空间:RDB文件是二进制文件,非常紧凑,适用于备份和迁移数据。
- 恢复速度快。
缺点
- Fork 的时候,内存中的数据被克隆了一份,极端情况下大致 2 倍的膨胀性需要考虑;
- 虽然 Redis 在 fork 时使用了写时拷贝技术,但是如果数据庞大时还是比较消耗性能;
- 在备份周期在一定间隔时间做一次备份,所以如果 Redis 意外 down 掉的话,就会丢失最后一次快照后的所有修改。
- 不适用于高可用性:由于数据不是实时保存到磁盘,所以不适用于要求高可用性和数据实时性的场景。
- 父进程在fork子进程的时候如果主进程比较大会阻塞;
AOF(Append Only File)
AOF(append only file)是Redis的另一种持久化方式。以日志的形式来记录每个写操作(增量保存),将 Redis 执行过的所有写指令记录下来(读操作不记录), 只许追加文件但不可以改写文件,Redis 启动之初会读取该文件重新构建数据,换言之,如果 Redis 重启就会根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。
AOF会记录过程,RDB只管结果
执行流程
- 客户端的请求写命令会被 append 追加到 AOF 缓冲区内;
- AOF 缓冲区根据 AOF 持久化策略
[always,everysec,no]
将操作 sync 同步到磁盘的 AOF 文件中; - AOF 文件大小超过重写策略或手动重写时,会对 AOF 文件 Rewrite 重写,压缩 AOF 文件容量;
- Redis 服务重启时,会重新 load 加载 AOF 文件中的写操作达到数据恢复的目的。
AOF 和 RDB 同时开启时,系统默认读取 AOF 的数据(数据丢失可能性非常之低)
AOF 保存模式:
- AOF_FSYNC_NO :不保存。
在这种模式下, 每次调用 flushAppendOnlyFile 函数, WRITE 都会被执行, 但 SAVE 会被略过。当出现Redis 被关闭、AOF 功能被关闭 、 系统的写缓存被刷新(可能是缓存已经被写满,或者定期保存操作被执行)中任意一种情况都会触发save执行,并且会Redis 主进程阻塞。 - AOF_FSYNC_EVERYSEC :每一秒钟保存一次。(默认)
在这种模式中, SAVE 原则上每隔一秒钟就会执行一次, 因为 SAVE 操作是由后台子线程(fork)调用的, 所以它不会引起服务器主进程阻塞。 - AOF_FSYNC_ALWAYS :每执行一个命令保存一次。(不推荐)
在这种模式下,每次执行完一个命令之后, WRITE 和 SAVE 都会被执行。
配置
AOF 默认不开启
文件名字
AOF 同步频率设置
appendfsync always
始终同步,每次 Redis 的写入都会立刻记入日志;
性能较差但数据完整性比较好。
appendfsync everysec
每秒同步,每秒记入日志一次,如果宕机,本秒的数据可能丢失。
appendfsync no
Redis 不主动进行同步,把同步时机交给操作系统。
Rewrite 压缩
当 AOF 文件的大小超过所设定的阈值时,Redis 就会启动 AOF 文件的内容压缩,只保留可以恢复数据的最小指令集。可以使用命令 bgrewriteaof。
优点
- 备份机制更稳健,丢失数据概率更低:AOF方式是将每个写操作追加到日志文件中,因此可以保证数据不会丢失。
- 可读性好:AOF日志是文本文件,可读性好,便于人工查看和维护。可以通过操作 AOF 稳健处理误操作。
缺点
- 比起 RDB 占用更多的磁盘空间(存疑); 因为rdb中临时文件的存在,所以两者谁占用更多磁盘空间不好说
- 日志文件较大:AOF日志文件相对较大,因为它记录了每个写操作。
- 恢复备份速度要慢;
- 性能相对较低:由于每个写操作都要追加到日志文件中,可能会导致写入性能相对较低
- 存在个别 Bug,造成不能恢复。 为什么aof不能独立使用的原因
选择:怎么使用这2种持久化
RDB和AOF的区别:
- 持久化机制:RDB是定期快照方式,AOF是追加日志方式。
- 数据安全性:AOF方式更安全,可以保证数据不丢失,而RDB可能会丢失数据。
- 可读性:AOF日志文件可读性好,RDB是二进制文件。
- 性能:RDB性能较高,但可能会导致数据丢失;AOF性能较低,但数据更安全。
在实际工作中如何选择持久化方式取决于项目的具体需求和场景:
- 如果项目对数据的实时性要求不高,可以选择RDB方式,因为它性能较高,适用于数据备份和迁移等场景。
- 如果项目对数据的安全性要求很高,不允许丢失任何数据,可以选择AOF方式,因为它可以保证数据不丢失。
- 对于一些关键业务,可以同时使用RDB和AOF方式,这样可以兼顾性能和数据安全性,但需要占用更多的磁盘空间。
- 在高可用性场景中,可以使用AOF方式,配合Redis的主从复制,以保证数据不丢失并提高可用性。
官方推荐两个都启用。
如果对数据不敏感,可以选单独用 RDB。
不建议单独用 AOF,因为可能会出现 Bug。
如果只是做纯内存缓存,可以都不用。
redis 支持同时开启开启两种持久化方式,我们可以综合使用 AOF 和 RDB 两种持久化机制,用AOF 来保证数据不丢失,作为数据恢复的第一选择; 用 RDB 来做不同程度的冷备,在 AOF 文件都丢失或损坏不可用的时候,还可以使用 RDB 来进行快速的数据恢复。