Skip to content

redis持久化

深入了解Redis持久化原理

Redis持久化机制:RDB和AOF

redis持久化方式

**RDB:**Redis 将内存数据库快照保存在名字为 dump.rdb 的二进制文件中。

优点:

  • 只会生成一个文件,方便操作,文件小
  • 相对AOF来说,恢复大数据集的速度快
  • 在RDB持久化开始时,只会fork一个子线程处理所有的持久化工作,不会影响到父系线程

缺点:

  • 如果你想保证数据的高可用性,即最大限度的避免数据丢失,那么RDB将不是一个很好的选择。因为系统一旦在定时持久化之前出现宕机现象,此前没有来得及写入磁盘的数据都将丢失。
  • 由于RDB是通过fork子进程来协助完成数据持久化工作的,因此,如果当数据集较大时,可能会导致整个服务器停止服务几百毫秒,甚至是1秒钟。

**AOF:**从现在开始, 每当 Redis 执行一个改变数据集的命令时(比如 SET), 这个命令就会被追加到 AOF 文件的末尾。

这样的话, 当 Redis 重新启动时, 程序就可以通过重新执行 AOF 文件中的命令来达到重建数据集的目的。

优点:

  • AOF可以更好的保护数据不丢失,一般AOF会每隔1秒,通过一个后台线程执行一次fsync操作,最多丢失1秒钟的数据。
  • AOF日志文件没有任何磁盘寻址的开销,写入性能非常高,文件不容易破损。
  • AOF日志文件即使过大的时候,出现后台重写操作,也不会影响客户端的读写。
  • AOF日志文件的命令通过非常可读的方式进行记录,这个特性非常适合做灾难性的误删除的紧急恢复。

缺点:

  • AOF日志文件相对于RDB来说会更大
  • AOF开启后,支持的写QPS会比RDB支持的写QPS低

**RDB+AOF混合持久化:**如果开启了混合持久化,aof在重写时,不再是单纯将内存数据转换为RESP命令写入aof文件,而是将重写这一刻之前的内存做rdb快照处理,并且将rdb快照内容和增量的aof修改内存数据的命令存在一起,都写入新的aof文件,新的aof文件一开始不叫appendonly.aof,等到重写完成后,新的aof文件才会进行改名,原子的覆盖原有的aof文件,完成新旧两个aof文件的替换。

于是在redis重启的时候,可以先加载rdb文件,然后再重放增量的aof日志就可以完全替代之前的aof全量文件重放,因此重启效率大幅得到提高。

简单说就是BGSAVE做镜像全量持久化,AOF做增量持久化。

AOF

结论:使用 redistemplate-standalone-load-test 测试后,AOF appendfsync always 对 redis 性能损耗很大,appendfsync everysec 对 redis 性能损耗很小。

介绍

Redis AOF(Append Only File)是一种日志形式的持久化方法,它记录服务器执行的所有写操作命令,以增量保存的方式将Redis执行过的所有写指令记录下来(读操作不记录),并且只许追加文件但不可以改写文件。以下是对Redis AOF的详细介绍:

一、AOF的特点

  1. 优势
    • 数据完整性好:AOF采用日志的形式来记录每个写操作,因此数据的完整性得到了很好的保障。在默认情况下,Redis每秒会将AOF文件同步到磁盘一次,因此最多只会丢失一秒的数据。
    • 文件可读性较好:AOF文件以纯文本的形式记录了Redis执行的写命令,因此文件内容易于理解,方便进行手动修改和分析。
    • 可修复性:即使AOF文件因为某些原因(如磁盘空间已满、写的过程中宕机等)未执行完整的写入命令,也可以使用redis-check-aof工具进行修复。
  2. 劣势
    • 数据恢复速度慢:与RDB相比,AOF的数据恢复速度较慢。因为AOF需要逐个执行文件中的命令来将数据载入到内存中,所以载入速度相对较慢。
    • 占用磁盘空间大:对于相同的数据集,AOF文件的体积通常要大于RDB文件的体积。这是因为AOF记录了所有的写操作命令,而RDB则是保存了某个时间点的数据集快照。
    • 性能压力:如果每次读写都同步的话,AOF会对性能产生一定的压力。虽然Redis提供了多种同步策略来平衡性能和数据安全性,但在某些高负荷场景下,AOF的性能可能会受到影响。

