Redis的数据持久化原理分析

113 阅读4分钟

一、简介

Redis有两种持久化方式:

  1. RDB全称redis database backup file(redis数据库备份文件),也被叫做redis数据快照。简单来说就是把内存中所有数据都记录到磁盘中。当redis实例故障重启后,从磁盘读取快照文件,恢复数据。它是redis默认的持久化方式。
  2. AOF全称为Append only file(追加文件),redis处理的每一个写命令都会记录在AOF文件中,可以看作是命令日志文件。AOF默认是关闭的。

二、RDB方式持久化

1、手动命令方式

save和bgsave两种命令方式。

60acfee97c12c8aaf7bd3ca64da0be9.png

项目中建议使用bgsave命令。

2、自动触发bgsave方式

redis内部有触发RDB的机制。可以在redis.conf中配置。

#900秒内如果至少有1个key被修改,则执行bgsave。
save 900 1
save 300 10
save 60 10000

3、RDB的执行原理

3.1. 普通版

bgsave开始时会fork主进程得到子进程,子进程共享主进程的内存数据。完成fork后读取内存数据并写入RDB文件。

8077ab1de0e3b7bfb80dba357c8234e.png

  1. 子进程通过复制主进程的页表,实现了共享主进程的内存数据。复制页表是很快的,花费纳米级别的时间,可以忽略不计。
  2. 磁盘上旧的RDB文件会被新的RDB文件覆盖。

3.2. 进阶版

如果在子进程写RDB文件过程中,主进程写入了新数据,怎么办?

fork采用的是写时复制(copy-on-write)技术:

  • 当主进程执行读操作时,访问共享内存。
  • 当主进程执行写操作时,则会拷贝一份被修改的内存页中的数据,并不是全部的内存数据,执行写操作。

linux中copy-on-write实现原理:

  1. fork()之后,kernel把父进程中所有的内存页权限都设为read-only,然后子进程的地址空间指向父进程。
  2. 当父子进程都只读内存时,相安无事。
  3. 当其中某个进程写内存时,CPU硬件检测到内存页是read-only的,于是触发页异常中断(page-fault),陷入kernel的一个中断例程。中断例程中,kernel就会把触发的异常的页复制一份,于是父子进程各自持有独立的一份。

e27679418f7b8b8d97c61e0aa75a680.png

二、AOF方式持久化

1、开启AOF

AOF默认是关闭的,可以修改redis.conf配置文件来开启AOF

#是否开启AOF功能,默认是NO
appendonly yes
#AOF文件的名称
appendfilename "appendonly.aof"

2、记录频率

AOF的命令记录的频率也可以通过redis.conf文件来配置。

#表示每执行一次写命令,立即记录到AOF文件
appendfsync always
#写命令执行完先放入AOF缓冲区,然后表示每隔一秒将缓冲区数据写到AOF文件,是默认方案
appendfsync everysec
#写命令执行完先放入AOF缓冲区,由操作系统决定何时将缓冲区命令写入磁盘。
appendfsync no
配置项刷盘时机优点缺点
always同步刷盘可靠性高,几乎不丢数据性能影响大
everysec每秒刷盘性能适中最多丢失一秒的数据
no操作系统控制性能最好可靠性较差,可能丢失大量数据

项目中推荐使用everysec

3、重写bgrewriteaof命令

因为是记录命令,AOF文件比RDB文件大的多,而且AOF会记录对同一个key的多次写操作,但只有最后一次写操作才有意义。通过执行bgrewriteaof命令,可以让AOF文件执行重写功能,用最少的命令达到相同的效果。

  • redis会在触发阈值时自动重写AOF文件。阈值可以在redis.conf文件中配置
#AOF文件比上次文件,增长超过多少百分比则触发重写
auto-aof-rewrite-percentage 100
#AOF文件体积最小多大以上触发重写
auto-aof-rewrite-min-size 64mb

三、RDB与AOF对比

如果对数据安全性要求较高,在实际开发中往往会结合两者来使用。

RDBAOF
持久化方式定时对整个内存做快照记录每一次执行的写命令
数据完整性不完整,两次备份之间会丢失相对完整,取决于刷盘策略
文件大小二进制文件,会有压缩,文件体积小记录命令,文件体积很大
宕机恢复速度很快
数据恢复优先级低,因为数据完整性不如AOF高,因为数据完整性更高
系统资源占用高,大量CPU和内存消耗低,主要是磁盘IO资源,但AOF重写时会占用大量的CPU和内存资源
使用场景可以容忍数分钟的数据丢失,追求更快的启动速度对数据安全性要求较高常见