专业的JAVA编程教程与资源

网站首页 > java教程 正文

Java开发:Redis的持久化方式

temp10 2025-05-28 20:18:03 java教程 9 ℃ 0 评论

前言

Redis是一款基于内存的高性能缓存中间件,所有的数据都在内存中存储,所以性能比较高(当然这只是其中一个原因)。但是如果运行Redis的节点突然宕机,或者Redis本身出现故障,那么内存中的缓存数据将全部丢失,因此我们需要一种持久化机制来保证Redis的数据不会因为意外而丢失。而Redis为我们提供了两种持久化的方式:快照(RDB文件)追加式文件(AOF文件)

Java开发:Redis的持久化方式

一、RDB(Redis DataBase)

RDB持久化是在指定的时间间隔内将内存中的数据集快照写入磁盘。也是默认的持久化方式,这种方式是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。在我们安装了Redis之后,所有的配置都是在redis.conf文件中,里面保存了RDB和AOF两种持久化机制的各种配置。当符合一定条件时Redis会自动将内存中的数据进行快照并持久化到硬盘。

1.1触发时机

我们可以通过redis.conf配置文件配置触发的条件,还可以通过指令主动触发持久化的过程。

配置文件中配置触发规则

save 900 1

save 300 10

save 60 10000

配置解释:

900秒内,如果超过1个key被修改,则发起快照保存

300秒内,如果超过10个key被修改,则发起快照保存

60秒内,如果1万个key被修改,则发起快照保存

---- 可以自己修改成合适的数值

除了通过配置文件配置触发规则,也可以通过命令主动触发。

1)save:sava指令会阻塞Redis的主线程,所以一定要谨慎使用

2)bgsave:bg其实就是 background,表示后台的,所以bgsave可以理解为后台进行持久化操作,不会阻塞Redis的主进程。当执行这个命令的时候,Redis会fork出一个子进程,子进程在后台默默运行,不会阻塞主进程,这也是Redis默认使用的方式。

3)执行flushall命令也会生成dump.rdb文件,但是里面是空的。

4)客户端执行shutdown关闭Redis时,也会触发快照。

1.2bgsave的运行原理

这种方式是Redis使用RDB快照时默认采用的持久化方式,Redis的主线程会fork出来一个子进程,被fork出来的子进程会共享主进程内的所有内存数据。当这个子进程开启之后,会开始读取主进程内的数据,并把他们写入RDB文件中。也就是持久化的操作不会影响主进程的工作,这样可以提高效率。但是还有一种情况,就是如果主进程执行写入命令时,那么这一块儿数据就会被复制一份,然后主进程去修改原来的数据 ,子进程备份复制出来的数据副本,这个地方其实利用的是写时复制的思想。

1.3优缺点分析

优点

1)父进程fork出子进程之后不需要再做任何操作,所以持久化过程不会阻塞父进程的操作。需要注意的是,fork一个子进程出来是会阻塞主进程的,如果内存中数据量比较大的时候,fork花费的时间可能会变长,这点需要注意。

2)整个Redis数据库只包含一个文件,方便进行文件备份,适合大规模的数据恢复。

缺点

1)无法保证数据的高可用性,如果Redis在下一次持久化开始之前出现故障,那么就会丢失最近一次持久化到故障发生期间的所有数据。

2)如果数据相对来说比较重要,希望将损失降到最小,则可以使用AOF方式进行持久化。

二、AOF(Append Only File)

全量备份总是耗时的,Redis为我们提供了一种更加高效的持久化方式,即AOF(appendonlyfile)。此方式工作机制很简单,Redis会将每一个收到的写命令都通过write函数追加到文件中。默认情况下Redis没有开启AOF方式的持久化。

开启AOF持久化后,每执行一条会更改Redis中的数据的命令,Redis就会将该命令写入硬盘中的AOF文件,这一过程显然会降低Redis的性能,但大部分情况下这个影响是能够接受的,另外使用较快的硬盘可以提高AOF的性能。

2.1开启方式

# 可以通过修改redis.conf配置文件中的appendonly参数开启

appendonly yes

# AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的。

dir ./

