一张图搞定redis持久化

2019-12-11  本文已影响0人  心似南风
redis持久化.png

一、Redis持久化概述

持久化的功能:Redis是内存数据库,数据都是存储在内存中,为了避免进程退出导致数据的永久丢失,需要定期将Redis中的数据以某种形式(数据或命令) 从内存保存到硬盘。 当下次Redis重启时,利用持久化文件实现数据恢复。除此之外,为了进行灾难备份,可以将持久化文件拷贝到一个远程位置。Redis持久化 分为RDB持久化和AOF持久化,前者将当前数据保存到硬盘,后者则是将每次执行的写命令保存到硬盘。

1.1 RDB

RDB是一种快照存储持久化方式,具体就是将Redis某一时刻的内存数据保存到硬盘的文件当中,默认保存的文件名为dump.rdb,而在Redis服务器启动时,会 重新加载dump.rdb文件的数据到内存当中恢复数据。 ,触发 RDB 持久化过程分为手动触发和自动触发。

1.2 触发机制

手动触发分别对应 save 和 bgsave 命令:

除了执行命令手动触发之外,Redis 内部还存在自动触发 RDB 的持久化机制,例如以下场景:

  1. 使用 save 相关配置,如“save m n”。表示 m 秒内数据集存在 n 次修改时,自动触发 bgsave。
  2. 如果从节点执行全量复制操作,主节点自动执行 bgsave 生成 RDB 文件并发送给从节点。
  3. 执行 debug reload 命令重新加载 Redis 时,也会自动触发 save 操作。
  4. 默认情况下执行 shutdown 命令时,如果没有开启 AOF 持久化功能则自动执行 bgsave。

1.3 流程说明

bgsave 是主流的触发 RDB 持久化方式,根据下图了解它的运作流程


bgsave流程说明.png

流程解析:

  1. 执行bgsave命令:Redis父进程判断当前是否存在正在执行的子进程,如RDB/AOF子进程,如果存在bgsave命令直接返回。
  2. 父进程执行fork操作创建子进程,fork操作过程中父进程会阻塞,通过info stats命令查看 latest_fork_usec 选项,可以获取最近一 个 fork 操作的耗时,单位为微秒。
  3. 父进程 fork 完成后,bgsave 命令返回“Background saving started”信息并不再阻塞父进程,可以继续响应其他命令。
  4. 子进程创建 RDB 文件,根据父进程内存生成临时快照文件,完成后对原有文件进行原子替换。执行 lastsave 命令可以获取最后一次生成 RDB 的时间,对应 info 统计的 rdb_last_save_time 选项。
  5. 进程发送信号给父进程表示完成,父进程更新统计信息,具体见 info Persistence 下的 rdb_* 相关选项。

1.4、服务器配置自动触发

除了通过客户端发送命令外,还有一种方式,就是在Redis配置文件中的save指定到达触发RDB持久化的条件,比如【多少秒内至少达到多少写操作】就 开启RDB数据同步。
例如我们可以在配置文件redis.conf指定如下的选项:

这种通过服务器配置文件触发RDB的方式,与bgsave命令类似,达到触发条件时,会forks一个子进程进行数据同步, 不过最好不要通过这方式来触发RDB持久 化,因为设置触发的时间太短,则容易频繁写入rdb文件,影响服务器性能, 时间设置太长则会造成数据丢失。

1.5、RDB文件的处理

  1. 保存:
    RDB 文件保存在 dir 配置指定的目录下,文件名通过 dbfilename 配置指定。可以通过执行 config set dir{newDir}config set dbfilename{newFileName}运行期动态执行,当下次运行时 RDB 文件会保存到新目录。
    当遇到坏盘或磁盘写满等情况时,可以通过 config set dir{newDir}在线修改文件路径到可用的磁盘路径,之后执行 bgsave 进行磁盘切换,同样适
    用于 AOF 持久化文件

1.6、RDB 方式的优缺点

1.7、 RDB 的缺点

  1. RDB 方式数据没办法做到实时持久化/秒级持久化
    如果服务器宕机的话,采用RDB的方式会造成某个时段内数据的丢失,比如我们设置10分钟同步一次或5分钟达到1000次写入就同步一次,那么如果还没达到触发条件服务器就死机了,那么这个时间段的数据会丢失。
  2. 使用bgsave命令在forks子进程时,如果数据量太大,forks的过程也会发生阻塞,另外,forks子进程会耗费内存。针对 RDB 不适合实时持久化的问题,Redis 提供了 AOF 持久化方式来解决。

二、AOF

AOF(append only file)持久化:与RDB存储某个时刻的快照不同,AOF持久化方式会记录客户端对服务器的每一次写操作命令到日志当中,并将这些写操作
以Redis协议追加保存到以后缀为aof文件末尾

2.1 使用AOF

2.2 配置说明

appendonly yes启用aof持久化方式
appendfsync always每次收到写命令就立即强制写入磁盘,最慢的大概只有几百的TPS,但是保证完全的持久化,不推荐使用
appendfsync everysec每秒中强制写入磁盘一次,在性能和持久化方面做了很好的折中,推荐
appendfsync no完全依赖os,性能最好,持久化没保证,Redis不会主动调用fsync去将AOF日志内容同步到磁盘,所以这一切就完全依赖于操作的系统调试了,对大多数Linux操作系统,是每30秒进行,几乎不使用。

2.3、工作流程说明

工作流程说明.png

流程如下:

  1. 所有的写入命令会追加到 aof_buf(缓冲区)中。
  2. AOF 缓冲区根据对应的策略向硬盘做同步操作。
  3. 随着 AOF 文件越来越大,需要定期对 AOF 文件进行重写,达到压缩的目的。
  4. 当 Redis 服务器重启时,可以加载 AOF 文件进行数据恢复。

