HelloCoder HelloCoder
首页
《Java小白求职之路》
《小白学Java》
计算机毕设
  • 一些免费计算机资源
  • 脚手架工具
  • 《从0到1学习Java多线程》
  • 《从0到1搭建服务器》
  • 《可观测和监控》
随笔
关于作者
首页
《Java小白求职之路》
《小白学Java》
计算机毕设
  • 一些免费计算机资源
  • 脚手架工具
  • 《从0到1学习Java多线程》
  • 《从0到1搭建服务器》
  • 《可观测和监控》
随笔
关于作者
  • 《LearnJavaToFindAJob》

    • 导读

    • 【初级】6~12k档

    • 【中级】12k-26k档

      • JVM进阶

      • Java进阶

      • MySQL

      • 中间件

        • Redis

          • Redis为什么删除数据后,内存占用依然很高?
          • Redis为什么要使用单线程,新版本为什么引入多线程?
          • Redis为什么要把字符串设计成SDS?
          • Redis主从、哨兵、集群的区别
          • Redis主从同步的原理
          • Redis之缓存击穿、穿透、雪崩
          • Redis分布式事务锁的原理
          • Redis的使用规范有哪些?
          • Redis的删除策略和内存淘汰机制
          • Redis的持久化机制,RDB和AOF
          • Redis的监控指标有哪些?
          • 一致性hash算法
        • Docker面试题
        • Dubbo面试题
        • Netty面试题
        • Nginx面试题
        • Tomcat面试题
        • Zookeeper面试题
        • elasticsearch面试题
        • k8s面试题
        • 消息队列面试题
      • 算法

      • 高阶

    • 【高级】26k+档

    • 大厂面试题

    • 求职建议

    • 面经

  • LearnJavaToFindAJob
  • 【中级】12k-26k档
  • 中间件
  • Redis
#Redis #RDB #AOF #持久化机制
码农阿雨
2022-06-02
目录

Redis的持久化机制,RDB和AOF

Redis是基于内存操作,很快,既然Redis在内存工作,但是数据如何保存呢?

在Redis重启的时候,如何把数据恢复,保持一致性?这就涉及Redis的持久化机制了。

# 1、Redis的持久化机制

Redis的持久化机制有两种:

  • RDB
  • AOF

可以单独使用其中一种或将二者结合使用。

# 2、RDB

RDB持久化是将当前进程中的数据生成快照保存到硬盘(因此也称作快照持久化),保存的文件后缀是.rdb

它是redis默认采用支持持久化的方式。

# 2.1 自动触发

常见配置:

# Redis默认设置, 表示  900秒内产生1条写入命令就触发一次快照,自动触发 bgsave
save 900 1
save 300 10
save 60 10000

# 如果持久化出错,主进程是否停止写入
stop-writes-on-bgsave-error yes

# 是否压缩,如果开启,则消耗更多的CPU,否则消耗更多硬盘
rdbcompression yes

# 使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗
rdbchecksum yes

# 快照文件名称
dbfilename dump.rdb

# 快照文件保存路径
dir ./

①、save m n:表示m秒内数据集存在n次修改时,自动触发bgsave。

其他参数解释见上。

# 2.2 手动触发

手动触发有两种方法:

  • 1)save

    同步操作,会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,直到RDB过程完成为止。

  • 2)bgsave 异步操作,Redis fork 出一个新子进程,原来的 Redis 进程(父进程)继续处理客户端请求,而子进程则负责将数据保存到磁盘,然后退出。

localhost:0>save
"OK"

localhost:0>bgsave
"Background saving started"

localhost:0>lastsave
"1603777804"

很明显bgsave 更适合执行RDB 操作,所以Redis的内部操作,包括自动触发,也是 bgsave。

RDB bgsave 具体过程如下:

​ 1、Redis服务器接收bgsave,主线程需要调用系统的 fork() 函数,构建出一个子进程去操作; ​ 2、子线程创建好RDB文件并退出时,向父进程发送一个通知,告知RDB文件创建完毕; ​ 3、父进程接收子进程创建好的RDB文件,bgsave命令执行结束。

# RDB优缺点:

优点:

  1. 采用子线程创建RDB文件,不会对redis服务器性能造成大的影响;
  2. 快照生成的RDB文件是一种压缩的二进制文件,可以方便的在网络中传输和保存。通过RDB文件,可以方便的将redis数据恢复到某一历史时刻,可以提高数据安全性,避免宕机等意外对数据的影响。

