redis身为内存数据库,它将数据以key-value键值对的形式存入内存中,使我们可以更快的访问数据,但是当我们redis挂了,我们内存中的数据又该如何恢复,这需要redis的持久化模式
redis持久化方式
1.RDB(快照方式)
能够在指定的时间间隔能对你的数据进行快照存储,也是redis默认的持久化方式
2.AOF
记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据
RDB
在默认情况下,Redis 将数据库快照保存在名字为 dump.rdb的二进制文件中,你可以对 Redis 进行设置, 让它在“ N 秒内数据集至少有 M 个改动”这一条件被满足时, 自动保存一次数据集。你也可以通过调用 SAVE或者 BGSAVE , 手动让 Redis 进行数据集保存操作,在redis.conf中,默认的配置方式如下:
# 指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合
# 这里表示900秒(15分钟)内有1个更改,300秒(5分钟)内有10个更改以及60秒内有10000个更改
# 如果想禁用RDB持久化的策略,只要不设置任何save指令,或者给save传入一个空字符串参数也可以
save 900 1
save 300 10
save 60 10000
这种持久化方式被称为快照 snapshotting.
RDB工作方式
当 Redis 需要保存 dump.rdb 文件时, 服务器执行以下操作:
- Redis 调用forks. 同时拥有父进程和子进程。
- 子进程将数据集写入到一个临时 RDB 文件中。
- 当子进程完成对新 RDB 文件的写入时,Redis 用新 RDB 文件替换原来的 RDB 文件,并删除旧的 RDB 文件。
RDB的优缺点
优点:由于RDB方式是使用二进制方式存储,所以恢复数据时RDB的方式会更快一点
缺点:RDB方式由于需要触发条件才能进行自动保存,当redis意外停止工作时,我们可能会丢失几分钟的数据
AOF
指定更新日志条件,共有3个可选值(三选一):
# no:表示等操作系统进行数据缓存同步到磁盘(快,持久化没保证)
# always:同步持久化,每次发生数据变更时,立即记录到磁盘(慢,安全)
# everysec:表示每秒同步一次(默认值,很快,但可能会丢失一秒以内的数据)
appendfsync always
appendfsync everysec
appendfsync no
推荐(并且也是默认)的措施为每秒 fsync 一次, 这种 fsync 策略可以兼顾速度和安全性。
aof文件记录每一步写操作
AOF工作原理
- Redis 执行 fork() ,现在同时拥有父进程和子进程。
- 子进程开始将新 AOF 文件的内容写入到临时文件。
- 对于所有新执行的写入命令,父进程一边将它们累积到一个内存缓存中,一边将这些改动追加到现有 AOF 文件的末尾,这样样即使在重写的中途发生停机,现有的 AOF 文件也还是安全的。
- 当子进程完成重写工作时,它给父进程发送一个信号,父进程在接收到信号之后,将内存缓存中的所有数据追加到新 AOF 文件的末尾。
- 搞定!现在 Redis 原子地用新文件替换旧文件,之后所有命令都会直接追加到新 AOF 文件的末尾。
大概就是redis每一次写操作都会将该操作放到os cache,然后到了1秒进行同步操作的时候,强制将os cache中的数据刷入到磁盘文件中
AOF优缺点
优点:使用默认的每秒fsync策略,Redis的性能依然很好(fsync是由后台线程进行处理的,主线程会尽力处理客户端请求),一旦出现故障,你最多丢失1秒的数据
缺点:对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积。
如果我们同时设置RDB和AOF两种持久化方式,redis会优先选择AOF的方式来还原数据,而不使用RDB方式
如果我们需要用AOF来还原数据,注意,我们在redis客户端设置
config set appendonly yes
当redis重启启动之前,我们需要修改redis.conf文件中appendonly参数改为yes,否则重启还是按照RDB方式重启