二、AOF的操作

  1. 开启AOF
    • 默认情况下,Redis的AOF功能是关闭的。要开启AOF,需要在Redis的配置文件redis.conf中找到appendonly这一行,并将其值改为yes。例如:将# appendonly no改为appendonly yes。保存配置文件后,重启Redis服务器即可生效。
  2. AOF重写机制
    • 随着Redis不断的进行写操作,AOF的文件会越来越大。为了解决这个问题,Redis提供了AOF重写机制。重写机制会创建一个新的AOF文件,其中包含恢复当前数据集所需的最小命令集合。这样可以有效地减小AOF文件的体积,提高恢复速度。
    • Redis提供了两种方式来触发AOF重写:手动触发和自动触发。手动触发可以通过执行BGREWRITEAOF命令来实现;自动触发则需要根据配置文件中的auto-aof-rewrite-percentage和auto-aof-rewrite-min-size选项来设置。当AOF文件的大小超过auto-aof-rewrite-min-size指定的最小大小时,并且AOF文件的大小比上一次重写后的大小增长了auto-aof-rewrite-percentage指定的百分比时,Redis会自动触发重写。
  3. AOF同步策略
    • Redis提供了多种AOF同步策略来平衡性能和数据安全性。这些策略包括:
      • always:每次执行写入都会执行同步,这是最安全也是最慢的方式。
      • everysec(默认):每秒执行一次同步操作。这种方式既兼顾了性能又保证了安全。
      • no:不主动进行同步操作,而是完全交由操作系统来做(即每30秒一次或更长时间)。这是最快但最不安全的方式。
  4. AOF恢复
    • 当Redis服务器重启时,它会根据AOF文件中的内容来恢复数据。具体过程为:逐个执行AOF文件中的命令来将硬盘中的数据载入到内存中。如果AOF文件损坏或丢失,则可能导致数据无法恢复。因此,在使用AOF时,建议定期备份AOF文件以防止数据丢失。

三、AOF与RDB的比较

  1. 数据恢复速度:RDB的数据恢复速度通常比AOF快,因为RDB保存的是数据集的快照,而AOF则需要逐个执行文件中的命令来恢复数据。
  2. 数据完整性:AOF的数据完整性比RDB好,因为AOF记录了所有的写操作命令,即使在最恶劣的情况下也只会丢失不超过两秒的数据。而RDB则可能丢失最后一次快照以后更改的所有数据。
  3. 占用磁盘空间:对于相同的数据集,AOF文件的体积通常要大于RDB文件的体积。这是因为AOF记录了所有的写操作命令,而RDB则是保存了某个时间点的数据集快照。
  4. 使用场景:如果数据相对重要且希望将损失降到最小,则可以使用AOF方式进行持久化;如果只需要数据在服务器运行的时候存在且对性能要求较高,则可以使用RDB方式进行持久化或混合使用两种方式。

综上所述,Redis AOF是一种重要的持久化方式,它能够有效地保障数据的完整性和可恢复性。然而,在使用AOF时也需要注意其可能带来的性能压力和磁盘空间占用问题。因此,在选择持久化方式时需要根据具体的应用场景和需求进行权衡和选择。

配置样例

shell
# 默认关闭若要开启将no改为yes
appendonly yes
# append文件的名字
appendfilename "appendonly.aof"
# AOF文件的写入方式
# always一旦缓存区内容发生变化就写入AOF文件中,对性能损耗影响很大
appendfsync always
# everysec 每个一秒将缓存区内容写入文件 默认开启的写入方式,对性能损耗很小
appendfsync everysec
# 将写入文件的操作交由操作系统决定
appendfsync no
# 当aof文件增长大小大于上次aof重写文件大小100%时触发重写,例如:上次aof重写后文件为100MB,此时aof文件大小为201MB则触发重写(201MB是100MB的约100%)
auto-aof-rewrite-percentage 100
# 表示当 AOF 文件的大小超过 64MB 时,如果同时满足 auto-aof-rewrite-percentage 的条件,Redis 将自动触发 AOF 文件重写。
auto-aof-rewrite-min-size 64mb