缺点:

  1. 在redis文件在时间点A生成,之后产生了新数据,还未到达另一次生成RDB文件的条件,redis服务器崩溃了,那么在时间点A之后的数据会丢失掉,数据一致性不是完美的好,如果可以接受这部分丢失的数据,可以用生成RDB的方式;
  2. 快照持久化方法通过调用fork()方法创建子线程。当redis内存的数据量比较大时,创建子线程和生成RDB文件会占用大量的系统资源和处理时间,对 redis处理正常的客户端请求造成较大影响。

# 3、AOF

AOF是记录Redis的命令,redis对将所有的写命令保存到一个aof文件中,根据这些写命令,实现数据的持久化和数据恢复,它增量备份。

常见配置:

# 是否开启aof,默认是不开启
appendonly no

# 文件名称
appendfilename "appendonly.aof"

# 同步方式,有三种,默认是 everysec
appendfsync everysec

# aof重写期间是否同步
no-appendfsync-on-rewrite no


# 重写触发配置
# (当前AOF文件大小超过上一次重写的AOF文件大小的百分之多少才会重写)
auto-aof-rewrite-percentage 100
# AOF文件重写需要的尺寸,AOF多大时开启重写
auto-aof-rewrite-min-size 64mb

# 文件重写策略
aof-rewrite-incremental-fsync yes

#

参数说明:

①appendfsync的三种模式。Redis 提供了三种 AOF 同步策略,控制写命令同步到 AOF 文件的方式:

  • always:把每个写命令都立即同步到aof文件,性能差,但是很安全
  • everysec:每 1 秒同步一次,Redis官方默认推荐。
  • no:redis不刷盘交给OS来处理,性能最好,但数据安全性最差

因此,在默认的everysec配置下进行AOF恢复,确实存在丢失最多1秒数据的可能性。

②aof-rewrite-incremental-fsync:

每次批量写入磁盘的数据量由aof-rewrite-incremental-fsync参数控制,默认为32M,避免单次刷盘数据过多造成硬盘阻塞

# 3.1 AOF的工作流程

三个步骤:命令追加、文件写入、文件同步。

  1. 所有的写入命令追加到aof_buf缓冲区中。

  2. AOF会根据对应的策略向磁盘做同步操作。刷盘策略由appendfsync参数决定。

  3. 定期对AOF文件进行重写。重写策略由auto-aof-rewrite-percentage、auto-aof-rewrite-min-size两个参数决定。

# 3.2 为什么需要重写?

redis不断的将写命令保存到AOF文件中,导致AOF文件越来越大,当AOF文件体积过大时,数据恢复的时间也是非常长的,所以就需要重写了。

可以重写的情况:

  1. 进程内超时的数据不用再写入到AOF文件中。
  2. 存在删除命令。
  3. 多条写命令可以合并为一个。

比如一个value 自增1w次,那AOF就需要记录1w次的操作,如果重写后,就可以直接记录该key的最终set值了。

# 3.3 AOF重写过程

​ 重写分为:

  • 自动触发

    由auto-aof-rewrite-percentage、auto-aof-rewrite-min-size两个参数决定 且没有进行BGSAVE、BGREWRITEAOF操作 。

    贴一下Redis的原话:

# Automatic rewrite of the append only file.
# Redis is able to automatically rewrite the log file implicitly calling
# BGREWRITEAOF when the AOF log size grows by the specified percentage.
# 
# This is how it works: Redis remembers the size of the AOF file after the
# latest rewrite (if no rewrite has happened since the restart, the size of
# the AOF at startup is used).
#
# This base size is compared to the current size. If the current size is
# bigger than the specified percentage, the rewrite is triggered. Also
# you need to specify a minimal size for the AOF file to be rewritten, this
# is useful to avoid rewriting the AOF file even if the percentage increase
# is reached but it is still pretty small.
#
# Specify a percentage of zero in order to disable the automatic AOF
# rewrite feature.

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

简单解释一下,首先当你AOF文件超过了 auto-aof-rewrite-min-size才会重写。

Redis会记录上一次重写的大小,和当前AOF的大小,当 (当前AOF大小/上次重写AOF大小)> auto-aof-rewrite-percentage 则自动重写。

例如当前文件大小129mb,上一次AOF重写原文件大小是64mb,超过100%,就重写。

自动重写也是调用 bgrewriteaof 命令。

  • 手动触发

    调用bgrewriteaof命令。

    短短一句命令其实背后做了很多操作。

localhost:0>bgrewriteaof
"Background append only file rewriting started"

