Redis将我们存储的数据放到内存中,从而使得其读写速度大大提高了,但是我们都知道内存中的数据是不能长久保存的,当我们的服务器发生断电或者其他异常时,可能会导致内存中的数据丢失,那么Redis为了保证我们的数据在出现这种情况时能够尽量完整的保存下来,Redis提供了两种持久化的方式:RDB和AOF,下面就介绍一下这两种方式以及对应的优缺点。
RDB(Redis DataBase)
RDB的持久化的原理是将内存中的数据周期性的持久化到硬盘中,生成.rdb文件,当Redis因为某些原因停止服务后,我们重启Redis时,Redis会将.rdb文件来读到内存中对我们的数据进行恢复,从而保证了我们的数据的安全。
RDB备份的流程
- 当Redis使用RDB进行备份时,会开启(fork)一个备份的子线程来进行持久化操作
- 在进行持久化时子线程会先将内存中的数据写到到一个临时文件中
- 当内存中的数据写入完毕后,再将新的rdb文件代替掉原有的rdb文件,从而保证在备份过程中不会因为某些意外,导致已有的持久化文件损坏。
- 在其整个过程中,主线程不会进行任何的IO操作,持久化操作全部由子线程执行,从而保证Redis的高性能操作
fork操作:fork是linux系统的一个操作,可以创建一个和父线程完全一样的子线程,并且共用一块内存区域,同时引入了COW(Copy On Write)机制,一般来说父子线程公用一块内存区域,但是当对数据进行修改时,会将对应的数据段里的数据页复制一份出来在其他内存区域,用来进行修改.
优点:
- 相比于AOF,RDB持久化文件所占用的磁盘空间更小
- 数据量较大时,数据恢复的速度相比于AOF要快
缺点:
- 由于RDB是周期性对内存数据进行的备份,那么当Redis因为停止服务后,最后一次备份之后的数据因为还没来得及备份导致丢失,如果对数据的完整性要求很高的话,就不适合这种持久化方式。
- 由于是通过fork操作创建的子进程,在某些情况下可能会需要额外的内存消耗。
- 虽然使用了在fork使用了写时复制的技术,但是如果数据量过大,还是会比较吃性能。
AOF(Apend Only File)
AOF持久化是当Redis在执行命令时,会将新来的写命令追加到硬盘中的持久化文件中,每当Redis重启时就执行持久化文件中的命令,从而实现数据的恢复操作。
AOF持久化流程
- 首先Redis收到的写命令会被追加到AOF缓冲区内,Redis会根据持久化策略(always,everysec,no)将缓冲区内的命令同步到磁盘的AOF文件中。
- 当AOF文件超过重写策略规定的大小或者手动重写时,AOF文件会被重写压缩,只保留可以恢复数据的最小指令集,减小硬盘的占用。
重写压缩的原理
当AOF持久化文件过大时,Redis会fork出一个子进程用于文件的重写操作,保证主线程不会阻塞,子进程在执行重写操作时会将内存中的数据写入临时文件中,同时会将新接收的写命令同时写入AOF缓冲区和重写缓冲区中,保证AOF文件的完整性,以及新生成的AOF文件不会丢失重写过程中新来的写命令。当重写完成后,子进程会给主进程发送信号,主进程会将重写缓冲区中的写命令追加到新的AOF文件中,重写后新的AOF文件替换原有的AOF文件,完成AOF重写。
Redis4.0版本后持久化的aof文件格式为内存快照+追加的指令.
优点:
- 由于是使用将命令追加的到持久化文件中的形式,所以相比于RDB保存的数据更加完整。
- 由于对每一条写命令都进行追加,持久化文件相较于AOF更大
缺点:
- 恢复数据时会依次执行持久化文件中的命令,恢复的速度相比于AOF更慢
- 每个写命令都要进行同步,有一定的性能压力
- 可能会存在bug,无法恢复数据