测试 AOF 持久化

使用https://gitee.com/dexterleslie/demonstration/tree/master/demo-redis/redis-server/docker-based/mode-standalone测试 AOF 持久化特性

配置 redis.conf

properties
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

#   save ""

# save 900 1
# save 300 10
# save 60 10000

使用前端模式启动 redis

sh
docker compose up

进入 redis cli

sh
docker exec -it demo-redis-server /bin/bash
redis-cli -a 123456

使用 set 命令创建数据

sh
set hello 8

杀死 redis 进程(为了避免正常关闭 redis 时会 save 数据)

sh
docker compose kill

重新启动 redis 后发现数据没有丢失

sh
docker compose up
keys *

aof重写机制

什么是aof重写?

在Redis中,"rewrite" 通常指的是 AOF(Append Only File)重写功能。AOF是Redis持久化的一种方式,它通过记录服务器接收到的每一个写命令(如SET、LPUSH等),并以文本的形式追加到文件中来实现数据的持久化。随着操作的不断进行,AOF文件会越来越大,这不仅会占用大量的磁盘空间,还会影响Redis的启动恢复速度,因为Redis在启动时会重新执行AOF文件中的命令来恢复数据。

为了解决这个问题,Redis提供了AOF重写(Rewrite)功能。AOF重写会创建一个新的AOF文件,该文件包含了恢复当前数据集所需的最少命令。这个过程并不是通过读取内存中的数据并重新写入文件来完成的,而是遍历现有的AOF文件,从中识别出已经过期的命令、重复的命令以及可以通过更少的命令来达到相同效果的命令,从而生成一个新的、更小的AOF文件。

AOF重写的触发方式

  1. 自动触发:Redis会根据配置中的auto-aof-rewrite-percentage(默认100)和auto-aof-rewrite-min-size(默认64MB)两个参数来自动触发AOF重写。当AOF文件的增长比例超过auto-aof-rewrite-percentage设定的值时(并且AOF文件大小大于auto-aof-rewrite-min-size),Redis会自动触发AOF重写。
  2. 手动触发:可以通过BGREWRITEAOF命令来手动触发AOF重写。这个命令会异步地执行AOF重写操作,不会阻塞Redis服务。

AOF重写的优点

  • 减少磁盘占用:通过重写AOF文件,可以去除无效的、重复的命令,从而减小AOF文件的大小。
  • 加速数据恢复:更小的AOF文件意味着在Redis重启时,需要执行的命令更少,因此可以更快地恢复数据。

注意事项

  • AOF重写虽然可以减小AOF文件的大小,但也会消耗一定的CPU和内存资源,特别是在数据集较大时。
  • 在AOF重写过程中,Redis会同时维护新旧两个AOF文件,直到新的AOF文件写入完成并且Redis认为这个新的AOF文件是安全的之后,才会删除旧的AOF文件。因此,在AOF重写期间,磁盘空间的使用量可能会暂时增加。
  • 为了确保数据的持久性,Redis在AOF重写时会继续将新的写命令追加到旧的AOF文件中,同时也会将这些命令缓存起来,以便在重写完成后追加到新的AOF文件中。这样,即使在AOF重写过程中发生宕机,Redis也可以通过旧的AOF文件或内存中的数据来恢复数据。

aof重写会影响redis性能吗?

AOF重写确实会对Redis的性能产生一定影响,但这种影响通常是可控的,并且可以通过合理的配置和优化来减轻。以下是对AOF重写影响Redis性能的详细分析:

