Redis学习--持久化

RDB

RDB持久化是把当前进程数据生成快照保存到硬盘的过程

  • 触发机制

手动触发save命令,阻塞当前Redis服务器,直到RDB过程完成为止
手动触发bgsave命令,Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。
自动触发save m n表示m秒内数据集存在n次修改时,自动触发bgsave。
如果从节点执行全量复制操作,主节点自动执行bgsave生成RDB文件并发送给从节点
执行debug reload命令重新加载Redis时,也会自动触发save操作。
默认情况下执行shutdown命令时,如果没有开启AOF持久化功能则自动执行bgsave。

  • 流程说明


    bgsave命令的运作流程
  • RDB文件的处理
    保存:RDB文件保存在dir配置指定的目录下,文件名通过dbfilename配置指定。可以通过执行config set dir{newDir}和config setdbfilename{newFileName}运行期动态执行,当下次运行时RDB文件会保存到新目录。
    压缩:Redis默认采用LZF算法对生成的RDB文件做压缩处理,压缩后的文件远远小于内存大小,默认开启,可以通过参数config set rdbcompression{yes|no}动态修改。
    校验:如果Redis加载损坏的RDB文件时拒绝启动,可以使用Redis提供的redis-check-dump工具检测RDB文件并获取对应的错误报告。

优点:

  • RDB是一个紧凑压缩的二进制文件,代表Redis在某个时间点上的数据快照。非常适用于备份,全量复制等场景。比如每6小时执行bgsave备份,并把RDB文件拷贝到远程机器或者文件系统中(如hdfs),用于灾难恢复。
  • Redis加载RDB恢复数据远远快于AOF的方式。

RDB的缺点:

  • RDB方式数据没办法做到实时持久化/秒级持久化。因为bgsave每次运行都要执行fork操作创建子进程,属于重量级操作,频繁执行成本过高。
  • RDB文件使用特定二进制格式保存,Redis版本演进过程中有多个格式的RDB版本,存在老版本Redis服务无法兼容新版RDB格式的问题。
AOF

开启AOF功能需要设置配置:appendonly yes,默认不开启。

AOF工作流程

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

AOF缓冲区同步文件策略

配置为everysec,是建议的同步策略,也是默认配置,做到兼顾性能和数据安全性。理论上只有在系统突然宕机的情况下丢失1秒的数据。
重写机制
随着命令不断写入AOF,文件会越来越大,为了解决这个问题,Redis引入AOF重写机制压缩文件体积。
AOF重写过程可以手动触发和自动触发:

  • 手动触发:直接调用bgrewriteaof命令。
  • 自动触发:根据auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数确定自动触发时机。
    1.auto-aof-rewrite-min-size:表示运行AOF重写时文件最小体积,默认为64MB。
    2.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重写运作流程

重启加载
Redis持久化文件加载流程

文件校验
对于错误格式的AOF文件,先进行备份,然后采用redis-check-aof--fix命令进行修复,修复后使用diff-u对比数据的差异,找出丢失的数据.
问题定位与优化

  • 改善fork操作
    1)优先使用物理机或者高效支持fork操作的虚拟化技术,避免使用Xen。
    2)控制Redis实例最大可用内存,fork耗时跟内存量成正比,线上建议每个Redis实例内存控制在10GB以内。
    3)合理配置Linux内存分配策略,避免物理内存不足导致fork失败
    4)降低fork操作的频率,如适度放宽AOF自动触发时机,避免不必要的全量复制等。
  • 子进程开销监控和优化
    1.CPU,不要做绑定单核CPU操作,不要和其他CPU密集型服务部署在一起,造成CPU过度竞争,部署多个Redis实例,尽量保证同一时刻只有一个子进程执行重写工作.
    2.内存
    1)同CPU优化一样,如果部署多个Redis实例,尽量保证同一时刻只有一个子进程在工作。
    2)避免在大量写入时做子进程重写操作,这样将导致父进程维护大量页副本,造成内存消耗。
    3.硬盘
    a)不要和其他高硬盘负载的服务部署在一起。如:存储服务、消息队列服务等。
    b)AOF重写时会消耗大量硬盘IO,可以开启配置no-appendfsync-onrewrite,默认关闭。表示在AOF重写期间不做fsync操作。
    c)当开启AOF功能的Redis用于高流量写入场景时,如果使用普通机械磁盘,写入吞吐一般在100MB/s左右,这时Redis实例的瓶颈主要在AOF同步硬盘上。
    d)对于单机配置多个Redis实例的情况,可以配置不同实例分盘存储AOF文件,分摊硬盘写入压力。
  • AOF追加阻塞


    使用everysec做刷盘策略的流程

    因为AOF线程负责每秒执行一次同步磁盘操作,超过两秒就会使主线程阻塞.
    1.发生AOF阻塞时,Redis输出日志,用于记录AOF fsync阻塞导致拖慢Redis服务的行为
    2.每当发生AOF追加阻塞事件发生时,在info Persistence统计中,aof_delayed_fsync指标会累加,查看这个指标方便定位AOF阻塞问题。
    3.AOF同步最多允许2秒的延迟,当延迟发生时说明硬盘存在高负载问题,可以通过监控工具如iotop,定位消耗硬盘IO资源的进程。

多实例部署
轮询控制AOF重写

1)外部程序定时轮询监控机器(machine)上所有Redis实例。
2)对于开启AOF的实例,查看(aof_current_sizeaof_base_size)/aof_base_size确认增长率。
3)当增长率超过特定阈值(如100%),执行bgrewriteaof命令手动触发当前实例的AOF重写。
4)运行期间循环检查aof_rewrite_in_progress和aof_current_rewrite_time_sec指标,直到AOF重写结束。
5)确认实例AOF重写完成后,再检查其他实例并重复2)~4)步操作。从而保证机器内每个Redis实例AOF重写串行化执行。

你可能感兴趣的:(Redis学习--持久化)