七、 Redis持久化
Redis是内存数据库,如果不讲内存中的数据库状态保存在磁盘中,那么一旦服务器进程退出,服务器中的数据库状态也会消失。所以Redis 提供了持久化的功能
7.1 RDB (Redis DataBase)
什么是 RDB
在主从复制中,rdb就是备用的
在指定的时间间隔内,将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot 快照,它恢复时是将快照文件直接读到内存里
运行原理
Redis会单独创建(fork)一个子进程进行持久化,会将数据写入到一个临时的文件中,待持久化过程结束之后,在用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不会进行任何 IO 操作的,这就确保了极高的性能。如果需要进行过大规模的恢复,且对于数据恢复的完整性不是非常敏感,那 RDB 方式要比 AOF 方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失
有时候在生产环境中需要进行备份
rdb 保存的文件是dump.db,在配置文件中的快照 snapshot 区域进行配置
在/usr/local/bin/config/
修改redis.conf
# 快速修改5个key
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k2 v2
OK
127.0.0.1:6379> set k3 v3
OK
127.0.0.1:6379> set k4 v4
OK
127.0.0.1:6379> set k5 v5
OK
# 然后关闭服务并退出
127.0.0.1:6379> shutdown
not connected> exit
# 清空数据,也会产生一个rdb文件
127.0.0.1:6379> FLUSHALL
OK
触发规则
save
- save规则满足的情况下,会自动触发 rdb 规则
- 执行 flushall 命令
- 退出redis,也会产生一个rdb文件
- 该命令会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,直到RDB过程完成为止
- 执行完成时候如果存在老的RDB文件,就把新的替代掉旧的。我们的客户端可能都是几万或者是几十万,这种方式显然不可取
bgsave
- 执行该命令时,Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求
- 具体操作是Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束
- 阻塞只发生在fork阶段,一般时间很短。基本上 Redis 内部所有的RDB操作都是采用 bgsave 命令
如何恢复rdb文件
只需要将rdb文件放在redis启动目录,redis启动的时候会自动检查dump.rdb
,恢复其中的数据
# 查看需要存在的位置
127.0.0.1:6379> config get dir
1) "dir"
2) "/usr/local/bin"
优点
- RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快
- RDB文件紧凑,全量备份,非常适合用于进行备份和灾难恢复
- 生成RDB文件的时候,redis主进程会fork()一个子进程来处理所有保存工作,主进程不需要进行任何磁盘IO操作
缺点
- 需要一定的时间间隔进程操作,如果redis意外宕机了,这个最后一次修改数据就没有了
- fork进程的时候,会占用一定的内容空间
7.2 AOF (Append Only File)
AOF 是什么
将我们所有命令记录下来,history,恢复的时候就把这个文件全部在执行一遍
运行原理
以日志的形式来记录每个写操作,将Redis执行过的所有指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作
AOF保存的是 appendonly.aof文件
append
默认是不开启的,需要手动进行配置!只需要 appendonly 设置为 yes 就开启了 aof
修改完后,重启即可生效
如果 aof 文件有错误,这时候 redis 是启动不起来的,需要修复这个 aof 文件
redis 提供了一个工具redis-check-aof
# 修复指令
redis-check-aof --fix appendonly.aof
如果文件正常,重启就可以直接恢复
重写规则
aof 默认就是文件的无线追加,文件会越来越大!
如果 aof 文件大于64m,父进程就会fork一个新的进程来将文件进行重写
优点
- 每一次修改都同步,文件的完整会更加好
- AOF日志文件即使过大的时候,出现后台重写操作,也不会影响客户端的读写
- AOF可以更好的保护数据不丢失,一般 AOF 会每隔1秒,通过一个后台线程执行一次fsync操作,最多丢失1秒钟的数据
- AOF日志文件没有任何磁盘寻址的开销,写入性能非常高,文件不容易破损
- AOF日志文件的命令通过非常可读的方式进行记录,这个特性非常适合做灾难性的误删除的紧急恢复
缺点
- 相对于数据文件来说,AOF远远大于 RDB,修复的速度也比 RDB 慢
- AOF 运行效率也比 RDB 慢,所以redis默认的配置就是 RDB持久化
- AOF因为是就操作进行记录,所以很容易被其他人进行破解,从而对数据进行分析
扩展
1、RDB持久化方式能够在指定的时间间隔内对你的数据进行快照存储
2、AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以 Redis 协议追加保存每次写的操作到文件末尾,Redis还能对 AOF 文件进行后台重写,使得 AOF 文件的体积不至于过大
3、只做缓存。如果你希望你的数据在服务器运行的时候存在,可以不使用任何持久化
4、同时开启两种持久化方式
- 这种情况下,当 redis 重启的时候会优先载入 AOF 文件来恢复原始的数据,因为在通常情况下 AOF 文件保存的数据集比 RDB 文件保存的数据集要完整
- RDB 的数据不实时,同时使用两者时服务器重启也只会找 AOF 文件。如果只使用 AOF 呢?作者建议不要,因为 RDB 更适合用于备份数据库(AOF在不断变化不好备份),快速重启,而且不会有 AOF 可能潜在的 Bug ,留着作为一个万一的手段
5、性能建议
-
因为 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 Replication 实现高可用性也可以,能省掉一大笔IO,也减少了 rewrite 时带来的系统波动。代价时如果Master/Slave同时倒掉,会丢失十几分钟的数据,启动脚本也要比较两个 Master/Slave 中的 RDB 文件,载入较新的那个