一、写入性能影响

  1. 写入性能下降:在AOF重写过程中,Redis需要同时处理客户端的写请求和AOF重写的任务。虽然AOF重写是由一个后台子进程(bgrewriteaof)完成的,但这个子进程会扫描Redis的内存数据,并将其转换为一系列写命令,然后写入到一个新的AOF文件中。这个过程中,如果客户端的写请求较多,主进程需要将这些写请求同时写入到旧的AOF文件和内存中的AOF缓冲区中,以确保数据的完整性。这可能会导致Redis的写入性能暂时下降。
  2. CPU和内存消耗:AOF重写过程中,子进程会占用一定的CPU和内存资源。如果Redis服务器的CPU和内存资源较为紧张,那么AOF重写可能会加剧这种紧张状态,进一步影响Redis的性能。

二、启动时间影响

虽然AOF重写本身不会直接影响Redis的启动时间,但过大的AOF文件会延长Redis的启动恢复时间。因为Redis在启动时需要加载并解析AOF文件,将其中的命令重新执行以恢复数据。如果AOF文件过大,这个过程就会相应地延长。

三、磁盘IO负载影响

AOF重写过程中,需要频繁地进行磁盘写操作,以将新的AOF文件写入磁盘。这可能会增加磁盘IO的负载,从而影响Redis的整体性能。特别是在磁盘性能较差或磁盘IO负载已经较高的情况下,AOF重写对性能的影响会更加明显。

四、如何减轻AOF重写对性能的影响

  1. 合理配置AOF重写触发条件:通过调整auto-aof-rewrite-percentageauto-aof-rewrite-min-size参数,可以控制AOF重写的触发时机和频率,从而避免在Redis负载较高时进行AOF重写。
  2. 优化Redis配置:合理配置Redis的内存使用、CPU使用等参数,确保Redis服务器有足够的资源来处理AOF重写等任务。
  3. 使用更快的磁盘:如果可能的话,使用更快的磁盘(如SSD)来存储AOF文件,可以加快AOF文件的写入速度,从而减轻磁盘IO负载对Redis性能的影响。
  4. 避免在高峰期进行AOF重写:如果可能的话,尽量在Redis负载较低的时间段进行AOF重写,以避免对Redis性能造成较大影响。

综上所述,AOF重写确实会对Redis的性能产生一定影响,但这种影响可以通过合理的配置和优化来减轻。因此,在使用Redis时,需要根据实际情况来配置AOF重写相关的参数,并密切关注Redis的性能指标,以便及时发现并解决问题。

RDB

结论:使用 redistemplate-standalone-load-test 测试后,RDB 持久化方案对 redis 性能损耗很小。

介绍

Redis RDB(Redis Database)是Redis的一种持久化机制,它通过将Redis在某个时间点的数据以快照的形式保存到磁盘上,从而确保数据的持久性。以下是关于Redis RDB的详细介绍:

一、工作原理

RDB持久化通过创建一个包含Redis数据库所有键值对的快照文件来实现。这个过程将内存中的数据以二进制格式转储到磁盘上,形成一个紧凑的文件,便于备份和迁移。当Redis需要持久化数据时,它会fork出一个子进程,这个子进程会遍历Redis的内存数据集,并将其写入到一个临时的RDB文件中。当写入完成后,这个临时文件会被重命名为正式的RDB文件,并替换掉旧的RDB文件。

二、触发方式

RDB的触发方式主要有以下几种:

  1. 手动触发
    • 通过执行SAVE命令可以立即执行一次快照生成,但需要注意,该命令会阻塞Redis服务器,直到RDB文件创建完毕,因此在生产环境中不推荐直接使用。
    • 使用BGSAVE命令可以在后台异步执行快照生成,不会阻塞服务器处理客户端请求。
  2. 自动触发
    • Redis服务器可以根据配置文件中的策略自动执行快照。例如,在Redis的配置文件redis.conf中,可以设置save指令来定义在一定时间内发生指定数量的写操作后自动执行BGSAVE。

三、配置文件

在Redis的配置文件redis.conf中,可以对RDB进行以下配置:

  1. RDB文件的保存路径:通过dir选项来设置RDB文件的保存路径。
  2. RDB文件的生成策略:通过save选项来设置RDB文件的生成策略。save选项是一个数组,每个元素由两个数字组成,表示在指定的时间间隔内,如果至少有指定数量的键发生变化,则执行一次BGSAVE命令。

四、优缺点

