redis持久化

作者: 打伞的Fish | 来源:发表于2018-06-24 11:14 被阅读31次

通读文章你会知道如下:

  • redis持久化的方式有哪些?
  • RDB和AOF两者的区别
  • RDB持久化的流程是怎么进行的?
  • AOF持久化方式如何开启?文件的同步策略有哪些,各自代表什么含义?
  • AOF的重写机制执行过程是怎么样的?
  • 持久化方式对系统的内存,硬盘和CPU各自会产生什么问题,有什么优化的方式?

1.RDB持久化方式

  • 含义:RDB持久化是把当前进程数据生成快照保存到硬盘的过程
    bgsave命令: Redis进程执行fork操作创建子进程, RDB持久化过程由子进程负责, 完成后自动结束。 阻塞只发生在fork阶段, 一般时间很短
  • 自动触发RDB持久化机制执行情况
    1. 使用save相关配置, 如“save m n”。 表示m秒内数据集存在n次修改 时, 自动触发bgsave。
    2. 如果从节点执行全量复制操作, 主节点自动执行bgsave生成RDB文件并发送给从节点
    3. 执行debug reload命令重新加载Redis时, 也会自动触发save操作。
    4. 默认情况下执行shutdown命令时, 如果没有开启AOF持久化功能则 自动执行bgsave
  • bgsave命令运行流程
bigsave命令执行流程
  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_*相关选项。
  • 设置存储的路径以及文件名称

可以通过执行config set dir{newDir}和config setdbfilename{newFileName}运行期动态执行, 当下次运行时RDB文件会保存到新目录,AOF相同设置

  • RDB方式的优缺点
  1. 优点:非常适用于备份, 全量复制等场景。 比如每6小时执行bgsave备份,并把RDB文件拷贝到远程机器或者文件系统中(如hdfs) , 用于灾难恢复。·Redis加载RDB恢复数据远远快于AOF的方式
  2. 缺点:RDB方式数据没办法做到实时持久化/秒级持久化。 因为bgsave每次运行都要执行fork操作创建子进程, 属于重量级操作, 频繁执行成本过高

2. AOF持久化方式

开启AOF功能需要设置配置: appendonly yes, 默认不开启。 AOF文件名通过appendfilename配置设置, 默认文件名是appendonly.aof

  • 含义:以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中的命令达到恢复数据的目的。 AOF的主要作用是解决了数据持久化的实时性。
  • 运行流程
运行流程
  1. 所有的写入命令会追加到aof_buf(缓冲区) 中。
  2. AOF缓冲区根据对应的策略向硬盘做同步操作。
  3. 随着AOF文件越来越大, 需要定期对AOF文件进行重写, 达到压缩的目的。
  4. 当Redis服务器重启时, 可以加载AOF文件进行数据恢复。
  • 文件的同步

AOF将buf数据同步到文件的策略由参数appendfsync控制


同步文件的策略

