Redis支持EDB和AOF两种持久化机制,可以有效地避免因进程退出造成的数据丢失问题,当下次重启时利用之前持久化的文件即可实现数据恢复
- RDB(快照)
- AOF(日志,主流方式,默认不开启)
- no: don't fsync, just let the OS flush the data when it wants. Faster.
- always: fsync after every write to the append only log. Slow, Safest.
- everysec: fsync only one time every second. Compromise.
- 重启加载(AOF、RDB)
- 问题与优化
- 多实例部署
RDB(快照)
RDB持久化是把当前进程数据生成快照保存当硬盘的过程,分为手动触发和自动触发
手动触发机制
手动触发分别对应save(废弃,不推荐)和bgsave(推荐)
save(阻塞,不推荐)
save命令:阻塞当前Redis服务器,直到RDB过程完成为止,对于内存比较大的实例会造成长时间阻塞,线上环境不建议使用
bgsave(优化阻塞,推荐)
bgsave命令:Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一半时间很短
自动触发机制
- save m n:m秒内数据集存在n次修改时,自动触发bgsave
- 执行debug reload 命令重新加载Redis时会触发save操作
- 默认执行shutdown时,如果没有开启AOF持久化功能,则自动执行bgsave
bgsave流程说明
- bgsave是主流的持久化方式流程说明如下:
1.执行bgsave命令,Redis父进程判断是否存在正在执行的子进程,入RDB/AOF,如果存在则直接返回
2.不存咋则父进程执行fork操作创建子进程,此时会阻塞,通过info stats可查看最近一个fork操作,单位为us
3.父进程fork完成后,返回Background saving started信息后不再阻塞父进程,可以继续相应其他命令
4.子进程创建RDB文件,根据父进程内存生成临时快照文件,完成后对原有文件进行原子替换,lastsave可以获取最后一次生成RDB的时间
5.进程发送信号给父进程表示完成,父进程更新统计信息。可以使用info persistence命令查看详情
RDB文件的处理
保存:RDB保存在dir配置指定的目录下,配置文件默认为redis的配置文件
- 可以通过执行config set dir ,config set dbfilename 运行期间动态执行,下次运行时RDB文件会保存在新目录。
当遇到坏盘或者磁盘写满时,可以通过config set dir在线修改文件路径
压缩
Redis默认采用LZF算法对生成的RDB文件做压缩处理,压缩后的文件大小远远小于内存大小,默认开启
校验
如果Redis加载损坏的RDB文件时拒绝启动,可以使用Redis提供的redis-check-dump检测RDB文件
RDB的优缺点
-
优点:
1.RDB是一个紧凑压缩的二进制文件,非常适用于备份,全量复制等场景
2.RDB恢复数据远远快于AOF的方式 -
缺点:
1.RDB方式要执行fork操作创建子进程,属于重量级操作,频繁执行成本比较高
2.老版本Redis服务无法兼容新版RDB格式
AOF(日志,主流方式,默认不开启)
AOF(append only file)持久化:以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中的命令达到恢复数据的目的。解决了数据持久化的实时性,已经是Redis持久化的主流方式
使用AOF
AOF默认不开启,其配置开启和保存文件名如下
保存路径同RDB一直,通过dir指定
AOF流程
命令写入(append)、文件同步(sync)、文件重写(rewirte)、重启加载(load)
- 流程
1.所有的写入命令会追加到aof_buf(缓冲区)中
2.AOF缓冲区根据对应的策略向硬盘做同步操作
3.随着AOF文件越来越大,需要定期对AOF文件进行重写,达到压缩的目的
4.当Redis服务器重启时,可以加载AOF文件进行数据恢复
命令写入
AOF写入文件的内容直接是文本协议格式。
-
AOF采用文本协议格式好处
1.文本协议具有很好的兼容性
2.开启AOF后,直接采用协议格式,避免二次处理开销
3.文本协议具有客户端,方便修改和处理 -
AOF吧命令追加到aof_buf中好处
1.Redis使用单线程响应命令,如果直接写硬盘,那么性能完全取决于硬盘负责性能
2.可以通过多种缓冲区同步硬盘的策略,在性能和安全性方面做出平衡
文件同步
Redis提供多种AOF缓冲策略,配置文件如下,提供3中策略,默认为everysec
no: don't fsync, just let the OS flush the data when it wants. Faster.
always: fsync after every write to the append only log. Slow, Safest.
everysec: fsync only one time every second. Compromise.
- 3种策略如下:
1.no:同步硬盘操作由操作系统负责,通常同步周期最长30秒,数据安全性无法保证
2.always:每次下入同步AOF文件,一般SATA硬盘,只能支持大约几百TPS写入,硬盘为Redis性能瓶颈,不建议使用
3.everysec:默认配置,fsync同步操作由专门线程每秒调用一次,兼顾性能和数据安全性。在系统突然宕机的情况下丢失1秒的数据
重写机制
随着不断地写入AOF,文件会越来越大,Redis引入AOF重写机制压缩文件体积。
Redis进程内的数据转化为写命令同步到新AOF文件的过程
- AOF文件变小的原因:
1.进程内已超时的数据不在写入文件
2.旧的AOF文件还有无效命令(del、hdel、srem等)
3.多条写命令可以合并为一个
AOF重写触发机制
- 手动触发:直接调用bgrewriteaof命令
- 自动触发:根据auto-aof-rewrite-percentage和auto-aof-rewrite-min-size参数
1.auto-aof-rewrite-percentage:当前AOF文件空间和上一次重写后AOF空间的比值,默认为100
2.auto-aof-rewrite-min-size:代表运行AOF重写时文件最小体积,默认为64MB
触发时机参数比较复杂,不细说O(∩_∩)O
重启加载(AOF、RDB)
AOF和RDB文件都可用于服务器重启时的数据恢复
流程说明如上图Redis启动时优先加载AOF
问题与优化
Redis持久化功能一直是影响Redis性能的高发地
fork操作
fork是个重量级操作,回赋值父进程的空间内存页表
- 改善操作
1.优先使用物理机或者高效支持fork操作的虚拟化技术,避免使用Xen
2.控制Redis实例最大可用内存,建议Redis实例内存控制在10GB内
3.合理配置Linux内存分配策略,避免物理内存不足导致fork失败
4.降低fork操作频率,适度放宽AOF自动触发时机,避免不必要的全量复制等
子进程开销监控和优化
子进程负责AOF或者RDB文件的重写,主要设计CPU、内存、硬盘三部分
AOF追加阻塞
开启AOF持久化时且策略使用everysec时,Redis使用另一条线程每秒执行fsync同步硬盘。当系统资源繁忙时会造成Redis主线程阻塞
多实例部署
Redis单线程架构导致无法充分利用CPU多核特性,通常做法是在一台机器上部署多个Redis实例。当多个实例开启AOF重写后,彼此之间会产生对COU和I/O的竞争,需要采取措施把子进程工作进行隔离
Comments | 0 条评论