优点

  1. 性能高效:RDB持久化是通过fork一个子进程来完成的,子进程负责将数据写入磁盘,而主进程继续处理客户端请求,因此对Redis的性能影响相对较小。
  2. 恢复速度快:由于RDB文件是二进制格式且包含完整的数据快照,因此在Redis重启时,加载RDB文件的速度非常快。
  3. 适合备份:RDB文件是紧凑的二进制文件,节省磁盘空间,非常适合用于备份和灾难恢复。

缺点

  1. 数据丢失风险:如果Redis在两次生成RDB文件之间发生故障,这段时间内的数据将会丢失。
  2. CPU和I/O开销:生成RDB文件时,Redis需要进行大量数据的序列化和I/O操作,会对CPU和I/O资源造成一定的压力。

五、其他注意事项

  1. 检查修复RDB文件:在备份的时候,RDB文件有可能出现破损。可以使用redis-check-rdb命令来检查并修复RDB文件。
  2. 禁用RDB:可以通过修改配置文件或使用redis-cli config set save ""命令来禁用RDB持久化。

综上所述,Redis RDB是一种高效、紧凑且易于备份的持久化方式,适用于对数据完整性要求不高但需要快速恢复的场景。然而,它也存在数据丢失的风险和一定的CPU、I/O开销。因此,在选择Redis的持久化方式时,需要根据实际需求和风险承受能力进行选择。

触发快照的时机

时机如下:

  • 执行savebgsave命令
  • 配置文件设置save <seconds> <changes>规则,自动间隔性执行bgsave命令
  • 主从复制时,从库全量复制同步主库数据,主库会执行bgsave
  • 执行flushall命令清空服务器数据
  • 执行shutdown命令关闭Redis时,会执行save命令

使用save命令会阻塞Redis服务器进程,服务器进程在RDB文件创建完成之前是不能处理任何的命令请求。

而使用bgsave命令不同的是,basave命令会fork一个子进程,然后该子进程会负责创建RDB文件,而服务器进程会继续处理命令请求。

配置样例

shell
appendonly no

# 想禁用的话不设置save   或者save ""
save 900 1
save 300 10
# 60秒内有10000个key变动则在第60秒持久化到存储中,注意:不是在第10000个key变动时持久化。
save 60 10000
# 备份进程出错主进程停止写入操作
stop-writes-on-bgsave-error yes
# 是否压缩rdb文件 推荐no 相对于硬盘成本cpu更值钱
rdbcompression yes

save <seconds> <changes>表示在seconds秒内,至少有changes次变化,就会自动触发gbsave命令。

  • save 900 1 当时间到900秒时,如果至少有1个key发生变化,就会自动触发bgsave命令创建快照
  • save 300 10 当时间到300秒时,如果至少有10个key发生变化,就会自动触发bgsave命令创建快照
  • save 60 10000 当时间到60秒时,如果至少有10000个key发生变化,就会自动触发bgsave命令创建快照

测试 RDB 持久化

使用https://gitee.com/dexterleslie/demonstration/tree/master/demo-redis/redis-server/docker-based/mode-standalone测试 RDB 持久化特性

配置 redis.conf

properties
save 30 2

使用前端模式启动 redis

sh
docker compose up

进入 redis cli

sh
docker exec -it demo-redis-server /bin/bash
redis-cli -a 123456

30 秒内只有一个 set 命令,时间到了 30 秒时 bgsave 进程没有启动,因为 redis.conf 配置为 30 秒内至少 2 个 set 命令

sh
set hello 8

杀死 redis 进程(为了避免正常关闭 redis 时会 save 数据)

sh
docker compose kill

重新启动 redis 后发现数据丢失

sh
docker compose up
keys *

删除之前的 redis 数据

sh
docker compose down -v

30 秒内两个 set 命令,时间到 30 秒时 bgsave 进程启动

sh
set hello 8
set hello1 8

杀死 redis 进程(为了避免正常关闭 redis 时会 save 数据)

sh
docker compose kill

重新启动 redis 后发现数据没有丢失

sh
docker compose up
keys *

RDB+AOF混合持久化

