自学内容网 自学内容网

Redis 持久化

Redis 存储数据时,对于同一份数据,分别在内存和硬盘上都进行了存储,当查询某个数据时,直接从内存中读取,硬盘的数据用来在 Redis 重启时恢复内存中的数据,Redis 提供了两种内存持久化的策略

1. RDB 持久化策略

定期备份,会在指定的时间间隔内,将内存中的数据集快照写入磁盘,

1.1. 手动触发

“定期”可以手动触发,通过 Redis 客户端,执行save命令或者bgsave命令来触发快照生成,不过执行save命令时,Redis 会集中处理快照,就会阻塞其它命令,而bgsave就不会影响Redis 服务器处理其它请求和命令,此时采用的是一种“多进程”的方式来完成的

  1. 首先,执行bgsave命令之后,Redis 父进程会判断当前进程是否存在其他正在执行的子进程,如 RDB/AOF 子进程,如果存在就直接返回,不存在的话就执行fork创建子进程,fork 过程中父进程会阻塞
  2. 当父进程 fork 完成后,不再阻塞父进程,可以执行其他命令
  3. 子进程创建 RDB 文件,根据父进程内存生成临时快照文件,完成后对原有文件进行原子替换
  4. 进程发送信号给父进程表示完成,父进程更新统计信息

由于 fork 采用的是“写时拷贝”的策略,所以在进行 bgsave 的过程中,绝大部分数据时不需要改变的,整体来说拷贝过程也挺快

而 Redis 生成的 RDB 文件是存放在 Redis 的工作目录中的,也可以在配置文件中找到该路径

切换到该目录之后就能找到 rdb 文件了

执行 RDB 镜像操作时,会把生成的快照数据先保存在一个临时文件中,当这个快照生成完毕之后,再把原来的 rdb 文件删除,然后更新临时文件的名称为 dump.rdb,如果是save命令就直接在当前进程中往同一个文件中写入数据了

需要注意的是 dump.rdb 文件不能随便修改,可能会使 Redis 无法正常启动

通过执行 redis-check-rdb dump.rdb可以检查格式是否有误

通过手动输入命令bgsave的方式来生成快照:

1.2. 自动触发

除了手动,也可以自动触发,通过 shutdown 命令关闭 Redis 服务器时会触发自动生成快照,进行主从复制的时候,主节点也会自动生成 rdb 快照,然后把 rdb 快照内容传输给从节点,所以说,在正常关闭 Redis 服务器时会触发生成 rdb,如果是异常重启,例如 kill -9 或者服务器掉电这样的情况就不会触发,也就会丢失当前没有存储快照的数据

此外,在 Redis 的配置文件中也可以配置一些 Redis 自动触发快照的条件:

这里表示需要满足过 900 秒,并且修改 1 次才会自动触发,如果设置为 save ""表示取消自动触发

如果修改配置文件之后,重启客户端配置才会生效

2. AOF 持久化策略

由于 RDB 采用的是定时备份的策略,所以两次快照之间的数据就可能会丢失,而 AOF 采用的是实时备份的策略。

修改配置文件中的 appendonly 为 yes 就能够开启 AOF

之后每次进行的操作都会被记录到 appendonly.aof 文本文件中,当 redis 服务器异常关闭,再次启动时也能通过读取 appendonly.aof 文件进行恢复

2.1. 写入流程

采用 AOF 之后,redis 既需要写硬盘,有需要写内存,但也并不会对性能有过大的影响,AOF 采用的是先把数据写入内存缓冲区,积累到一定数量时再统一写入硬盘,也就大大减少了写入硬盘的次数

但是,当面的策略也存在一个问题,当数据在缓冲区中没来的及写入内存时,Redis 服务器出现问题了,那么次数缓冲区的数据就丢失了,所以控制缓冲区的刷新频率就很有必要了,Redis 中提供了三种不同的刷新缓冲区策略:

策略

含义

特点

appendfsync always

每次执行写命令后都立即将 AOF 缓冲区中的内容刷新到磁盘

数据安全性最高,Redis 性能最低

appendfsync everysec

每秒将 AOF 缓冲区中的内容刷新到磁盘一次

在性能和数据安全性之间做了一个较好的平衡

appendfsync no

由操作系统决定何时将 AOF 缓冲区中的内容刷新到磁盘

数据安全性最低

2.2. 重写机制

由于 aof 文件是记录每一次的操作的,所以会持续增长,增长到一定大小就会影响 Redis 下一次启动的时间,对于一些操作的记录其实也可以进行合并,所以存在很多不必要的记录

重写的时候就是把当前内存中的数据获取出来,以 AOF 的格式写入到一个新的 AOF 文件中,也就是记录一次结果状态,也就类似于 RDB 生成的快照,只不过 RDB 那里是按照二进制来生成的,AOF 重写是按照文本格式来生成的

在重写的时,还是会 fork 一个新的进程,父进程还继续接收客户端新的请求,继续把这些请求产生的 AOF 数据先写入到缓冲区,再刷新到原有的 AOF 文件里,只不过父进程又准备了一个 aof_rewrite_buf 缓冲区,专门用来存放 fork 之后接收到的数据,子进程把 AOF 数据写完之后,父进程再把 aof_rewrite_buf 缓冲区中的内容也写入到新的 AOF 文件中,然后替换到原来的 AOF 文件

如果在执行bgrewriteaof时,发现 Redis 正在进行 AOF 重写,就会直接返回,如果 Redis 正在生成 rdb 文件的快照,AOF 重写操作就会阻塞,快照生成完毕再执行重写

3. 混合持久化

在配置文件中 aof-use-rdb-preamble yes表示开启混合持久化

执行bgrewriteaof之后再来看 appendonly.aof 文件,发现存储的结果变味了和 rdb 文件一样的二进制

是因为此时采用了“混合持久化”的方式,也就是按照 aof 的方式,把每一个操作都记录到文件中,在触发 aof 重写时,就会把当前的内存状态按照 rdb 的二进制格式写入到新的 aof 文件中,之后再存储就还是原来的 aof 文本格式


原文地址:https://blog.csdn.net/2202_76097976/article/details/145512317

免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!