AOF重写大致过程:

  1. 父进程执行fork(),创建一个子进程。

  2. 父进程处理客户端请求,父进程把所有修改命令会写入到aof_rewrite_buf中,并根据appendfsync策略持久化到AOF文件中。

  3. 子进程把新AOF文件写入完成后,子进程发送信号给父进程,父进程更新统计信息。

  4. 父进程将aof_rewrite_buf(AOF重写缓冲区)的数据写入到新的AOF文件中。

过期的键不会被记录到 AOF 文件中

 AOF重写流程

AOF的持久化也可能会造成阻塞。

fsync 每秒同步一次,假如系统磁盘比较忙,可能就会造成Redis主线程阻塞。

# AOF优缺点:

优点:

  1. 提供了多种同步命令的方式,默认1秒同步一次写命令,最多丢失1秒内的数据;、

  2. 如果AOF文件有错误,比如在写AOF文件时redis崩溃了,redis提供了多种恢复AOF文件的方式,例如使用redis-check-aof工具修正AOF文件(一般都是最后一条写命令有问题,可以手动取出最后一条写命令);

  3. AOF文件可读性较强,也可手动操作写命令。

缺点:

  1. AOF文件比RDB文件较大;
  2. redis负载较高时,RDB文件比AOF文件具有更好的性能;
  3. RDB使用快照的方式持久化整个redis数据,而aof只是追加写命令,因此从理论上来说,RDB比AOF方式更加健壮,另外,官方文档也指出,在某些情况下,AOF的确也存在一些bug,(举个例子,阻塞命令 BRPOPLPUSH 就曾经引起过这样的 bug 。)这些bug的场景RDB是不存在的。

# 4、数据恢复

当Redis重新启动时,可以读取快照文件恢复数据。

将备份文件 (dump.rdb) 或者 (.aof文件)移动到 redis 安装目录并启动服务即可,redis就会自动加载文件数据至内存了。

RDB恢复又分两种情况:

1)主库master:

  • 载入RDB时,过期键会被忽略。

2)从库salve:

载入 RDB 时,文件中的所有键都会被载入,当同步进行时,会和Master 保持一致。不过,因为主从服务器在进行数据同步的时候,从服务器的数据库就会被清空,所以一般来说,过期键在载入RDB文件的从服务器也不会造成影响

AOF则不会,过期但并未被删除释放的状态会被正常记录到 AOF 文件中,当过期键发生释放删除时,DEL 也会被同步到 AOF 文件中去。

如果同时开启了RDB和AOF,Redis会优先加载AOF文件,找不到AOF文件才会加载RDB文件。

# 混合模式

redis4.0开始 添加了RDB-AOF混合方式,可以通过设置aof-use-rdb-preamble yes开启。.aof文件就由.rdb和.aof文件组成了。这样加载速度快,同时结合AOF,增量的数据以AOF方式保存了,数据更少的丢失。

# 5、总结

对比维度 RDB (Redis Database) AOF (Append Only File)
工作原理 定时生成内存数据的二进制快照 记录每一次写操作命令到日志文件(文本格式)
数据可靠性 较低,可能丢失最后一次快照后的数据 较高,取决于配置(如everysec策略最多丢失1秒数据)
恢复速度 快(直接加载二进制文件) 慢(需逐条重放命令)
文件大小 较小(压缩的二进制格式) 较大(记录所有写命令)
性能影响 对性能影响小,但fork子进程时可能导致短暂阻塞 对性能有一定影响,程度取决于同步策略

如果你非常关心你的数据,但仍然可以承受数分钟以内的数据丢失, 那么你可以只使用 RDB 持久化。

因为定时生成 RDB 快照(snapshot)非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快, 除此之外, 使用 RDB 还可以避免之前提到的 AOF 程序的 bug 。

如果要担心数据安全和一致性,应该同时使用两种持久化功能。

# 版本优化

Redis 5.0

  • 进一步对 AOF 持久化机制进行了优化,增强了 AOF 文件的压缩和优化。通过对 AOF 文件中的重复操作进行压缩,减少了磁盘的使用空间,提升了 AOF 机制的性能。
  • 持久化的配置进行了一些细化,比如优化了 AOF 文件的重写触发机制,避免了重写过程中因不必要的操作而造成性能的影响。
阅读全文
×

(为防止恶意爬虫)
扫码或搜索:HelloCoder
发送:290992
即可永久解锁本站全部文章

解锁
#Redis#RDB#AOF#持久化机制
上次更新: 2025-12-04 10:36:01
最近更新
01
prometheus指标脱坑
12-04
02
什么是IDEA
12-04
03
Gradle项目导入
12-04
更多文章>
Theme by Vdoing | Copyright © 2020-2025 码农阿雨
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式