注意:混合持久化是在AOF重写阶段起作用,需要启用AOF持久化配置,可以不启用RDB持久化配置

参考 demo-redis/redis-server/standalone/redis.conf 配置

介绍

Redis的RDB+AOF混合持久化是一种结合了RDB快照和AOF日志的持久化方式,旨在同时提供快速的数据恢复能力和数据完整性保障。以下是对Redis RDB+AOF混合持久化的详细介绍:

一、混合持久化的原理

混合持久化整合了RDB和AOF的优点。在混合持久化模式下,Redis会首先以RDB的格式将数据写入文件开头部分,再将后续的操作命令以AOF的格式追加到文件末尾。这样,在恢复数据时,Redis可以优先加载RDB部分实现快速的数据恢复,然后再通过AOF部分补全数据,从而确保数据的完整性。

二、混合持久化的配置与启用

  1. 配置混合持久化

    要在Redis中启用混合持久化,需要在Redis的配置文件(redis.conf)中进行设置。通常,需要设置以下两个选项:

    • appendonly yes:启用AOF持久化。
    • aof-use-rdb-preamble yes:启用混合持久化。

    设置完成后,重启Redis服务器即可生效。

  2. 触发混合持久化

    混合持久化的触发方式与AOF持久化类似。在混合持久化模式下,Redis会根据配置文件中设置的AOF重写触发条件来决定何时进行混合持久化。当满足重写条件时,Redis会创建一个新的AOF文件,并将当前内存中的数据以RDB格式写入文件开头,然后将后续的操作命令以AOF格式追加到文件末尾。

三、混合持久化的优点与缺点

  1. 优点
    • 快速恢复:由于混合持久化文件开头部分包含了RDB格式的数据快照,因此Redis在恢复数据时可以先加载这部分数据,实现快速的数据恢复。
    • 数据完整性:通过AOF格式的命令追加,混合持久化可以确保在Redis宕机或重启后,数据能够完整地恢复。
    • 性能平衡:混合持久化结合了RDB和AOF的优点,既不会因频繁的全量快照而导致性能下降,也不会因AOF文件过大而影响恢复速度。
  2. 缺点
    • 磁盘空间占用:虽然混合持久化通过压缩和优化减少了数据文件的体积,但仍然需要占用一定的磁盘空间来存储持久化文件。
    • 写入性能影响:在混合持久化模式下,Redis需要将数据同时写入RDB和AOF两部分,这可能会对写入性能产生一定的影响。然而,由于Redis采用了异步写入和子进程处理等技术来优化性能,因此这种影响通常是可以接受的。

四、使用场景

混合持久化适用于对数据安全性要求较高且希望兼顾性能和恢复速度的场景。例如,在金融、电商等关键业务系统中,数据的安全性和完整性至关重要,同时业务对性能的要求也较高。在这种情况下,混合持久化可以提供一个良好的解决方案。

综上所述,Redis的RDB+AOF混合持久化是一种结合了RDB快照和AOF日志优点的持久化方式,它提供了快速的数据恢复能力和数据完整性保障。在配置和使用混合持久化时,需要根据具体的应用场景和需求进行权衡和选择。

测试 RDB+AOF 混合持久化

文件配置如下:

shell
# 默认关闭若要开启将no改为yes
appendonly yes
# append文件的名字
appendfilename "appendonly.aof"
# everysec 每个一秒将缓存区内容写入文件 默认开启的写入方式,对性能损耗很小
appendfsync everysec
# 当aof文件增长大小大于上次aof重写文件大小100%时触发重写,例如:上次aof重写后文件为100MB,此时aof文件大小为201MB则触发重写(201MB是100MB的约100%)
auto-aof-rewrite-percentage 100
# 表示当 AOF 文件的大小超过 64MB 时,如果同时满足 auto-aof-rewrite-percentage 的条件,Redis 将自动触发 AOF 文件重写。
auto-aof-rewrite-min-size 64mb
# 启用RDB+AOF
aof-user-rdb-preamble yes

进入 redis-cli ,使用 bgrewriteaof 触发 AOF 重写

bash
bgwriteaof