# 默认的文件名是appendonly.aof,可以通过appendfilename参数修改

appendfilename appendonly.aof

2.2AOF 保存模式

Redis目前支持三种AOF保存模式,它们分别是:不保存、每秒钟保存一次、每执行一个命令保存一次。

可以修改以下配置项配置AOF的保存模式。

# appendfsync always

appendfsync everyse

AOF_FSYNC_NO(不保存):在这种模式下,每次调用ushAppendOnlyFile函数,WRITE都会被执行,但SAVE会被略过。在这种模式下,SAVE只会在以下情况中被执行:1.Redis被关闭;2.AOF功能被关闭;3.系统的写缓存被刷新(可能是缓存已经被写满,或者定期保存操作被执行)。这三种情况下的SAVE操作都会引起Redis主进程阻塞。

AOF_FSYNC_EVERYSEC(每一秒钟保存一次):在这种模式中,SAVE原则上每隔一秒钟就会执行一次,因为SAVE操作是由后台子线程调用的,所以它不会引起服务器主进程阻塞。

AOF_FSYNC_ALWAYS(每执行一个命令保存一次(不推荐)):在这种模式下,每次执行完一个命令之后,WRITE和SAVE都会被执行。另外,因为SAVE是由Redis主进程执行的,所以在SAVE执行期间,主进程会被阻塞,不能接受命令请求。

AOF保存模式对性能和安全性的影响

对于三种AOF保存模式,它们对服务器主进程的阻塞情况如下:

AOF_FSYNC_NO:写入和保存都由主进程执行,两个操作都会阻塞主进程。

AOF_FSYNC_EVERYSEC:写入操作由主进程执行,阻塞主进程。保存操作由子线程执行,不直接阻塞主进程,但保存操作完成的快慢会影响写入操作的阻塞时长。

AOF_FSYNC_ALWAYS:和AOF_FSYNC_NO模式一样。

因为阻塞操作会让Redis主进程无法持续处理请求,所以一般说来,阻塞操作执行得越少,完成得越快,Redis的性能就越好。

2.3AOF重写(瘦身)

AOF 持久化是通过保存被执行的写命令来记录数据库状态的,所以AOF文件的大小随着时间的流逝一定会越来越大。影响包括但不限于:对于Redis服务器,计算机的存储压力;AOF还原出数据库状态的时间增加。

为了解决AOF文件体积膨胀的问题,Redis提供了AOF重写功能:Redis服务器可以创建一个新的AOF文件来替代现有的AOF文件,新旧两个文件所保存的数据库状态是相同的,但是新的AOF文件不会包含任何浪费空间的冗余命令,通常体积会较旧AOF文件小很多。这个操作相当于对 AOF 文件“瘦身”。在重写的时候,是根据这个键值对当前的最新状态,为它生成对应的写入命令。这样一来,一个键值对在重写日志中只用一条命令就行了,而且,在日志恢复时,只用执行这条命令,就可以直接完成这个键值对的写入了。

2.4从 RDB 持久化切换到 AOF 持久化

在 Redis 2.2 或以上版本,可以在不重启的情况下,从 RDB 切换到 AOF :

  1. 为最新的 dump.rdb 文件创建一个备份。
  2. 将备份放到一个安全的地方。
  3. 执行以下两条命令:

redis-cli> CONFIG SET appendonly yes

redis-cli> CONFIG SET save ""

4. 确保命令执行之后,数据库的键的数量没有改变。

5. 确保写命令会被正确地追加到 AOF 文件的末尾。

步骤 3 执行的第一条命令开启了 AOF 功能:Redis 会阻塞直到初始 AOF 文件创建完成为止, 之后 Redis 会继续处理命令请求, 并开始将写入命令追加到 AOF 文件末尾。

步骤 3 执行的第二条命令用于关闭 RDB 功能。这一步是可选的, 如果你愿意的话, 也可以同时使用 RDB 和 AOF 这两种持久化功能。

别忘了在 redis.conf 中打开 AOF 功能!否则的话, 服务器重启之后, 之前通过 CONFIG SET 设置的配置就会被遗忘, 程序会按原来的配置来启动服务器。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表