Redis简记之二———持久化

一、问题背景

redis有时可能会出现问题,会导致缓存数据的清空。

所以就需要持久化的出现。

二、RDB持久化

既然redis的数据都在内存中存放着,最简单的就是遍历一遍把它们全都写入文件中。

为了节约空间,redis定义了一个二进制的格式,把数据一条一条码在一起,生成了一个RDB文件。

但是但数据量过大时,备份一次需要很长时间,并且备份只有在写入操作时才会发生 。所以就需要一个配置参数,既可以支持周期性备份,也可以避免做无用功。

  • save 900 1     # 900秒(15分钟)内有1个写入

  • save 300 10    # 300秒(5分钟)内有10个写入

  • save 60 10000  # 60秒(1分钟)内有10000个写入

多个条件可以组合使用,只要上面一个条件满足,redis就会去进行备份。

最后,redis需要fork出一个子进程去做这件事,不能浪费redis的时间。

出现的问题redis周期性去备份,周期还是分钟级别的,但是服务每秒钟都要响应多少请求,这样就会丢失很多数据。

三、、AOF持久化

于是,参考了MySQL的二进制日志binlog文件。

由于Redis基于命令式的,每天的工作就是响应业务程序发来的命令请求。

Redis将执行的所有写入命令都记录下来,专门写入了一个文件,并给这种持久化方式也取了一个名字:AOF(Append Only File)

该多久写一次文件呢? 准备一个缓冲区,然后把要记录的命令先临时保存在这里,然后再择机写入文件,这个临时缓冲区叫做aof_buf。

但是数据并没有写到文件中,原因是操作系统中也有一个缓冲区,写入的数据被他缓存起来了。所以这时候就需要一个策略——AOF持久化策略

AOF持久化策略(即缓冲区内容写入和同步sync到AOF中),可以通过配置appendfsync属性来选择AOF持久化策略:

always:将aof_buf缓冲区中的所有内容写入并同步到AOF文件,每次有新命令追加到 AOF 文件时就执行一次 fsync。
everysec(默认):如果上次同步AOF的时间距离现在超过一秒,先将aof_buf缓冲区中的所有内容写入到AOF文件,再次对AOF文件进行同步,且同步操作由一个专门线程负责执行。
no:将aof_buf缓冲区中的所有内容写入到AOF文件,但并不对AOF文件进行同步,何时同步由操作系统(OS)决定。

 

AOF持久化策略的效率与安全性:

 Always:效率最慢的,但安全性是最安全的,即使出现故障宕机,持久化也只会丢失一个事件 循环的命令数据
everysec:兼顾速度和安全性,出现宕机也只是丢失一秒钟的命令数据
No:写入最快,但综合起来单次同步是时间是最长的,且出现宕机时会丢失上传同步AOF文件之后的所有命令数据。

四、AOF重写

        由于AOF持久化会把执行的写命令追加到AOF文件中,所以随着时间写入命令会不断增加, AOF文件的体积也会变得越来越大。AOF文件体积大对Reids服务器,甚至宿主服务器造成影响。

为了解决AOF文件体积膨胀的问题,Redis提供了AOF文件重写(rewrite)功能:

生成一个不保存任何浪费空间的冗余命令新的AOF文件,且新旧AOF文件保存数据库状态一样的
新的AOF文件是通过读取数据库中的键值对来实现的,程序无须对现有的AOF文件进行读入,分析,或者写入操作。
为防止缓冲区溢出,重写处理list,hash,set以及Zset时,超过设置常量数量时会多条相同命令记录一个集合。
Redis 2.4 可以通过配置自动触发 AOF 重写,触发参数 auto-aof-rewrite-percentage(触发AOF文件执行重写的增长率) 以及 auto-aof-rewrite-min-size(触发AOF文件执行重写的最小尺寸)

AOF重写的作用

※ 减少磁盘占用量
※ 加速数据恢复


Redis服务器使用单个线程来处理命令请求,服务器大量调用aof_rewrite函数,在AOF重写期间,则无法处理client发来的命令请求,所以AOF重写程序放在子进程执行,好处:

※ 子进程进行AOF重写期间,服务器进程可以继续处理命令请求
※ 子进程带有服务器进程的数据副本,保证了数据的安全性。

AOF重写使用子进程会造成数据库与重写后的AOF保存的数据不一致,为了解决这种数据不一致,redis使用了AOF重写缓冲区实现:

BGREWRITEAOF命令实现原理(只有信号处理函数执行时才对服务器进程造成阻塞):

※ 执行命令,同时将命令追加到AOF缓冲区和AOF重写缓冲区
※ 当AOF子进程重写完成后,发送一个信号给父进程,父进程将执行AOF重写缓冲区中的所有内容写入到新AOF文件中,新AOF文件保存的数据库状态将和服务器当前的数据库状态一致。
※ 对新的AOF文件进行改名,原子性地覆盖现有AOF文件,完成新旧两个AOF文件替换处理完成。
 

 五、RDB和AOF的优缺点

① RDB的优点:

(1)RDB文件是紧凑的二进制文件,比较适合做冷备,全量复制的场景;

(2)相对于AOF持久化机制来说,直接基于RDB数据文件来重启和恢复Redis进程,更加快速;

(3)RDB对Redis对外提供的读写服务,影响非常小,可以让Redis保持高性能,因为Redis主进程只需要fork一个子进程,让子进程执行磁盘IO操作来进行RDB持久化即可;

(4)RDB使用单独子进程来进行持久化,主进程不会进行任何IO操作,保证了Redis的高性能 ;

RDB的缺点:

(1)如果想要在Redis故障时,尽可能少的丢失数据,那么RDB没有AOF好;

(2)RDB每次在fork子进程来执行RDB快照数据文件生成的时候,如果数据文件特别大,可能会导致对客户端提供的服务暂停数毫秒,或者甚至数秒;

(3)RDB无法实现实时或者秒级持久化。

② AOF的优点:

(1)AOF可以更好的保护数据不丢失;

(2)AOF日志文件以append-only模式写入,写入性能比较高;

(3)AOF日志文件即使过大的时候,出现后台重写操作,也不会影响客户端的读写;

(4)适合做灾难性的误删除紧急恢复。

AOF的缺点:

(1)对于同一份数据来说,AOF日志文件通常比RDB数据快照文件更大,恢复速度慢;

(2)AOF开启后,支持的写QPS会比RDB支持的写QPS低,因为AOF一般会配置成每秒fsync一次日志文件,当然,每秒一次fsync,性能也还是很高的;

(3)以前AOF发生过bug,就是通过AOF记录的日志,进行数据恢复的时候,没有恢复一模一样的数据出来。

六、RDB和AOF的选择

1、不要仅仅使用RDB,因为那样会导致你丢失很多数据;

2、也不要仅仅使用AOF,因为那样有两个问题:

① 你通过AOF做冷备,没有RDB做冷备,恢复速度更快;
② RDB每次简单粗暴生成数据快照,更加健壮,可以避免AOF这种复杂的备份和恢复机制的bug;
3、综合使用AOF和RDB两种持久化机制,用AOF来保证数据不丢失,作为数据恢复的第一选择;

用RDB来做不同程度的冷备,在AOF文件都丢失或损坏不可用的时候,还可以使用RDB来进行快速的数据恢复;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

自xing且乐观~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值