Redis 提供了两种持久化方式,即 RDB(Redis Database)和 AOF(Append-Only File)。
RDB 持久化是 Redis 的默认持久化方式。它将 Redis 的数据集以二进制格式保存到磁盘上的一个文件中。RDB 持久化适用于执行周期性备份的场景。RDB 文件是通过压缩(可以配置 rdbcompression 参数禁用压缩以节省 CPU 资源)的二进制格式,更加紧凑以节省空间。
Redis 会默认将备份的快照文件存储在 Redis 当前进程工作目录中的 dump.rbd 文件中,可以配置 dir 和 dirfilename 两个参数分别指定快照的存储路径和文件名。
创建快照的步骤:
在执行 fork 函数时,类 unix 操作系统会使用写时拷贝策略。所以新的 RDB 文件存储的时执行 fork 函数那一刻的内存数据。 关于写时拷贝(Copy-On-Write,COW) 在使用写时拷贝的情况下,当多个进程或线程共享同一份内存数据时,它们实际上共享同一个物理内存页。这意味着在一开始,这些进程或线程都指向相同的内存页。当其中一个进程或线程尝试修改这个共享的内存页时,才会进行实际的拷贝操作。这个操作会将要修改的内存页复制一份,使得修改操作只影响到修改操作的那个进程或线程,而不会影响其他共享该内存页的进程或线程。 写时拷贝的优点是在数据没有发生写操作之前,多个进程或线程可以共享同一份内存数据,避免了不必要的内存复制。这对于需要共享大量数据或频繁进行复制操作的情况下,可以提高性能和节省内存空间。
在 Redis 中,可以通过在配置文件中设置 save指令来配置自动触发快照的规则。save指令的格式如下:
save <seconds> <changes>其中,<seconds>表示时间间隔,单位是秒,指定了多长时间内如果发生了至少 <changes> 次修改操作,则触发快照。
例如,以下是一些示例配置规则:
save 900 1 # 如果在900秒(15分钟)内至少有1个键被修改,则触发快照
save 60 10000 # 如果在60秒内至少有10000个键被修改,则触发快照
save 300 5 # 如果在300秒(5分钟)内至少有5个键被修改,则触发快照在上述示例中,Redis 会根据指定的时间间隔和修改次数来判断是否触发快照生成。当满足任意一个配置规则时,Redis 将自动执行快照操作。
需要注意的是,配置多个 save指令会形成一个规则列表。当 Redis 执行快照时,会按照规则列表的顺序进行判断。因此,应该将频率较低、更保守的规则放在列表的前面,而将频率较高、更宽松的规则放在列表的后面。
当执行 SAVE命令时,Redis 会阻塞主进程,将数据集以二进制格式保存到磁盘上的一个 RDB 文件中。在生成快照期间,Redis 不能处理其他命令请求,直到快照过程完成。
SAVE命令在快照生成期间对 Redis 的性能会有一定的影响,因此,不建议在生产环境中使用 SAVE,一般情况下建议使用 BGSAVE命令进行快照生成。
BGSAVE命令用于在后台异步执行生成 Redis 快照。当执行 BGSAVE命令时,Redis 会启动一个子进程来生成快照,而不会阻塞主进程。在子进程生成快照的同时,Redis 主进程可以继续处理其他命令请求。
LASTSAVE命令用于获取最后一次生成快照的时间戳。执行 LASTSAVE命令后,Redis 会返回一个表示最后一次生成快照时间的 UNIX 时间戳。
执行 FLUSHALL命令将删除当前正在使用的所有数据库中的所有键值对。这个命令会导致所有数据被永久删除。FLUSHALL命令是一个原子操作,即要么全部清空成功,要么全部失败。在执行期间,Redis 将阻塞其他命令的执行。
如果当前配置了自动快照条件,那么不论清空过程是否达到快照条件,都会进行快照。
关于主从模式和复制的内容应该单独讲,所以这里就不讨论了
AOF 持久化以日志的形式记录 Redis 服务器所执行的写操作,将这些写操作追加到文件的末尾。当 Redis 重新启动时,可以通过重新执行这些写操作来还原数据集。在配置文件中找到 appendonly 的配置项,配置 appendonly yes 启用配置。
AOF 文件是一个文本文件,其中包含了 Redis 接收到的每个写操作的命令。每个命令都以 Redis 协议格式进行编码,并追加到 AOF 文件的末尾。
下面是一个示例,展示了在 AOF 文件中可能包含的命令:
*3\r\n$3\r\nSET\r\n$5\r\nmykey\r\n$7\r\nmyvalue\r\n
*2\r\n$3\r\nGET\r\n$5\r\nmykey\r\n
*4\r\n$4\r\nHMSET\r\n$6\r\nmyhash\r\n$2\r\na1\r\n$3\r\nval\r\n$2\r\na2\r\n$3\r\n123\r\n每个命令由多个部分组成,以 \r\n(CRLF)作为分隔符。以下是命令的结构:
*3\r\n:表示命令由三个参数组成。$3\r\nSET\r\n:表示第一个参数是字符串,长度为 3,值为”SET”。$5\r\nmykey\r\n:表示第二个参数是字符串,长度为 5,值为”mykey”。$7\r\nmyvalue\r\n:表示第三个参数是字符串,长度为 7,值为”myvalue”。在 AOF 文件中,每个命令都按照此格式(redis 的通信协议格式)记录。当 Redis 重新启动时,它会逐行读取 AOF 文件中的命令,并将其重新执行,以还原数据。
需要注意的是,AOF 文件是追加写入的,因此它会随着每个新的写操作而增长。为了保护数据的完整性,可以根据需要选择合适的 AOF 同步策略,确保将写操作同步到磁盘。
如果有这样三条命令,实际上对于恢复数据来讲,前两条记录是无用的。随着执行的命令越来越多,AOF 文件也越来越大,即使内存中的数据可能并不多。
SET key 1
SET key 2
SET key 3redis 能够自动优化 AOF 文件,每当达到一定条件 redis 就会重写 AOF 文件,这个条件可以在配置文件中配置:
1、auto-aof-rewrite-percentage:该配置项表示当AOF文件的大小超过上一次AOF重写(如果没有重写则以启动时大小为标准)之后的大小的一定百分比时,Redis会自动触发AOF重写。默认值为100,即AOF文件大小超过上一次重写大小的100%时触发重写。
2、auto-aof-rewrite-min-size:该配置项表示当AOF文件的大小超过一定字节数时,Redis会自动触发AOF重写,无论是否超过了上一次AOF重写之后的大小。默认值为64MB。AOF 重写通过读取当前数据集的内存状态,并以更紧凑的方式重新写入 AOF 文件,去除了冗余的命令和操作。AOF 重写不会影响正在运行的 Redis 实例的正常操作,它是在后台进行的。
AOF 重写的过程如下:
事实上,由于 IO 缓存机制,进程的 IO 操作并不会立马体现在磁盘内容上。操作系统会将 IO 操作中的数据暂时存储在内存中的缓存中,并在适当的时机将其刷新到磁盘上。IO 缓存的存在可以提高 IO 性能,因为内存中的读取和写入比磁盘访问要快得多。通过将多个 IO 操作合并成更大的块,可以减少磁盘访问的次数,从而提高效率。这种方式下,进程可以更快地完成 IO 操作并继续执行后续的任务。
然而,IO 缓存也引入了数据持久性和一致性的问题。如果系统发生故障(如断电),尚未刷新到磁盘的缓存数据可能会丢失。这种情况造成的损失对于使用 redis 写入 AOF 文件实现持久化的应用时无法容忍的,这就需要 redis 再写入 AOF 文件后立即将缓存同步到磁盘中。
在 redis 中, appendfsync配置项用于控制 AOF(Append-Only File)文件的同步策略,即何时将 AOF 缓冲区的数据同步到磁盘。
在配置文件中,有三个可选的 appendfsync选项:
appendfsync always:表示每次执行写操作时都会将 AOF 缓冲区的数据立即同步到磁盘。这是最安全的选项,因为它可以确保每个写操作都持久化到磁盘,但也会对性能产生较大的影响,因为每次写操作都需要等待磁盘的响应。appendfsync everysec:表示每秒将 AOF 缓冲区的数据同步到磁盘一次。这是默认的选项,它在性能和数据安全之间取得了一种平衡。Redis 会将 AOF 缓冲区的数据积累到一定程度,然后每秒同步一次到磁盘,这样可以提高性能并保证一定程度的数据持久化。appendfsync no:表示完全依赖操作系统进行数据同步,即不强制要求将 AOF 缓冲区的数据立即同步到磁盘。这是最高性能的选项,因为写操作不会等待磁盘的响应,但也是最不安全的选项,因为在发生系统崩溃等情况时可能会导致数据丢失。操作系统提供了同步写(synchronous write)和异步写(asynchronous write)两种方式。
因此,在涉及到数据持久性和一致性的场景中,可以根据需求选择合适的同步或异步写模式,以平衡性能和数据可靠性的需求。
可以同时使用 RDB 和 AOF 来进行持久化。
同时启用 RDB 和 AOF,Redis 可以将数据保存到磁盘上的两个不同文件中。RDB 会定期创建快照,将内存中的数据保存到磁盘上的 RDB 文件中,而 AOF 会记录每个写操作的指令,将其追加到 AOF 文件中。
同时使用 RDB 和 AOF 的好处包括:
------本页内容已结束,喜欢请分享------