当前位置:网站首页>Redis persistence mechanism

Redis persistence mechanism

2022-08-10 19:02:00 murmur silently


概述

Redis The official provides two different persistence methods to store data to hard disk,分别是:

  • 快照(Snapshot)
  • AOF(Append Only File)只追加日志文件

Snapshots are enabled by default,When both persistence methods are enabled at the same time,优先 AOF


快照(Snapshot)

In this way, all data at a certain moment can be written to the hard disk,保存的文件以 .rdb 形式结尾的文件,因此也称 RDB 方式

1. 快照生成方式

1.1 客户端方式

Redis 提供了两个命令来生成 RDB 文件,分别是 savebgsave,他们的区别就在于:save 在「主进程」执行,有可能阻塞「主进程」,而 bgsave 会创建一个「子进程」执行

1.2 服务器配置
save 3600 1 300 100 60 10000

上述是 redis.conf 中的相关内容,需要注意的点有两个:

  • 如果配置 save "" Snapshots can be disabled entirely
  • redis Snapshots are enabled by default,And the default configuration is as follows:save 3600 1 300 100 60 10000,它的意思是,As long as any one of the following conditions is met,就会执行 bgsave
    • 3600 秒(1 小时)之内,对数据库进行了至少 1 次修改
    • 300 秒(5 分钟)之内,对数据库进行了至少 100 次修改
    • 60 秒之内,对数据库进行了至少 10000 次修改

If we want to customize the snapshot generation frequency,Just modify it according to the template

2. 保存快照

# rdb快照文件名
dbfilename dump.rdb
# rdb快照文件存放目录,请确保有写权限
dir ./

3. 其他相关配置

# 默认使用bgsave持久化时,如果发生错误,will stop writingRDB快照文件,It is sometimes difficult for users to realize that the data is not persisted correctly
# 如果你已经设置了对RedisProper monitoring of services,Consider turning this feature off,Errors are allowed to be ignored,继续写RDB快照文件
# yes:开启 no:关闭
stop-writes-on-bgsave-error yes
# 是否使用LZF压缩字符串对象,一般建议开启
# yes:开启 no:关闭
rdbcompression yes
# 在写入和读取RDBCheck the file for corruption
# yes:开启 no:关闭
rdbchecksum yes
# 加载RDB或还原负载时,启用或禁用ziplist和listpackWait for complete disinfection to check
# yes:检查 no:不检查 clients:Checks are performed only on user connections
sanitize-dump-payload no
# 在未启用持久性的实例中删除复制使用的RDB文件,默认情况下此选项处于禁用状态
# This is only available if both are disabledAOF和RDB持久性的实例,否则将完全忽略
rdb-del-sync-files no

4. bgsave 执行原理

当接收到 bgsave 命令时,redis 会调用 fork 创建一个子进程,子进程负责将快照写入磁盘,The parent process continues to process the command

The parent process can continue executing commands,That is, the data can be modified,The key is to use it「写时复制技术」,通过 fork 创建的子进程,Share the same piece of memory data with the parent process,The child process copies the page tables of the parent process,But the physical memory pointed to by the page table is still the same,This is to speed up the creation of child processes,所以,The child process can directly read the memory data of the main process,并写入 RDB 文件

When the main process is only a read-only operation on the shared data,Then the child process and the parent process do not affect each other,But if the main process wants to modify an item of shared data,就会发生写时复制,这块数据会被复制一份,The master process then makes modifications on that copy,子进程继续把原来的数据写入 RDB 文件,也就是说,The data just modified by the main process,是没办法在这一时间写入 RDB 文件的,只能交由下一次的 bgsave 快照

5. 自动触发

除了上述的方式以外,Snapshots are also automatically generated in the following situations:

  • 主从复制时,Triggered when the slave node is fully replicating from the master node bgsave 操作,生成当时的快照发送到从节点
  • 执行 debug reload 命令重新加载 redis 时会触发 bgsave 操作
  • 执行 shutdown 命令时,如果没有开启 aof 持久化,会触发 bgsave 操作

只追加日志文件(Append Only File)

这种方式可以将所有客户端执行的写命令记录到日志文件中,This records the changes in the data.只要 Redis 从头到尾执行一次 AOF 文件所包含的所有写命令,就可以恢复 AOF 文件的记录的数据集

1. 触发 AOF 持久化

redis The default configuration is not enabled AOF 持久化机制,需要在 redis.conf 开启

# yes:开启AOF持久化 no:关闭AOF持久化
appendonly yes
# 指定生成AOF文件名称
appendfilename "appendonly.aof"
# 指定存储AOF文件的文件夹名称
appenddirname "appendonlydir"
# AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置
dir ./

从 Redis7 版本开始,使用一组 aof 文件记录数据,There are two basic types:

  1. 基本文件,Represents the complete data when the file was created,可以是 rdb 或 aof 内容格式
  2. 增量文件,Records new commands after the previous file
  3. 清单文件,Track the order in which files are created and used

文件名是以 appendfilename 前缀,Followed by the sequence number and type,因此 aof The files generated in the file directory are probably there:

  1. 基本文件 appendonly.aof.1.base.rdb
  2. 增量文件 appendonly.aof.1.incr.aof,appendonly.aof.2.incr.aof......
  3. 清单文件 appendonly.aof.manifest

2. 写回策略

