Redis-持久化

Redis支持RDB和AOF两种持久化机制,持久化功能有效地避免因进程退出造成的数据丢失问题, 当下次重启时利用之前持久化的文件即可实现数据恢复。

1.RDB

RDB持久化就是把当前进程数据生成快照保存到硬盘的过程,触发RDB持久化过程分为手动触发和自动触发。

1.1 触发机制
·bgsave命令: Redis进程执行fork操作创建子进程, RDB持久化过程由子进程负责, 完成后自动结束。 阻塞只发生在fork阶段, 一般时间很短。 运行
bgsave命令对应的Redis日志如下:

* Background saving started by pid 3151
* DB saved on disk
* RDB: 0 MB of memory used by copy-on-write
* Background saving terminated with success

Redis内部还存在自动触发RDB的持久化机制, 例如以下场景:

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

压缩: Redis默认采用LZF算法对生成的RDB文件做压缩处理, 压缩后的文件远远小于内存大小, 默认开启, 可以通过参数config set
rdbcompression{yes|no}动态修改。
虽然压缩RDB会消耗CPU, 但可大幅降低文件的体积, 方便保存到硬盘或通过网络发送给从节点, 因此线上建议开启。
1.4 RDB的优缺点
RDB的优点:
·RDB是一个紧凑压缩的二进制文件, 代表Redis在某个时间点上的数据快照。 非常适用于备份, 全量复制等场景。 比如每6小时执行bgsave备份,
并把RDB文件拷贝到远程机器或者文件系统中(如hdfs) , 用于灾难恢复。
·Redis加载RDB恢复数据远远快于AOF的方式。
RDB的缺点:
·RDB方式数据没办法做到实时持久化/秒级持久化。 因为bgsave每次运行都要执行fork操作创建子进程, 属于重量级操作, 频繁执行成本过高。
 

针对RDB不适合实时持久化的问题, Redis提供了AOF持久化方式来解决。

2 AOF

AOF(append only file) 持久化: 以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中的命令达到恢复数据的目的。 AOF的主要作用
是解决了数据持久化的实时性, 目前已经是Redis持久化的主流方式。理解掌握好AOF持久化机制对我们兼顾数据安全性和性能非常有帮助。
2.1 使用AOF

开启AOF功能需要设置配置: appendonly yes, 默认不开启。 AOF文件名通过appendfilename配置设置, 默认文件名是appendonly.aof。 保存路径同
RDB持久化方式一致, 通过dir配置指定。 AOF的工作流程操作: 命令写入(append) 、 文件同步(sync) 、 文件重写(rewrite) 、 重启加载
(load) , 如图5-2所示。

下面介绍关于AOF的两个疑惑:
1) AOF为什么直接采用文本协议格式? 可能的理由如下:
·文本协议具有很好的兼容性。
·开启AOF后, 所有写入命令都包含追加操作, 直接采用协议格式, 避免了二次处理开销。
·文本协议具有可读性, 方便直接修改和处理。
2) AOF为什么把命令追加到aof_buf中?
Redis使用单线程响应命令, 如果每次写AOF文件命令都直接追加到硬盘, 那么性能完全取决于当前硬盘负
载。 先写入缓冲区aof_buf中, 还有另一个好处, Redis可以提供多种缓冲区同步硬盘的策略, 在性能和安全性方面做出平衡。

配置为always时, 每次写入都要同步AOF文件, 在一般的SATA硬盘上, Redis只能支持大约几百TPS写入, 显然跟Redis高性能特性背道而驰,
不建议配置。
·配置为no, 由于操作系统每次同步AOF文件的周期不可控, 而且会加大每次同步硬盘的数据量, 虽然提升了性能, 但数据安全性无法保证。
·配置为everysec, 是建议的同步策略, 也是默认配置, 做到兼顾性能和数据安全性。 理论上只有在系统突然宕机的情况下最多丢失2秒的数据。
2.4 重写机制
随着命令不断写入AOF, 文件会越来越大, 为了解决这个问题, Redis引入AOF重写机制压缩文件体积。 AOF文件重写是把Redis进程内的数据转
化为写命令同步到新AOF文件的过程。
重写后的AOF文件为什么可以变小? 有如下原因:
1) 进程内已经超时的数据不再写入文件。
2) 旧的AOF文件含有无效命令, 如del key1、 hdel key2、 srem keys、 set a111、 set a222等。 重写使用进程内数据直接生成, 这样新的AOF文件只保
留最终数据的写入命令。
3) 多条写命令可以合并为一个, 如: lpush list a、 lpush list b、 lpush list c可以转化为: lpush list a b c。 为了防止单条命令过大造成客户端缓冲区溢
出, 对于list、 set、 hash、 zset等类型操作, 以64个元素为界拆分为多条。
AOF重写降低了文件占用空间, 除此之外, 另一个目的是: 更小的AOF文件可以更快地被Redis加载。
AOF重写过程可以手动触发和自动触发:
·手动触发: 直接调用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

2.5 重启加载
AOF和RDB文件都可以用于服务器重启时的数据恢复。 如图5-4所示,表示Redis持久化文件加载流程。

1) Redis提供了两种持久化方式: RDB和AOF。
2) RDB使用一次性生成内存快照的方式, 产生的文件紧凑压缩比更高, 因此读取RDB恢复速度更快。 由于每次生成RDB开销较大, 无法做到实
时持久化, 一般用于数据冷备和复制传输。
3) save命令会阻塞主线程不建议使用, bgsave命令通过fork操作创建子进程生成RDB避免阻塞。
4) AOF通过追加写命令到文件实现持久化, 通过appendfsync参数可以控制实时/秒级持久化。 因为需要不断追加写命令, 所以AOF文件体积逐渐
变大, 需要定期执行重写操作来降低文件体积。
5) AOF重写可以通过auto-aof-rewrite-min-size和auto-aof-rewritepercentage参数控制自动触发, 也可以使用bgrewriteaof命令手动触发。
6) 子进程执行期间使用copy-on-write机制与父进程共享内存, 避免内存消耗翻倍。 AOF重写期间还需要维护重写缓冲区, 保存新的写入命令避免
数据丢失
7) 持久化阻塞主线程场景有: fork阻塞和AOF追加阻塞。 fork阻塞时间跟内存量和系统有关, AOF追加阻塞说明硬盘资源紧张。
 

备注:文章参考《Redis开发与运维》,作者:付磊,张益军

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值