Redis如何实现持久化?
Redis持久化
在Redis中提供了两种持久化方式:1、RDB 2、AOF
RDB
RDB全称Redis Database Backup file(Redis数据备份文件),也被叫做Redis数据快照。简单来说就是把内存中的所有数据都记录到磁盘中。当Redis示例故障重启后,从磁盘读取快照文件,恢复数据。
主动备份
以上两种方式都可以手动的执行RDB文件的生成。
触发RDB机制
Redis内部有触发RDB的机制,在redis.conf配置文件中,有如下配置:
Shell
# 配置rdb
# 15分钟内有至少1个key被更改则进行快照
save 900 1
# 5分钟内有至少10个key被更改则进行快照
save 300 10
# 1分钟内有至少10000个key被更改则进行快照
save 60 10000
RDB的执行原理
bgsave命令执行时会fork主进程得到子进程,子进程共享主进程的内存数据。完成fork后读取内存数据并写入RDB文件。
页表
首先Redis主进程对数据进行读写操作是在内存中的,在Linux系统中,所有的进程无法直接操作物理内存,Linux给每个进程分配了虚拟内存,主进程只能操作虚拟内存,操作系统会维护一个虚拟内存和物理内存的映射关系表---页表。页表记录了虚拟地址与物理地址的映射关系,这样主进程就可以完成对物理内存的读写操作。
流程介绍
- 当执行bgsave命令时,会fork(克隆)一个子进程,子进程并不是对物理内存数据做拷贝,在fork时,仅仅把页表进行了拷贝,此时完成了子进程与主进程的内存空间共享。
- 子进程读取到内存数据后,把数据写入到磁盘中,新的RDB文件会替换旧RDB文件。(此时已完成异步持久化已完成了,但是子进程写RDB文件时,主进程仍然可以写数据,此时可能会出现冲突。Redis解决方式:)
- fork采用的是copy-on-write技术,fork子进程时,会将内存中的数据标记为read-only,任何进程只能读,不能写。
- 当主进程要写数据时,先拷贝一份数据,完成拷贝后,再对拷贝的数据完成写的操作,主进程读的操作也会读取拷贝的数据,主进程页表也会映射到拷贝的数据(子进程对旧页表进行持久化)。
AOF
AOF全称为Append Only File(追加文件)。Redis处理的每一个写命令都会记录在AOF文件,可以看做是命令日志文件。
原理
AOF会将每一次写操作的命令记录到AOF文件中。
AOF默认是关闭的,需要修改redis.conf配置文件来开启AOF:
Shell
# 开启aof
appendonly yes
# 文件名
appendfilename "appendonly.aof"
AOF的命令记录的频率也可以通过redis.conf文件来配:
Shell
# 表示每执行一次写命令,立即记录到AOF文件
appendfsync always
# 写命令执行完先放入AOF缓冲区,然后表示每隔1秒将缓冲区数据写到AOF文件,是默认方案
appendfsync everysec
# 写命令执行完先放入AOF缓冲区,由操作系统决定何时将缓冲区内容写回磁盘
appendfsync no
bgrewriteaof命令
因为AOF时记录命令,AOF文件会比RDB文件大很多。而且AOF会记录对同一个key的多次操作,但只有最后一次操作有意义。通过bgrewriteaof命令,可以让AOF文件执行重写功能,用最少得命令达到相同的效果。
Redis也会在触发阈值时去重写AOF文件,阈值也可以在redis.conf中配置:
Shell
# AOF文件比上次文件 增长超过多少百分比则触发重写
auto-aof-rewrite-percentage 100
# AOF文件体积最小多大以上才触发重写
auto-aof-rewrite-min-size 64mb
RDB与AOF对比
RDB和AOF各有自己的优缺点,如果对数据安全性要求较高,在实际开发中往往会结合两者来使用。
此博客项目中Redis采用两种持久化方式结合使用的。