Redis Is to execute the write operation command first,Record the command again AOF 日志,Only the write operation command executes successfully,才会进行记录,Both operations are performed on the main thread,will occupy the disk I/O,因此 AOF The timing at which the log is written back to disk is important

There are three writeback strategies:

  • always(谨慎使用):每条 Redis 操作命令都会写入磁盘,最多丢失一条数据
  • everysec(默认):每秒钟写入一次磁盘,最多丢失一秒的数据
  • no(不推荐):It is up to the operating system to decide when to write to disk,Linux 默认 30s 写入一次数据至磁盘

配置项如下:

appendfsync everysec

As for how these three strategies are implemented,It's actually just in control fsync() 函数的调用时机

当应用程序向文件写入数据时,内核通常先将数据复制到内核缓冲区中,然后排入队列,然后由内核决定何时写入硬盘

如果想要应用程序向文件写入数据后,能立马将数据同步到硬盘,就可以调用 fsync() 函数,这样内核就会将内核缓冲区的数据直接写入到硬盘,等到硬盘写操作完成后,该函数才会返回

  • Always 策略就是每次写入 AOF 文件数据后,就执行 fsync() 函数
  • Everysec 策略就会创建一个异步任务来执行 fsync() 函数
  • No 策略就是永不执行 fsync() 函数

3. 重写 AOF 文件

AOF The persistence mechanism records every write command,因此 AOF 文件会越来越大,会影响数据恢复的效率.AOF File rewrite will rewrite the database contents in memory to a new one by command aof 文件,替换原有文件,减小 aof 文件体积

3.1 触发重写的方式

第一种方式:客户端执行 BGREWRITEAOF 命令触发重写,不会阻塞 redis 服务

第二种方式:Automatic triggering in server configuration

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

如上配置,启用 AOF 持久化后,当 AOF 文件体积大于 64 M,并且 AOF When the file size is at least double the size since the last rewrite,会自动触发重写

指定百分比为 0 Automatic can be disabled AOF 重写

auto-aof-rewrite-percentage 0
3.2 重写流程

  1. bgrewriteaof 触发重写,判断是否当前有 bgsave 或 bgrewriteaof 在运行,如果有,则等待该命令结束后再继续执行
  2. 主进程 fork 出子进程执行重写操作,保证主进程不会阻塞
  3. 子进程遍历 redis 内存中数据到临时文件,客户端的写请求同时写入 aof_buf 缓冲区和 aof_rewrite_buf 重写缓冲区,保证原 AOF 文件完整以及新 AOF 文件生成期间的新的数据修改动作不会丢失
  4. 子进程写完新的 AOF 文件后,向主进程发信号,父进程更新统计信息.主进程把 aof_rewrite_buf 中的数据写入到新的 AOF 文件
  5. 使用新的 AOF 文件覆盖旧的 AOF 文件,完成 AOF 重写

4. 其他配置

# 前面讲过,AOF是调用fsync()The function writes a record of write operations back to disk,This will take up a certain amount of diskI/O
# 如果设为yes,相当于appendfsync no,Writes to disk will not be performed,只是写入缓冲区,缓解磁盘压力
no-appendfsync-on-rewrite no
# 在Redis启动过程中,当AOF数据重新加载回内存时,可能会发现AOF文件在最后被截断
# 如果设置为yes,则加载一个截断的AOF文件,And tell the user about the event through the log
# 如果设置为no,服务器将因错误而中止并拒绝启动,用户需要使用“redis-check-aof”实用程序修复AOF文件
aof-load-truncated yes
# 开启混合持久化,下面会提到
aof-use-rdb-preamble yes
# 支持在aofTimestamps are recorded in,Data can be recovered at a specific time,但会改变aof格式,Possibly something that already existsaof文件不兼容
aof-timestamp-enabled no

RDB 和 AOF 混合方式

Redis4.0 提出了一个混合使用 AOF 日志和内存快照的方法,混合持久化同样也是通过 bgrewriteaof 重写命令完成的,不同的是,When hybrid persistence is turned on,fork 出的子进程先将共享的内存副本全量的以 RDB 方式写入 aof 文件,然后在将重写缓冲区的增量命令以 AOF 方式写入到文件,写入完成后通知主进程更新统计信息,并将新的含有 RDB 格式和 AOF 格式的 AOF 文件替换旧的的 AOF 文件

配置如下:

aof-use-rdb-preamble yes

备份数据

备份 RDB Just copy it to a safe place,Server runtime replication RDB Documents are safe,因为 RDB Once the file is created, it will not be modified

备份 AOF 在 Redis7.0.0 It can also be copied directly before,但 7.0.0 The version will be there later aof 文件夹下有多个文件,在 aof Copying while overwriting may result in unusable files,So it needs to be closed when backing up aof 重写,步骤:

  • 关闭自动 aof 重写:CONFIG SET auto-aof-rewrite-percentage 0
  • Make sure there are no manuals during this time BGREWRITEAOF 启动重写
  • Check if rewriting is in progress,查询 INFO persistence,如果返回1,Then you have to wait for the rewrite to complete
  • 将 aof Copy the folder to a safe place
  • Turn back on automatically aof 重写:CONFIG SET auto-aof-rewrite-percentage <prev-value>

原网站

版权声明
本文为[murmur silently]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/222/202208101832512998.html