tulip notes
首页
  • 学习笔记

    • 《Vue》
  • 踩坑日记

    • JavaScript
  • MQ
  • Nginx
  • IdentityServer
  • Redis
  • Linux
  • Java
  • SpringBoot
  • SpringCloud
  • MySql
  • docker
  • 算法与设计模式
  • 踩坑与提升
  • Git
  • GitHub技巧
  • Mac
  • 网络
  • 项目构建合集
  • 一些技巧
  • 面试
  • 一些杂货
  • 友情链接
  • 项目发布
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Star-Lord

希望一天成为大师的学徒
首页
  • 学习笔记

    • 《Vue》
  • 踩坑日记

    • JavaScript
  • MQ
  • Nginx
  • IdentityServer
  • Redis
  • Linux
  • Java
  • SpringBoot
  • SpringCloud
  • MySql
  • docker
  • 算法与设计模式
  • 踩坑与提升
  • Git
  • GitHub技巧
  • Mac
  • 网络
  • 项目构建合集
  • 一些技巧
  • 面试
  • 一些杂货
  • 友情链接
  • 项目发布
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 各种MQ

  • Nginx

  • IdentityServer

  • Redis

    • 初始Redis与安装
    • Redis常用的一些场景
    • Redis中的缓存失效
    • 关于Redis的一些问题
    • Redis的持久化策略
      • RDB-持久化
        • 原理
        • 命令配置
        • RDB优缺点分析
      • AOF-持久化
        • 原理
        • AOF优缺点分析
      • 总结
      • 断电-恢复
      • 扩展
    • Redis从单机到集群等模式
    • Redis和MySql实现数据一致性
    • 通过Redis实现分布式锁
    • Redis的客户端介绍
  • Linux

  • 中间件
  • Redis
EffectTang
2023-11-20
目录

Redis的持久化策略

# Redis的持久化策略

redis虽然是基于内存进行操作的一个数据库,但它也有将数据持久化到电脑磁盘上的能力

Redis的持久化有别于mysql这种数据库,它了实现⾼效的读写操作,并不会即时进⾏数据的持久化,⽽是按照⼀定的规则进⾏持久化操作的——持久化策略

Redis提供了2种持久化策略:

  • RDB (Redis DataBase)
  • AOF(Append Only File)

# RDB-持久化

RDB:在满⾜特定的redis操作条件时,将内存中的数据以数据快照的形式存储到rdb⽂件中。Redis重启的时候,通过加载dump.rdb文件来恢复数据,从而达到数据持久化。当然,你也可以通过手动触发的方式进行保存。

以下是手动触发rdb-持久化命令:

127.0.0.1:6379> save
OK
127.0.0.1:6379> bgsave
Background saving started
127.0.0.1:6379> 
1
2
3
4
5

Save,是通过主进程来执行rdb,会阻塞所有命令。而bgsave,则会执行fork操作创建子进程,通过子进程来完成RDB持久化。阻塞只会发生在fork阶段。

# 原理

RDB是redis默认的持久化策略,当redis中的写操作达到指定的次数、同时距离上⼀次持久化达到指定的时间 就会将redis内存中的数据⽣成数据快照,保存在指定的rdb⽂件中。

还需要注意的是,RDB每一次的数据快照生成都是redis中的全部数据,且新的数据快照在保存到rdb文件时,会把原有的快照给覆盖。

其中的默认的规则的定义在redis.conf配置文件中可以看到,我们也可以通过取消注释的方式并修改参数的方式进行自定义规则

# Unless specified otherwise, by default Redis will save the DB:
#   * After 3600 seconds (an hour) if at least 1 change was performed
#   * After 300 seconds (5 minutes) if at least 100 changes were performed
#   * After 60 seconds if at least 10000 changes were performed
1
2
3
4

默认触发持久化条件:

  • 3600s 1次:3600s内,至少有一个键发生变化,就会进⾏持久化
  • 300s 10次:300s内,至少有一个键发生变化,就会进⾏持久化
  • 60s 10000次:60s内,至少有一个键发生变化,就会就⾏持久化

此外,我们还可以指定rdb数据存储的文件,同样在配置文件中redis.conf可以找到

# The filename where to dump the DB
dbfilename dump.rdb
1
2

最后,redis既然支持两种持久化策略,那么它们彼此肯定有类似开关的配置,来控制redis选择何种持久化策略

RDB持久化也是可以在配置文件中进行关闭的,将rdbcompression 后的yes改为no即可

# Compress string objects using LZF when dump .rdb databases?
# By default compression is enabled as it's almost always a win.
# If you want to save some CPU in the saving child set it to 'no' but
# the dataset will likely be bigger if you have compressible values or keys.
rdbcompression yes
1
2
3
4
5