系统调用write和fsync说明:

  1. write操作会触发延迟写(delayed write) 机制。 Linux在内核提供页缓冲区用来提高硬盘IO性能。 write操作在写入系统缓冲区后直接返回。 同步硬盘操作依赖于系统调度机制, 例如: 缓冲区页空间写满或达到特定时间周期。 同步文件之前, 如果此时系统故障宕机, 缓冲区内数据将丢失。
  2. fsync针对单个文件操作(比如AOF文件) , 做强制硬盘同步, fsync将阻塞直到写入硬盘完成后返回, 保证了数据持久化
    默认配置everysec
  • 重写机制
  1. 含义:随着命令不断写入AOF, 文件会越来越大, 为了解决这个问题, Redis引入AOF重写机制压缩文件体积。 AOF文件重写是把Redis进程内的数据转化为写命令同步到新AOF文件的过程。
    重写使用的是进程内的数据生成,这样减少无效命令,同时可以多条命令合并一个。
  2. 触发情况
    手动触发: 直接调用bgrewriteaof命令。
    自动触发: 根据auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数确定自动触发时机。
    auto-aof-rewrite-min-size: 表示运行AOF重写时文件最小体积, 默认为64MB。
    auto-aof-rewrite-percentage: 代表当前AOF文件空间(aof_current_size) 和上一次重写后AOF文件空间(aof_base_size) 的比值。
    自动触发时机=aof_current_size>auto-aof-rewrite-minsize&&(aof_current_size-aof_base_size) /aof_base_size>=auto-aof-rewritepercentage
    其中aof_current_size和aof_base_size可以在info Persistence统计信息中查看(但是实践中没找到这个参数呢?,额,额, 额, )
  • 重写执行流程
  1. 当前进程如果正在执行 AOF重写,请求则不执行,如果正在执行bgsave操作,重写命令延迟到此操作完成之后再执行
  2. 父进程执行fork创建子进程,开销等同于bgsave过程
  3. 主进程fork操作完成后, 继续响应其他命令。 所有修改命令依然写入AOF缓冲区并根据appendfsync策略同步到硬盘, 保证原有AOF机制正确性
  4. 由于fork操作运用写时复制技术, 子进程只能共享fork操作时的内存数据。 由于父进程依然响应命令, Redis使用“AOF重写缓冲区”保存这部分新数据, 防止新AOF文件生成期间丢失这部分数据
  5. 子进程根据内存快照, 按照命令合并规则写入到新的AOF文件。 每次批量写入硬盘数据量由配置aof-rewrite-incremental-fsync控制, 默认为32MB, 防止单次刷盘数据过多造成硬盘阻塞
  6. 新AOF文件写入完成后, 子进程发送信号给父进程, 父进程更新统计信息, 具体见info persistence下的aof_*相关统计。
  7. 父进程把AOF重写缓冲区的数据写入到新的AOF文件。
  8. 使用新AOF文件替换老文件, 完成AOF重写


    重写执行过程
  • AOF重启加载

优先加载AOF


AOF与RDB加载情况

3.持久化的一些问题

  • fork操作的耗时

fork创建的子进程不需要拷贝父进程的物理内存空间, 但是会复制父进程的空间内存页表,因此fork
操作耗时跟进程总内存量息息相关

  1. 优先使用物理机或者高效支持fork操作的虚拟化技术, 避免使用Xen。
  2. 控制Redis实例最大可用内存, fork耗时跟内存量成正比, 线上建议每个Redis实例内存控制在10GB以内
  3. 降低fork操作的频率, 如适度放宽AOF自动触发时机, 避免不必要的全量复制等
  • 子进程开销监控
  1. CPU:子进程负责把进程内的数据分批写入文件,属于CPU密集型操作,如果做绑定单核CPU操作会和父进程进行资源的竞争,跟其他CPU密集型服务一起会产生CPU过度竞争,,部署多个实例保证同一个时刻只有一个子进程在进行重写工作。
  2. 内存:父子进程会共享相同的物理内存页, 当父进程处理写请求时会把要修改的页创建副本, 而子进程在fork操作过程中共享整个父进程内存快照,如果重写过程中存在内存修改操作, 父进程负责创建所修改内存页的副本,所以部署多个实例,则保证同一个时刻只有一个子进程在工作,同时避免在大量写入的时候进行重写操作,这样会导致父进程维护大量的页副本。
  • 硬盘开销
  1. 不要和其他高硬盘负载的服务部署在一起。 如: 存储服务、 消息队列服务等。
  • AOF追加阻塞
  1. 主线程负责写入AOF缓冲区。
  2. AOF线程负责每秒执行一次同步磁盘操作, 并记录最近一次同步时间。
  3. 主线程负责对比上次AOF同步时间:
    ·如果距上次同步成功时间在2秒内, 主线程直接返回。
    ·如果距上次同步成功时间超过2秒, 主线程将会阻塞, 直到同步操作完成。
    问题:
    如果系统fsync缓慢, 将会导致Redis主线程阻塞影响效率
    每当发生AOF追加阻塞事件发生时, 在info Persistence统计中,aof_delayed_fsync指标会累加, 查看这个指标方便定位AOF阻塞问题。
    AOF同步最多允许2秒的延迟, 当延迟发生时说明硬盘存在高负载问题, 可以通过监控工具如iotop, 定位消耗硬盘IO资源的进程


    持久化指标参数

相关文章

网友评论

    本文标题:redis持久化

    本文链接:https://www.haomeiwen.com/subject/isacyftx.html