Redis的持久化有两种方式:RDB和AOF
RDB原理是将Redis在内存中的数据记录定时dump到磁盘上。
1> 快照文件称为RDB文件,默认是保存在当前运行目录,也可在redis.conf中配置
#是否压缩,建议不开启,压缩也会消耗cpu,磁盘的话不值钱
rdbcompression yes
#RDB文件名称
dbfilename dump.rdb
#文件保存的路径目录
dir ./
2> RDB会在什么时候执行?
自动触发:
默认是服务停止时:Redis停机时会执行一次RDB,当Redis实例故障重启后,从磁盘读取快照文件,恢复数据。
save m n :在m秒内,如果有n个键发生改变,则自动触发持久化,通过bgsave执行,如果设置多个、只要满足其—就会触发,配置文件有默认配置(可以注释掉)
save 900 1 #900秒内,如果至少有1个key被修改,则执行bgsave
save 300 10 #300秒内,如果至少有10个key被修改,则执行bgsave
save “” #禁用RDB
flushall:用于清空redis所有的数据库,flushdb清空当前redis所在库数据(默认是0号数据库),会清空RDB文件,同时也会生成dump.rdb、内容为空
主从同步:全量同步时会自动触发bgsave命令,生成rdb发送给从节点
手动触发:
[root@localhost ~]# redis-cli
127.0.0.1:6379> save
127.0.0.1:6379> bgsave
Background saving started
fork底层实现:
进程操作的数据存储在物理内存上,但是所有进程不能直接操作物理内存,而是操作系统给每个进程分配虚拟内存,虚拟内存映射物理内存,进程只能操作虚拟内存,操作系统通过页表维护虚拟内存,进程基于页表到物理内存中读写数据。fork过程不是将内存数据拷贝一份给子进程,这样速度慢影响主进程效率,而是将主进程的页表拷贝一份给子进程,并将数据设置为只读,这样子进程也能和主进程操作同一片物理内存,从而实现与主进程空间共享。无需拷贝所有数据给子进程,速度快,主进程阻塞时间短。然后子进程就可以根据页表读取内存中数据写如磁盘,替换旧备份文件。
子进程备份时主进程对数据进程改动,采用的是copy-on-write技术:
- 当主进程执行读操作时,访问共享内存
- 当主进程执行写操作时,则会涉及写操作的内存页,在新复制的内存页上进行写操作
RDB方式bgsave的基本流程:
RDB的缺点?
因为RDB执行间隔时间长,两次RDB之间写入数据时如果发生宕机,有数据丢失风险
fork子进程、压缩、写出RDB文件都比较耗时
AOF全称为Append Only File(追加文件)。Redis每一个写命令都会以追加方式记录在AOF文件
1> AOF默认是关闭的,需要修改redis.conf配置文件来开启AOF:
#是否开启AOF功能,默认是no
appendonly yes
#AOF文件的名称
appendfilename "appendonly.aof"
2> AOF同步策略,可通过redis.conf文件来配置:
#表示每执行一次写命令,立即记录到AOF文件,最多丢—条
appendfsync always
#写命令执行完先放入AOF缓冲区,然后表示每隔1秒将缓冲区数据写到AOF文件,是默认方案,一旦系统出现宕机现象,那么这一秒钟之内修改的数据将会丢失
appendfsync everysec
#写命令执行完先放入AOF缓冲区,由操作系统决定何时将缓冲区内容写回磁盘,可能丢失较多数据
appendfsync no
配置项 | 刷盘时机 | 优点 | 缺点 |
---|---|---|---|
Always | 同步刷盘 | 可靠性高,几乎不丢数据 | 性能影响大 |
everysec | 每秒刷盘 | 性能适中 | 最多丢失1S数据 |
no | 操作系统控制 | 性能最好 | 可靠性较差,可能丢失大量数据 |
3> AOF重写:AOF因为是记录命令,文件比RDB大的多。而且AOF会记录对同一个key的多次写操作,但只有最后一次写操作才有意义。通过执行bgrewriteaof命令,可以让AOF文件执行重写功能,用最少的命令达到相同效果。
Redis也会在触发阈值时自动去重写AOF文件。阈值也可以在redis.conf中配置:
#AOF文件比上次文件增长超过多少百分比则触发重写
auto-aof-rewrite-percentage 100
#AOF文件体积最小多大以上才触发重写
auto-aof-rewrite-min-size 64mb
AOF | RDB对比:
RDB | AOF | |
---|---|---|
持久化方式 | 定时对整个内存做快照 | 记录每一次执行的命令 |
数据完整性 | 不完整,两次备份之间会丢失 | 相对完整,取决于刷盘策略 |
文件大小 | 会有压缩,文件体积小 | 记录命令,文件体积大 |
宕机恢复速度 | 很快 | 慢 |
数据恢复优先级 | 低,数据完整性不如AOF | 高,数据完整性更高 |
系统资源占用 | 高,大量CPU和内存消耗。fork子进程、压缩、写出RDB文件都比较耗时,当数据集很大时,可能导致整个服务器停止服务几百毫秒,甚至1秒钟。 | 低,主要是磁盘IO资源,但AOF重写时会占用大量CPU和内存资源 |
使用场景 | 可以容忍数分钟的数据丢失,追求更快的启动速度 | 对数据安全性要求较高的场景 |
RDB和AOF各有自己的优缺点,使用 RDB 持久化会有数据丢失的风险,但是恢复速度快,而使用 AOF 持久化可以保证数据完整性,但恢复数据的时候会很慢。于是从 redis4 之后新增了混合 AOF 和 RDB 的模式:RDB做全量备份,在RDB备份期间的写操作记录到AOF文件中,即AOF做增量持久化。
当重写策略满足或手动触发重写的时候,fork
一个子线程将内存数据以 RDB 二进制格式写入 AOF 文件头部,那些在重写操作执行之后执行的 redis 命令,则以 AOF 持久化的方式追加到 AOF 文件的末尾。
这样的话,重启服务时会通过RDB 文件来重新构建内容,再使用 AOF 来重新执行近期的写指令,既保证了数据完整性,又提高了恢复的性能。
aof-rdb 持久化机制默认是没有开启的,需要在 redis.conf
配置文件中配置开启,并开启 AOF 持久化。
# 混合持久化开关
aof-use-rdb-preamble yes