# 命令配置

除了通过配置文件方式改变,你也可以通过命令的方式进行修改

CONFIG SET dbfilename mydata.rdb
CONFIG SET dir /var/lib/redis/backup
1
2

第一条是修改持久化文件名称,第二条则是修改存储位置。

注意事项

  • 重启服务:更改 dbfilename 和 dir 需要重启 Redis 服务才能生效。
  • 权限检查:确保目标目录具有足够的权限,Redis 服务账户能够写入该目录。
  • 备份数据:在生产环境中进行此类更改前,请确保备份现有数据,以防意外丢失。

# RDB优缺点分析

缺点

  • 如果redis出现故障,存在数据丢失的⻛险,丢失上⼀次持久化之后的操作数据
  • RDB采⽤的是数据快照形式进⾏持久化,不适合实时性持久化;
  • 如果数据量巨⼤,在RDB持久化过程中⽣成数据快照的⼦进程执⾏时间过⻓,会导致redis卡顿,因此 save时间周期设置不宜过短;

优点

  • 但是在数据量较⼩的情况下,执⾏速度⽐较快;
  • 由于RDB是以数据快照的形式进⾏保存的,我们可以通过拷⻉rdb⽂件轻松实现redis数据移植

# AOF-持久化

Append Only File,当达到设定触发条件时,将redis执⾏的写操作指令存储在aof⽂件中,从而达到数据持久化的目的。当Redis重启时再重新执行AOF文件中的命令达到恢复数据的目的。AOF的主要作用是解决了数据持久化的实时性。

那么这个触发条件是什么呢?系统定制的,还是说开发者自行配置的?

待交叉验证

肯定不能每执行一条写入命令就记录到文件中,那会严重拖垮Redis的性能。于是Redis准备了一个缓冲区,然后把要记录的命令先临时保存在这里,然后再择机写入文件。Redis把这个临时缓冲区叫做aof_buf。

但随着时间的推移,写的这个aof_buf备份文件越来越大,不仅非常占硬盘空间,复制、移动、加载、分析都非常的麻烦耗时。得想个办法把文件给压缩一下,于是有了AOF重写。那如何压缩呢——或者叫如何重写呢?

原来的一条条记录这种方式实在是太笨了,数据改来改去有很多中间状态都没用,何不就把最终的数据状态记录下来就好了。比如这三条指令可以合并成一条,不过这件事干起来还是很耗时间。于是Redis决定和RDB方式一样,fork出一个子,经常来做这件事情。

但这样还是存在一个问题,如果在重写期间,Redis要是修改了数据,就会出现和重写的内容不一致的情况。怎么办呢?

于是Redis在之前的aof_buf之外又准备了一个缓冲区AOF重写缓冲区(aof_rewrite_buf)。从子进程创建重写开始的那一刻起,Redis把后面来的写入命令也copy 1份,写到这个重写缓冲区中。等到子进程重写文件结束之后,再把这个缓冲区中的命令写入到新的lf文件中,最后再重命名新的文件,替换掉原来的那个臃肿不堪的大文件,终于重写大功告成。

以上就是系统默认的同步方式。

注意:Redis中默认未开启aof持久化。

# AOF and RDB persistence can be enabled at the same time without problems.
# If the AOF is enabled on startup Redis will load the AOF, that is the file
# with the better durability guarantees.
#
# Please check https://redis.io/topics/persistence for more information.

appendonly no
1
2
3
4
5
6
7

# 原理

Redis将每⼀个成功的写操作写⼊到aof⽂件中,当redis重启的时候就执⾏aof⽂件中的指令,并将其应用到内存中从而恢复数据。

跟rdb持久化类似,它的一些设置也可以在配置文件redis.conf中进行修改:

将appendonly 设置为 yes,则表示开启aof持久化。

# AOF and RDB persistence can be enabled at the same time without problems.
# If the AOF is enabled on startup Redis will load the AOF, that is the file
# with the better durability guarantees.
#
# Please check https://redis.io/topics/persistence for more information.
# 开启aof持久化策略 
appendonly no
1
2
3
4
5
6
7

同样,我们也可以指定aof数据存储的文件

# The name of the append only file (default: "appendonly.aof")
## 设置 aof文件
appendfilename "appendonly.aof"
1
2
3

持久化策略同样可以在配置文件redis.conf中找到并修改:

# If unsure, use "everysec".

# appendfsync always
appendfsync everysec
# appendfsync no
1
2
3
4
5

