Redis持久化方式RDB和AOF介绍

持久化简介

将内存中的数据隔段时间在硬盘中做备份,防止数据突然丢失

  • 快照方法 RDB
  • 日志方法 AOF

RDB

启动方式

指令:save

  • 谁:redis操作者(用户)
  • 什么时间:即时(随时进行)
  • 干什么事情:保存数据

手动执行一次保存一次数据,产生在日志文件夹下的rdb文件(二进制)

save指令会阻塞当前redis服务器,线上环境不推荐使用。

指令:bgsave

  • 谁:redis操作者(用户)发起指令;redis服务器控制指令执行
  • 什么时间:即时(发起);合理的时间(执行)
  • 干什么事情:保存数据
127.0.0.1:6379> bgsave
Background saving started

原理:调用linux的fork函数生成子进程,由这个子进程负责创建rdb文件。

自动执行

  • 谁:redis服务器发起指令(基于条件)
  • 什么时间:满足条件
  • 干什么事情:保存数据

发起的还是bgsave

配置:

save second changes:满足限定时间范围内key的变化数量达到指定数量即进行持久化。

示例:

save 900 1
save 300 10
save 60 10000

其他启动方式

  1. 全量复制
  2. 服务器运行过程中重启 debug reload
  3. 关闭服务器时指定保存数据 shutdown save

相关配置

  • dbfilename dump.rdb
    • 说明:设置本地数据库文件名,默认值为 dump.rdb
    • 经验:通常设置为dump-端口号.rdb
  • dir
    • 说明:设置存储.rdb文件的路径
    • 经验:通常设置成存储空间较大的目录中,目录名称data
  • rdbcompression yes
    • 说明:设置存储至本地数据库时是否压缩数据,默认为 yes,采用 LZF 压缩
    • 经验:通常默认为开启状态,如果设置为no,可以节省 CPU 运行时间,但会使存储的文件变大(巨大)
  • rdbchecksum yes
    • 说明:设置是否进行RDB文件格式校验,该校验过程在写文件和读文件过程均进行
    • 经验:通常默认为开启状态,如果设置为no,可以节约读写性过程约10%时间消耗,但是存储一定的数据损坏风险
  • stop-writes-on-bgsave-error yes
    • 说明:后台存储过程中如果出现错误现象,是否停止保存操作
    • 经验:通常默认为开启状态

优点

  • RDB是一个紧凑压缩的二进制文件,存储效率较高
  • RDB内部存储的是redis在某个时间点的数据快照,非常适合用于数据备份,全量复制等场景
  • RDB恢复数据的速度要比AOF快很多
  • 应用:服务器中每X小时执行bgsave备份,并将RDB文件拷贝到远程机器中,用于灾难恢复。

缺点

  • RDB方式无论是执行指令还是利用配置,无法做到实时持久化,具有较大的可能性丢失数据
  • bgsave指令每次运行要执行fork操作创建子进程,要牺牲掉一些性能
  • Redis的众多版本中未进行RDB文件格式的版本统一,有可能出现各版本服务之间数据格式无法兼容现象

AOF

概述

AOF(append-only-file):以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中命令
达到恢复数据的目的。与RDB相比可以简单描述为改记录数据为记录数据产生的过程

AOF的主要作用是解决了数据持久化的实时性,目前已经是Redis持久化的主流方式

这个文件是一个文本文件

AOF写数据三种策略

  • always(每次)
    每次写入操作均同步到AOF文件中,数据零误差,性能较低,命令写入到aof_buf后,会调用系统fsync操作同步到文件中。
  • everysec(每秒)
    每秒将缓冲区中的指令同步到AOF文件中,数据准确性较高,性能较高,是默认配置。只调用系统write操作,fsync同步文件操作由专门进程每秒调用一次。
    在系统突然宕机的情况下丢失1秒内的数据
  • no(系统控制)
    由操作系统控制每次同步到AOF文件的周期,整体过程不可控,只调用系统write操作,不对AOF文件做fsync操作。

相关配置

  • appendonly yes|no 开启AOF
  • appendfsync always|everysec|no 写数据策略

AOF重写

随着命令不断写入AOF,文件会越来越大,为了解决这个问题,Redis引入了AOF重写机制压缩文件体积。AOF文件重写是将Redis进程内的数据转化为写命令同步到新AOF文件的过程。简单说就是将对同一个数据的若干个条命令执行结果转化成最终结果数据对应的指令进行记录。

作用

  • 降低磁盘占用量,提高磁盘利用率
  • 提高持久化效率,降低持久化写时间,提高IO性能
  • 降低数据恢复用时,提高数据恢复效率

重写规则

  • 进程内已超时的数据不再写入文件
  • 忽略无效指令,重写时使用进程内数据直接生成,这样新的AOF文件只保留最终数据的写入命令如del key1、hdel key2、srem key3、set key4 111、set key4 222等
  • 对同一数据的多条写命令合并为一条命令,如lpush list1 alpush list1 blpush list1 c 可以转化为:lpush list1 a b c
  • 为防止数据量过大造成客户端缓冲区溢出,对list、set、hash、zset等类型,每条指令最多写入64个元素

重写方式

手动重写:bgrewriteaof

自动重写:

# aof_current_size达到最小size开始重写
auto-aof-rewrite-min-size size
# (aof_current_size-aof_base_size)/aof_base_size>percentage开始重写
auto-aof-rewrite-percentage percentage

配置自动重写要了解两个参数:

aof_current_size
aof_base_size

aof_current_size表示当前AOF文件大小,aof_base_size指的就是上一次重写后AOF文件的大小。这两个参数可以通过运行指令info Persistence查看。

原理和bgsave类似,也是用子进程去重写。

RDB与AOF区别

持久化方式 RDB AOF
占用存储空间 小(数据级:压缩) 大(指令级:重写)
存储速度
恢复速度
数据安全性 会丢失数据 依据策略决定
资源消耗 高/重量级 低/轻量级
启动优先级

如何选择?

  • 对数据非常敏感,建议使用默认的AOF持久化方案
    • AOF持久化策略使用everysecond,每秒钟fsync一次。该策略redis仍可以保持很好的处理性能,当出现问题时,最多丢失0-1秒内的数据。
    • 注意:由于AOF文件存储体积较大,且恢复速度较慢
  • 数据呈现阶段有效性,建议使用RDB持久化方案
    • 数据可以良好的做到阶段内无丢失(该阶段是开发者或运维人员手工维护的),且恢复速度较快,阶段点数据恢复通常采用RDB方案
    • 注意:利用RDB实现紧凑的数据持久化会使Redis降的很低,慎重总结:
  • 综合比对
    • RDB与AOF的选择实际上是在做一种权衡,每种都有利有弊
    • 如不能承受数分钟以内的数据丢失,对业务数据非常敏感,选用AOF
    • 如能承受数分钟以内的数据丢失,且追求大数据集的恢复速度,选用RDB
    • 灾难恢复选用RDB
    • 双保险策略,同时开启 RDB 和 AOF,重启后,Redis优先使用 AOF 来恢复数据,降低丢失数据的量

原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/redis%e6%8c%81%e4%b9%85%e5%8c%96%e6%96%b9%e5%bc%8frdb%e5%92%8caof%e4%bb%8b%e7%bb%8d/