文章目录
前言
- Redis 是 内存数据库,如果不将内存中的数据库状态保存到磁盘,那么一旦服务器进程退出,服务器中的数据库状态也会消失。所以 Redis 提供了持久化功能
1. RDB(Redis DataBase)
-
在 指定的时间间隔内 将 内存中的数据集 快照 写入磁盘,也就是行话讲的 Snapshot 快照,它 恢复时 是 将快照文件直接读到内存里
-
rdb 保存的文件是 dump.rdb
1.1 内部实现原理
-
父进程:fork子进程后,继续处理 客户端 写数据操作,整个过程中,主进程是不进行任何 IO 操作的
-
子进程:先将数据 写入到一个临时文件中,待持久化 过程都结束了,再用这个临时文件替换上次持久化好的文件
1.2 何时触发?
save 60 5 # 60s 内修改了 5次 key,就会触发 rdb 操作
save
的规则满足的情况下,会自动触发rdb
规则- 执行
flushall
命令,也会触发我们的rdb
规则 - 退出
redis
,会自动生成一个rdb
文件
1.3 如果恢复 rdb 文件?
-
只需要将
rdb
文件放在我们redis
启动目录就可以,redis
启动的时候会自动检查dump.rdb
并恢复其中的数据 -
查看 需要存在的位置:
127.0.0.1:6379> config get dir
1.4 优缺点
优点:
- 适合 大规模的 数据恢复
- 对 数据的完整性 要不高
缺点:
- 需要 一定的时间间隔进程操作;如果
redis
意外宕机了,这个 最后一次修改数据就没有的了 fork
进程的时候,会 占用一定的内存空间
2. AOF(Append Only File)
Aof
保存的是appendonly.aof
文件
2.1 内部原理
-
以 日志的形式来记录每个写操作,将
Redis
执行过的所有指令记录下来(读操作不记录),只许追加文件但不可以改写文件 -
redis
启动之初会读取该文件重新构建数据,换言之,redis
重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作
2.2 开启
- 默认是不开启的:将配置文件中
appendonly
改为yes
即可 - 重启,
redis
就可以生效了
如果这个 aof 文件有错位,这时候 redis 是启动不起来的,我们需要 修复这个 aof 文件
-
redis
给我们提供了一个工具redis-check-aof --fix
执行:
redis-check-aof --fix appendonty.aof
2.3 重写规则说明
aof
默认就是 文件的无限追加,文件会越来越大
修改配置: 如果aof
文件大于64m
,fork
一个新的进程来将我们的文件进行重写
no-appendfsync-on-rewrite no
..
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
同步方式配置:
appendonly no # 默认是不开启 aof 模式的,默认是使用 rdb 方式持久化的,在大部分所有的情况下, rdb完全够用!
appendfilename "appendonly.aof" # 持久化的文件的名字
# appendfsync always # 每次修改都会 sync。消耗性能
appendfsync everysec # 每秒执行一次 sync,可能会丢失这1s的数据!
# appendfsync no # 不执行 sync,这个时候操作系统自己同步数据,速度最快!
# rewrite 重写
2.4 优缺点
优点:
- 每一次修改都同步,文件的完整会更加好
- 每秒同步一次,可能会丢失一秒的数据
- 从不同步,效率最高的
缺点:
- 相 对于数据文件来说,aof 远远大于 rdb,修复的速度也比 rdb 慢
- Aof 运行效率也要比 rdb 慢,所以我们 redis 默认的配置就是 rdb 持久化
3. 同时开启两种持久化方式
在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF
文件保存的数据集要比RDB文件保存的数据集要完整。
RDB 的数据不实时,同时使用两者时服务器重启也只会找AOF文件,那要不要只使用AOF呢?作者
建议不要,因为RDB更适合用于备份数据库(AOF在不断变化不好备份),快速重启,而且不会有
AOF可能潜在的Bug,留着作为一个万一的手段。
4. 性能建议
- 因为 RDB 文件只用作后备用途,建议只在 Slave 上持久化 RDB 文件,而且只要 15分钟备份一次就够了,只保留 save 900 1 这条规则。
- 如果 Enable AOF,好处是在最恶劣情况下也只会丢失不超过两秒数据,启动脚本较简单只 load 自己的 AOF 文件就可以了,代价一是带来了持续的 IO,二是 AOF rewrite 的最后将 rewrite 过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。只要硬盘许可,应该尽量减少 AOF rewrite 的频率,AOF 重写的基础大小默认值 64M 太小了,可以设到 5G 以上,默认超过原大小100%大小重写可以改到适当的数值。
- 如果不 Enable AOF ,仅靠 Master-Slave Repllcation 实现高可用性也可以,能省掉一大笔 IO,也减少了 rewrite 时带来的系统波动。代价是如果 Master / Slave 同时倒掉,会丢失十几分钟的数据,启动脚本也要比较两个 Master / Slave 中的 RDB文件,载入较新的那个,微博就是这种架构。