默认的触发条件是,每秒执行一次。另外2个分别是:

  • appendfsync always:只要进⾏成功的写操作,就执⾏aof
  • appendfsync no:让redis执⾏决定aof,完全依赖OS的写入,一般为30秒左右一次,性能最好但是持久化最没有保证,不被推荐。

AOF(Append Only File)持久化机制并不是直接将写操作命令写入硬盘文件,而是首先写入一个缓冲区,然后再根据配置的不同策略将缓冲区的内容同步到硬盘文件中。这种设计是为了提高性能,避免频繁的磁盘 I/O 操作对性能的影响。

# AOF优缺点分析

aof存储的是指令,⽽且会对指令进⾏整理;⽽RDB直接⽣成数据快照,在数据量不⼤时RDB⽐较快。

AOF策略记录每次对服务器进行写的操作,并将这些操作追加到文件末尾,以此来恢复原始数据。但是AOF文件有可能变得越来越大,为了降低存储开销和提高恢复速度,Redis提供了AOF重写功能。这个重写就是所谓的整理。

它是Redis的一种优化措施,它通过对AOF文件中的指令进行整理(例如合并相同的指令、消除重复的指令等),从而达到减少文件大小的目的。具体来说,Redis在执行AOF重写时,会创建一个新的临时文件,然后遍历现有的AOF文件,并根据一系列规则对其进行整理,最后将整理后的指令写入新的临时文件中,然后再替换原有的AOF文件。这样就可以有效地减少AOF文件的大小,提高恢复速度。

比如有两个操作,分别是set k1为k2,set k1为 k3,整理后 就会合并为一个set k1为k3

优点

  • aof是对指令⽂件进⾏增量更新,更适合实时性持久化
  • 跟RDB类似,可以通过拷⻉aof⽂件进⾏redis数据移植

缺点

  • 由于它会记录每一次写操作,因此会对服务器的性能造成一定的影响;
  • 由于它以文件的形式存储数据,因此在文件较大时,会导致服务器读取速度变慢;

# 总结

粗略的讲,RDB是选择了性能,但数据容易丢失,而AOF选择了保存数据,性能上不如RDB。

redis官⽅建议同时开启2中持久化策略,但如果同时存在aof⽂件和rdb⽂件的情况下恢复数据时,只会选择aof文件。

# 断电-恢复

当 Redis 重启时,会根据以下逻辑决定如何恢复数据:

  1. 检查 AOF 文件:如果 AOF 持久化被启用(即 appendonly yes),Redis 会首先尝试使用 AOF 文件恢复数据。如果 AOF 文件存在并且是有效的,Redis 将从 AOF 文件中恢复数据。
  2. 检查 RDB 文件:如果 AOF 文件不存在或无法使用,Redis 会检查是否存在 RDB 文件。如果存在有效 RDB 文件,Redis 将从 RDB 文件中恢复数据。
  3. 恢复顺序:
    • 优先使用 AOF:如果 AOF 文件存在并且可用,Redis 会优先使用 AOF 文件进行恢复。
    • 使用 RDB 作为备选:如果 AOF 文件不存在或无法使用,Redis 会尝试使用 RDB 文件恢复数据。

# 扩展

最后,在Redis4.0之后,还提供了混合模式,这种模式下RDB持久化的数据也会写进 appendonly.aof文件,而不是 dump.rdb 文件;而AOF持久化的命令也追加在 appendonly.aof 中RDB持久化的数据之后 也就是说,混合模式下 appendonly.aof 文件的前部分是 RDB的数据,后部分才是AOF的数据。

对应的开启同样也在配置文件redis.conf,但开启混合不仅需要开启混合开关,还需开启aof的持久化开关

# 开启aof持久化策略 
appendonly no
# When loading, Redis recognizes that the AOF file starts with the "REDIS"
# string and loads the prefixed RDB file, then continues loading the AOF
# tail.
aof-use-rdb-preamble yes
1
2
3
4
5
6

这样掉电恢复时,就变成了如下步骤:

  • 首先读取 AOF 文件中的 RDB 部分,将其中的键值对加载到内存中
  • 然后读取 AOF 文件中的 AOF 部分,按顺序执行其中的命令,更新内存中的数据
上次更新: 2025/04/23, 16:23:16
关于Redis的一些问题
Redis从单机到集群等模式

← 关于Redis的一些问题 Redis从单机到集群等模式→

最近更新
01
面向切面跟自定义注解的结合
05-22
02
时间跟其他数据的序列化
05-19
03
数据加密与安全
05-17
更多文章>
Theme by Vdoing | Copyright © 2023-2025 EffectTang
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式