2.3.1、重写机制说明

2.4 触发机制

AOF 重写过程可以手动触发和自动触发:

  1. 执行AOF重写请求。如果当前进程正在执行AOF重写,请求不执行并返回如下响应,ERR Background append only file rewriting already in progress
  2. 父进程执行fork创建子进程, 开销等于同于bgsave过程。

3.1 主进程fork操作完成后,继续响应其他命令,所有修改命令依然写入AOF缓冲区并根据appendfsync策略同步到硬盘,保证原有AOF机制的正确性。

3.2 由于 fork 操作运用写时复制技术,子进程只能共享 fork 操作时的内存数据。由于父进程依然响应命令,Redis 使用“AOF 重写缓冲区”保存这部 分新数据,防止新 AOF 文件生成期间丢失这部分数据。

  1. 子进程根据内存快照,按照命令合并规则写入到新的 AOF 文件。每次批量写入硬盘数据量由配置 aof-rewrite-incremental-fsync 控制,默认为 32MB,防止单 次刷盘数据过多造成硬盘阻塞
    4.1 新 AOF 文件写入完成后,子进程发送信号给父进程,父进程更新统计信息,具体见 info persistence 下的 aof_*相关统计。
    4.2 父进程把 AOF 重写缓冲区的数据写入到新的 AOF 文件。
    4.3 使用新 AOF 文件替换老文件,完成 AOF 重写。

2.5 AOF注意事项

1.AOF文件损坏
在写入aof日志文件时,如果redis服务器宕机,则aof日志文件会出格式错误,在重启Redis服务器时,Redis服务器会拒绝载入这个aof文件,可以通过命令修复aof并恢复数据。
redis-check-aof -fix file.aof

2.6、AOF的优缺点

2.6.1、AOF的优点

  1. AOF可以设置完全不同步、每秒同步、每次操作同步。因为aof时操作指令的追加,所以可以频繁的大量同步。
  2. AOF文件是一个值追加日志的文件,即使服务宕机未写入完整的命令,也可以通过redis-check-aof工具修复这些问题。
  3. 如果AOF文件过大,Redis会在后台自动地重写AOF文件。重写后会使AOF文件压缩到最小所需的指令集。
  4. AOF文件是有序保存数据库的所有写入操作,易读,易分析。即使如果不小心误操作数据库,也很容易找出错误指令,恢复到某个数据节点。例如不小心FLUSHALL,可以非常容易恢复到执行命令之前。

2.6.2、AOF的缺点

  1. 相同数据量下,AOF的文件通常体积会比RDB大,因为AOF时存指令的,而RDB时所有指令的结果快照。但AOF在日志重写后会压缩一些空间。
  2. 在大量写入和载入的时候,AOF的效率会比RDB低。因为大量写入,AOF会执行更多的保存命令,载入的时候也需要大量的执行命令来得到最后的结果。RDB对此更有优势。

2.7、重启加载的选择

AOF 和 RDB文件都可以用于服务器重启时的数据恢复


重启加载的选择.png

2.8、持久化的选择

  1. 如果redis中的数据完全丢弃也没有关系(如Redis完全用作DB层数据的cache),那么无论是单机,还是主从架构,都可以不进行任何持久化。
  2. 在单机环境下(对于个人开发者,这种情况可能比较常见),如果可以接受十几分钟或更多的数据丢失,选择RDB对Redis的性能更加有利;如果只能接受秒级别的数据丢失,应该选择AOF。
  3. 但在大多数情况下,我们都会配置主从环境,slave的存在既可以实现数据的热备,也可以进行读写分离分担Redis读请求,以及在master宕掉后继续提供服务。
    在这种情况下的做法是:
  1. 异地灾备:上述讨论的几种持久化策略,针对的都是一般的系统故障,如进程异常退出、宕机、断电等,这些故障不会损坏硬盘。但是对于一些可能导致硬盘损坏的灾难情况,如火灾地震,就需要进行异地灾备。

注意

  1. RDB虽然可以通过bgsave指令后台保存快照,但fork()子进程是有开销的,在内存数据集较大的情况下会占用很长的cpu时间,fork新进程时这个复制是需要时间的,在服务器结点上测试,35G的数据bgsave瞬间会阻塞200ms以上,一般建议Redis使用内存不超过20g。
  2. I/O消耗的问题
    线上是在Slave节点开启rdb持久化,磁盘性能一般,1.2g的rdb文件持久化一分钟一次,
    一次大概耗时30s左右,所以rdb的频率也不能太频繁,需要根据情况做好配置。
  3. AOF是追加写命令到aof文件的方式,优点是可以基本做到数据无损,缺点是文件增长较快,需要间歇性bgrewritebgrewrite也是一个既耗cpu又耗磁盘IO的操作,
    单cpu利用率最高可达100%,一般建议找几个空闲时段设置脚本来做bgrewrite

2.9、持久化配置方案

  1. 企业级的持久化的配置策略
  1. 数据备份方案
    RDB非常适合做冷备,每次生成之后,就不会再有修改了
    数据备份方案
    (1)写crontab定时调度脚本去做数据备份
    (2)每小时都copy一份rdb的备份,到一个目录中去,仅仅保留最近48小时的备份
    (3)每天都保留一份当日的rdb的备份,到一个目录中去,仅仅保留最近1个月的备份
    (4)每次copy备份的时候,都把太旧的备份给删了
    (5)每天晚上将当前服务器上所有的数据备份,发送一份到远程的云服务上去【crontab】
    2.8、AOF常用配置总结
上一篇 下一篇

猜你喜欢

热点阅读