目录
大部分源自:https://www.jianshu.com/p/9c7f0f786c5b
redis持久化的意义:
redis持久化的意义主要在于故障恢复,比如你部署一个redis,作为缓存有可能里边有一些比较重要的数据,如果没有持久化的时候,redis遇到灾难性故障的时候就会丢失所有的数据。
多以持久化是必不可少的。
AOF持久化机制对每条写入命令作为日志,以append-only模式写入一个日志文件中,在redis重启的时候,可以通过AOF写入的指令来重新构建整个数据集。
通过RDB和AOF都可以将redis内存中的数据持久化到硬盘上,然后可以将数据备份到云服务器上。
如果redis挂了可以从云服务器上的备份文件copy到指定位置然后重启redis,redis就会自动持久化文件中的数据,去恢复内存中的数据。
如果同时使用RDB和AOF两种持久化机制,那么redis重启的时候,会使用AOF来构建数据,因为AOF的数据更加完整。
快照(snapshotting,RDB)![](https://i-blog.csdnimg.cn/blog_migrate/a9113b3c01e1a41803de54c6d569b22d.webp?x-image-process=image/format,png)
Redis可以通过创建快照来获得存储在内存里面的数据在某个时间点上的副本。Redis创建快照之后,可以对快照进行备份,可以将快照复制到其他服务器从而创建具有相同数据的服务器副本(Redis主从结构,主要用来提高Redis性 能),还可以将快照留在原地以便重启服务器的时候使用。 RDB持久化机制对redis中的数据执行周期性的持久化。
快照持久化是Redis默认采用的持久化方式,在redis.conf配置文件中默认有此下配置:
save 900 1 #在900秒(15分钟)之后,如果至少有1个key发生变化,Redis就会自动触发BGSAVE命令创建快照。
save 300 10 #在300秒(5分钟)之后,如果至少有10个key发生变化,Redis就会自动触发BGSAVE命令创建快照。
save 60 10000 #在60秒(1分钟)之后,如果至少有10000个key发生变化,Redis就会自动触发BGSAVE命令创建快照。
当满足条件时,redis需要执行RDB的时候服务器会执行以下操作:
1.redis调用系统的fork()函数创建一个子进程
2.子进程将数据集写入一个临时的RDB文件
3.当子进程完成对临时的RDB文件的写入时,redis用新的RDB文件来替换原来旧的RDB文件,并将旧的RDB文件删除
redis在进行快照的过程中不会对RDB文件进行修改,只有快照结束后才会将旧快照替换成新快照,也就是说任何时候RDB都是完整的
RDB优点:
(1)RDB会生成多个数据文件,每个数据文件都代表了某一个时刻中redis的数据,这种多个数据文件的方式,非常适合做冷备。
(2)RDB对redis对外提供读写服务的时候,影像非常小,因为redis 主进程只需要fork一个子进程出来,让子进程对磁盘io来进行rdb持久化
(3).RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。
RDB缺点
(1)如果redis要故障时要尽可能少的丢失数据,RDB没有AOF好,例如1:00进行的快照,在1:10又要进行快照的时候宕机了,这个时候就会丢失10分钟的数据。
(2)RDB每次fork出子进程来执行RDB快照生成文件时,如果文件特别大,可能会导致客户端提供服务暂停数毫秒或者几秒
只追加文件(append-only file,AOF)
与快照持久化相比,AOF持久化 的实时性更好,因此已成为主流的持久化方案。默认情况下Redis没有开启 AOF(append only file)方式的持久化,可以通过appendonly参数开启:
appendonly yes
在Redis的配置文件中存在三种不同的 AOF 持久化方式,它们分别是:
appendfsync always #每次有数据修改发生时都会写入AOF文件,这样会严重降低Redis的速度
appendfsync everysec #每秒钟同步一次,显示地将多个写命令同步到硬盘
appendfsync no #让操作系统决定何时进行同步
为了兼顾数据和写入性能,用户可以考虑 appendfsync everysec选项 ,让Redis每秒同步一次AOF文件,Redis性能 几乎没受到任何影响。而且这样即使出现系统崩溃,用户最多只会丢失一秒之内产生的数据。当硬盘忙于执行写入操 作的时候,Redis还会优雅的放慢自己的速度以便适应硬盘的最大写入速度。
redis中的数据是有一定限量的,不可能说redis中的数据无限增长,进而导致AOF文件无限增长。
内存大小是一定的,等到了一定大小redis 会采用淘汰策略lru,自动将内存中的数据清除掉
AOF是存放每条写命令的,所以会不断的增大,当大到一定程度时,AOF会做rewrite操作,rewrite操作就是基于当时redis的数据重新构造一个小的AOF文件,然后将大的AOF文件删除。
AOF的优点:
(1)AOF可以更好的保护数据不丢失,一般AOF会以每隔1秒,通过后台的一个线程去执行一次fsync操作,如果redis进程挂掉,最多丢失1秒的数据。
(2)AOF以appen-only的模式写入,所以没有任何磁盘寻址的开销,写入性能非常高。
(3)AOF日志文件的命令通过非常可读的方式进行记录,这个非常适合做灾难性的误删除紧急恢复,如果某人不小心用flushall命令清空了所有数据,只要这个时候还没有执行rewrite,那么就可以将日志文件中的flushall删除,进行恢复。
AOF的缺点
(1)对于同一份文件AOF文件比RDB数据快照要大。
(2)AOF开启后支持写的QPS会比RDB支持的写的QPS低,因为AOF一般会配置成每秒fsync操作,每秒的fsync操作还是很高的
(3)数据恢复比较慢,不适合做冷备。
RDB和AOF到底如何选择
(1)不要仅仅使用RDB这样会丢失很多数据。
(2)也不要仅仅使用AOF,因为这一会有两个问题,第一通过AOF做冷备没有RDB做冷备恢复的速度快;第二RDB每次简单粗暴生成数据快照,更加健壮。
(3)综合AOF和RDB两种持久化方式,用AOF来保证数据不丢失,作为恢复数据的第一选择;用RDB来做不同程度的冷备,在AOF文件都丢失或损坏不可用的时候,可以使用RDB进行快速的数据恢复。
Redis 4.0 对于持久化机制的优化
Redis 4.0 开始支持 RDB 和 AOF 的混合持久化(默认关闭,可以通过配置项 aof-use-rdb-preamble 开启)。
如果把混合持久化打开,AOF 重写的时候就直接把 RDB 的内容写到 AOF 文件开头。
好处:结合 RDB 和 AOF 的优点, 快速加载同时避免丢失过多的数据。
缺点:AOF 里面的 RDB 部分是压缩格式不再是 AOF 格式,可读性较差。
补充内容:AOF 重写
AOF重写可以产生一个新的AOF文件,这个新的AOF文件和原有的AOF文件所保存的数据库状态一样,但体积更小。
AOF重写是一个有歧义的名字,该功能是通过读取数据库中的键值对来实现的,程序无须对现有AOF文件进行任伺读 入、分析或者写入操作。
在执行 BGREWRITEAOF 命令时,Redis 服务器会维护一个 AOF 重写缓冲区,该缓冲区会在子进程创建新AOF文件期 间,记录服务器执行的所有写命令。当子进程完成创建新AOF文件的工作之后,服务器会将重写缓冲区中的所有内容 追加到新AOF文件的末尾,使得新旧两个AOF文件所保存的数据库状态一致。最后,服务器用新的AOF文件替换旧的 AOF文件,以此来完成AOF文件重写操作