redis是面试中最常问的中间件,其中一个性价比比较高的学习点是redis的持久化,大概十分钟就可以有理有据的答上来一道面试题,还是值得学习一下的。redis的持久化方式有两种,一种是RDB持久化,一种是AOF持久化。那么这两种持久化方式怎么配置,怎么使用,他们之间的区别是什么呢?我们来具体的说一下。1、RDB快照(snapshot)
这个是指redis把数据以快照的方式保存在磁盘上。默认的情况下,redis将数据保存在文件名为dump.rdb的二进制文件中。redis在运行时,会把内存中的数据快照保存到磁盘上,在redis重启时,会从rdb文件中读取数据还原redis数据库的状态。rdb触发机制
save命令
save命令是同步命令,在save执行时,会占用主进程,导致redis其他命令无法使用。在数据量过大时,可能会导致redis反应变慢。bgsave命令
bgsave命令是异步操作,执行bgsave命令保存快照,可以在生成快照的同时,依然可以正常处理其他命令。简单来说,bgsave子进程是由主线程fock生成的,它不影响主进程的执行,同时还可以共享主进程的数据。save和bgsave对比:
命令 | save | bgsave |
IO类型 | 同步 | 异步 |
是否阻塞redis | 是 | 是(在生成子进程时有短暂阻塞,速度很快,基本没有影响) |
复杂度 | O(n) | O(n) |
优点 | 不消耗额外内存 | 不阻塞客户端 |
缺点 | 阻塞客户端命令 | 需要fork子进程,消耗内存 |
通过配置自动配置
可以通过修改配置文件对redis进行设置,比如可以设置让它在“ N 秒内数据集至少有 M 个改动”这一条件被满足时, 自动保存一次 数据集。比如说, 以下设置会让 Redis 在满足"60 秒内有至少有 1000 个键被改动"这一条件时,自动保存一次数据集:# save 60 1000 关闭RDB只需要将所有的save保存策略注释掉即可PS:配置自动生成rdb文件后台使用的bgsave,相关配置如下所示:# RDB自动持久化规则
# 当 900 秒内有至少有 1 个键被改动时,自动进行数据集保存操作
save 900 1
# 当 300 秒内有至少有 10 个键被改动时,自动进行数据集保存操作
save 300 10
# 当 60 秒内有至少有 10000 个键被改动时,自动进行数据集保存操作
save 60 10000
# RDB持久化文件名
dbfilename dump.rdb
# 数据持久化文件存储目录
dir /var/lib/redis
# bgsave发生错误时是否停止写入,通常为yes
stop-writes-on-bgsave-error yes
# rdb文件是否使用压缩格式
rdbcompression yes
# 是否对rdb文件进行校验和检验,通常为yes
rdbchecksum yes
2、AOF
由于RDB快照方式可能遇到一些问题,比如说redis因为某些原因造成故障停机,那么服务器会丢失掉最近写入的,还没来得及保存快照的数据。因此,redis增加了一种持久化方式AOF。AOF是通过将修改的每一条指令写入一个记录文件件appendonly.aof中(先写入os cache,每隔一段时间 fsync到磁盘)。这样子的话,在redis重启时,可以通过读取指令来重新写入数据达到重建数据库的目的。AOF持久化的三种策略
可以通过修改配置文件来打开AOF功能,命令如下:
appendonly yes
同时也可以通过配置多久将数据fsync 到磁盘一次。有三个选项:appendfsync always:每次有新命令追加到 AOF 文件时就执行一次 fsync ,非常慢,也非常安全。
appendfsync everysec:每秒 fsync 一次,足够快,并且在故障时只会丢失 1 秒钟的数据。
appendfsync no:从不 fsync ,将数据交给操作系统来处理。更快,也更不安全的选择。推荐(并且也是默认)的措施为每秒 fsync 一次, 这种 fsync 策略可以兼顾速度和安全性。
举例:当开启AOF后,比如我往redis内存储一条数据 set test 111,对应的AOF文件里会有一条记录数据,如下所示:
这是一种resp协议格式数据,星号后面的数字代表命令有多少个参数,$号后面的数字代表这个参数有几 个字符。
AOF重写
由于AOF不断的将命令追加到文件的末尾,因此随着命令的不断增加,AOF文件的体积会变的越来越大。比如说,执行INCR命令执行了100次,在AOF内会生成100个操作命令。但实际上来说,只需要一个SET到当前值的命令就可以存储了,前面的99次INCR都是无意义的。实际上可能不止这一种多余的废操作,因此Redis可以对AOF文件进行重写,会把命令进行精简整合成一个新的AOF文件,新的文件里包含生成当前数据的最少命令。可以通过bgrewriteaof命令重写AOF,也可以通过配置文件配置AOF文件的自动重写。


3、RBD和AOF比较
这里对RDB和AOF进行一下比较,首先说一下各自的优缺点。
RDB:
1、优点:
文件紧凑,很适合进行数据备份和容灾恢复
恢复大量数据时RDB速度快
2、缺点:
AOF:
1、优点:
2、缺点
对比表格:
| RBD | AOF |
启动优先级 | 低 | 高 |
体积 | 小 | 大 |
恢复速度 | 快 | 慢 |
数据安全性 | 可能丢失数据 | 由策略决定,每秒fsync最多丢失1s数据 |
如何选择使用哪种方式:
使用可以根据需要来自行选择,如果对数据丢失不敏感的,使用rdb即可。当然在生产环境使用时,可以两种方式都启用。rdb文件可以用来做备份,aof文件来保证数据的安全性。
4、混合模式
在redis4.0之后,出现了一个新的持久化选项——混合持久化。可以通过以下配置开启混合持久化(必须先开启AOF)aof‐use‐rdb‐preamble yes
开启混合持久化后,AOF在重写时,不是单纯的把命令写入AOF文件,而是把重写这一刻之前的内存数据做RDB快照处理,在重写之后的还是继续使用AOF命令的形式保存。这样aof文件里就有历史的RDB快照和增量的AOF命令。我们知道,RDB文件的恢复速度比AOF快的多,因此这种混合的模式,在redis重启的时候能大大提升效率。5、End
诚招:票圈点赞工程师

对了,如果一个人(水哥)不厌其烦的向你传授知识,那他就是你的老师,为老师点个赞+在看+收藏+分享+评论夸两句 实在在是不过分阿不过分