Redis 持久化策略

Redis 持久化策略

什么是持久化

由于内存具有易失性,无法进行断电存储,所以在重启之后数据就会丢失,但是硬盘具有永久存储的特性,所以持久化就是将数据从内存中保存到硬盘的过程目的就是为了防止数据的丢失。 同时持久化也是Redis比起Memcached的优势,Memcached并不支持持久化

Redis的持久化分为以下三种

  1. RDB(Redis DataBase)持久化
  2. AOF(Append Only File)持久化
  3. 混合持久化

RDB持久化

RDB持久化其实就是以快照的方式进行持久化的存储。 在这里插入图片描述

对于一个Redis服务器来说,它的所有非空数据库以及数据库中的所有键值对就是当前数据库的状态。所以只需要将数据库的状态保存在硬盘当中,即使服务器停机或者断电,只要硬盘中存储的状态还在,就可以通过它来还原数据库原来的状态。

在这里插入图片描述 在这里插入图片描述 为了保证文件的安全以及容量更小,RDB持续化所生成的RDB文件是一个经过压缩的二进制文件,通过这个文件就可以还原数据库的状态。

SAVA与BGSAVA

RDB持久化根据执行持久化的对象不同又分为SAVABGSAVA两种方式

SAVA即让Redis服务进程来执行持久化,所以直到RDB持久化结束之前,Redis服务进程会一直处于阻塞状态,无法处理任何命令。

BGSAVE则会通过fork()来创建一个子进程,然后让子进程来接管RDB持久化,而父进程继续处理命令请求

由于SAVA的会导致主进程的阻塞,所以使用时基本不会考虑,所以通常我们都会默认使用BGSAVA来进行,下面我指的也都是BGSAVA

RDB持久化的优缺点

优点:

  • RDB文件是经过压缩的二进制文件,占用内存更小更紧凑,适合作为备份文件
  • RDB容灾恢复更有用,因为其更加紧凑,可以更快的传输到远程服务器进行数据恢复。
  • RDB可以提高Redis的运行速度,因为使用BGSAVA持久化时会fork出子进程进行持久化的I/O操作,主进程不会受到干扰。
  • 比起AOF格式的文件,RDB文件这种直接恢复状态的重启更快 缺点:
  • 由于RDB是以快照形式进行保存的,并且快照之间存在一定的时间间隔,如果Redis服务被终止,则会导致丢失一段时间的数据
  • RDB的BGSAVA需要fork()出子进程来进行持久化,但是如果CPU性能不佳且数据量很大的时候,fork()的时间就会增加,导致Redis可能会停止服务一段时间。

AOF持久化

AOF持久化其实就是保存Redis服务器所执行的命令来保存数据库的状态,将命令追加到AOF文件的末尾(Append Only File),AOF的核心其实就是将所有执行过的命令重新执行,来恢复状态

什么意思呢?例如我们执行了几条命令,此时AOF持久化会将这些命令以请求协议格式追加到AOF文件末尾 在这里插入图片描述 当服务器启动时,就会读取AOF文件中的所有命令,将其在服务器上重新执行一次,来恢复服务器的状态。 在这里插入图片描述

AOF重写

随着服务器存储的数据越来越多,此时AOF保存的命令也越来越多,文件的体积就会变得非常大,这样就可能导致对Redis服务器以及宿主机造成影响,并且随着文件的增大,使用AOF来进行数据还原需要的时间也就更多。

并且还存在一个问题,就是命令中存在着大量冗余和多余的命令。

1
2
3
4
5
6
127.0.0.1:6379> lpush list2 5 2 1 3 4
(integer) 5
127.0.0.1:6379> lpop list2
"4"
127.0.0.1:6379> rpop list2
"5"

例如上面这些命令,我存储了5 2 1 3 4五个数据,之后我又删除了4和5,所以最终剩下的只有1 2 3。 但是如果将所有的命令都保存进去,在恢复状态的时候又会重新模拟一次中间的删除流程,这些步骤是不需要的,我们只需要最终的结果。

所以AOF引入了重写的机制,即只保存能够获取最终结果的命令 重写的流程很简单,就是去直接读取当前数据库中的键值状态,然后构造出对应的命令来进行保存 例如上面那个,就直接进行一次lpush 1 2 3,就可以直接省去了中间的操作。

并且和RDB的BGSAVA一样,为了不阻塞主进程,所有的重写操作都会通过创建子进程来进行,并且由于子进程创建时会通过写时拷贝机制带有服务器数据的副本,所以也不需要对数据进行加锁就可以保证安全,提高了效率 在这里插入图片描述 此时子进程进行AOF的重写,父进程则继续处理接受的请求。 但是这时又引入了一个问题,如果父进程接受了新的命令,这些命令可能就会对数据库的状态进行修改,这样就会导致重写后的AOF文件所保存的状态和当前的数据库状态不一致

为了解决这个问题,服务器新增了一个AOF重写缓冲区,将两个AOF的过程给分割开 服务器流程

  1. 执行客户端发送来的新命令
  2. 将执行后的写命令追加到AOF缓冲区中
  3. 将执行后的写命令追加到AOF重写缓冲区中

这样AOF缓冲区的数据会被定期写入和同步到AOF文件中,不会影响整个AOF的流程。 而在执行重写后所执行的命令也都会保存到AOF重写缓冲区中。

所以在子进程重写结束后,其会通过信号的方式来通知父进程,此时服务器就会进行以下的操作来完成重写的AOF文件的更换

  • 将当前AOF重写缓冲区中的命令保存到一个新的AOF文件中,此时的新AOF文件的状态与当前数据库保存一致,并且比起旧的AOF更加简洁
  • 此时对新的AOF文件进行改名,原子性的覆盖掉原先的AOF文件,完成AOF重写文件与旧文件的更替

AOF持久化的优缺点

优点

  • AOF持久化保存的数据更加完整,其设定了三种保存策略:每次操作保存、每秒钟保存、跟随系统的持久化策略保存,其中每秒保存一次为AOF的默认策略。通过这种方法,使得即使发生了意外情况,最多也只会丢失1秒的数据,而不像RDB会丢失一段时间的数据
  • AOF如其名,采用了命令追加的方式写入到文件中,所以不会出现文件损坏的问题
  • AOF持久化将命令以协议格式写入文件,非常容易理解和解析,即使不小心使用flushall进行删库,并且状态被保存了下来。也可以通过删除AOF文件中的flushall命令来消除那次操作。(RDB快照则没办法避免)

缺点

  • 在数据量相同的时候,AOF文件要大于RDB文件
  • 在Redis负载较高的时候,RDB的性能比AOF更好
  • RDB使用快照的形式来持久化整个Redis数据,而AOF是将每次执行的命令追加到AOF文件中,所以RDB比AOF更健壮

混合持久化

混合持久化是在Redis4.0之后新增的一种方式,混合持久化结合了RDB和AOF的优点,在写入文件的时候,会先把当前的数据以RDB的形式写入文件的开头再将后续的操作命令以AOF的格式写入文件中,这样既能保证Redis重启时的速度(RDB快照状态恢复),又能减少数据丢失的风险(AOF丢失时间短)

混合持久化的优缺点

优点

  • 结合了RDB和AOF的优点,开头为RDB格式的数据,可以快速启动(快照),并且之后为AOF格式,减少了大量数据丢失的风险 缺点
  • AOF文件可读性变差,因为AOF文件前面增加了RDB格式的内容
  • 兼容性差,由于混合持久化是在4.0之后才引入的,如果开启之后则混合持久化AOF文件就不能使用在之前的版本
Built with Hugo
主题 StackJimmy 设计