redis持久化
redis是内存数据库,如果不将内存中的数据状态保存的磁盘,那么一旦服务器宕机,服务器中的数据库状态也会消失,所以redis提供了持久化功能。
RDB和AOF
我们既可以把redis理解为缓存技术,也可以理解为数据库,因为redis支持将内存中的数据周期性的写入磁盘或者把操作追加到记录文件中,这个过程称为redis的持久化。redis支持两种方式的持久化,一种是快照方式(snapshotting),也称RDB方式;两一种是追加文件方式(append-only file),也称AOF方式。RDB方式是redis默认的持久化方式。
什么是RDB
在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是snapshot快照,它恢复时是将快照文件直接读入内存里
Redis会单独创建一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件,整个过程中,主线程是不进行任何io操作的,这就确保了极高的性能,如果需要进行大规模数据的恢复,且对于数据的恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效,RBD的缺点是最后一次持久化后的数据可能丢失,我们默认的就是RDB,一般情况下不需要修改这个配置 !一般在生产环境中会将这个文件进行备份。

redis 回写数据库 redis数据恢复原理_数据

演示rdb方式的持久化
1.修改redis.conf文件

#save 900 1
#save 300 10
#save 60 10000
#只要60秒内修改了5次,就触发保存rdb文件操作
save 60 5
#以下为默认配置
appendonly no
dbfilename dump.rdb
dir  ./   #rdb文件默认放在安装根路径

2.启动redis

//启动redis服务端
redis-server redis.conf
//启动客户端
redis-cli -p 6379

3.set五条数据

127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> 
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

查看rdb文件的保存位置

127.0.0.1:6379> config get dir
1) "dir"
2) "/opt/redis/redis-5.0.5"
127.0.0.1:6379>

redis 回写数据库 redis数据恢复原理_redis 回写数据库_02


4.此时退出redis

127.0.0.1:6379> shutdown
not connected> exit

5.然后再次连接,查看数据。
发现数据已经恢复。

127.0.0.1:6379> keys *
1) "k3"
2) "k1"
3) "k5"
4) "k4"
5) "k2"
127.0.0.1:6379>

另一种情况,使用flushall命令清空了数据库,然后对数据进行恢复。
6.对rdb文件备份

mv dump.rdb dump.rdb.bak

7.清空整数数据库并退出

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> shutdown
not connected> exit

在清空数据库的同时也会生成一个dump.rdb文件
8.重新连接redis,发现没有数据

root@hecs-x-medium-2-linux-20200428093220:/opt/redis/redis-5.0.5# redis-server redis.conf 
root@hecs-x-medium-2-linux-20200428093220:/opt/redis/redis-5.0.5# redis-cli -p 6379
127.0.0.1:6379> keys *
(empty list or set)

原因是清空后数据库后有一个空的备份文件,此时我们删除dump.rdb文件,把dump.rdb.bak改为dump.rdb

redis 回写数据库 redis数据恢复原理_redis 回写数据库_03

rm dump.rdb
mv dump.rdb.bak dump.rdb

9.再次重启redis,查看数据
数据已经恢复

127.0.0.1:6379> keys *
1) "k3"
2) "k1"
3) "k5"
4) "k4"
5) "k2"
127.0.0.1:6379>

rdb总结
触发规则
1.save的规则满足的情况下,会自动出发rdb规则
2.执行flushall 命令,也会出发rdb规则
3.退出redis,也会产生rdb文件
rdb优缺点
优点:

  1. 大规模的数据恢复可以优先考虑
  2. 对数据的完整性要求不高也可以使用

缺点:

  1. 需要一定的时间间隔进行操作 ! 如果redis意外宕机了,这个最后一次修改的数据就没有了 !
  2. fork进程的时候, 会占用一定的内存空间

什么是AOF

将我们的所以命令都记录下来,好比一个history ,恢复的时候就把这个文件全部的执行一遍即可。

以日志的形式去记录每个写的操作,将redis执行的所有指令记录下来,只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作

redis 回写数据库 redis数据恢复原理_redis 回写数据库_04


演示aof方式的持久化

1.修改配置文件

# AOF and RDB persistence can be enabled at the same time without problems.
# If the AOF is enabled on startup Redis will load the AOF, that is the file
# with the better durability guarantees.
#
# Please check http://redis.io/topics/persistence for more information.
#启用AOF方式 默认是no不开启的我们需要修改
appendonly yes
#每次有新命令追加到 AOF 文件时就执行一次 fsync :非常慢,也非常安全
appendfsync always
#每秒 fsync 一次:足够快(和使用 RDB 持久化差不多),并且在故障时只会丢失 1 秒钟的数据
appendfsync everysec
#从不 fsync :将数据交给操作系统来处理。更快,也更不安全的选择
appendfsync no

从上面三种AOF持久化时机来看,为了保证不丢失数据,appendfsync always是最安全的。

配置修改后重启aof就会生效。

操作和rdb类似这里不再演示

appendonly.aof文件记录的都是写操作的命令。

如果appendonly.aof被破坏了 (比如使用vim对此文件编辑) redis是无法启动的,

redis 回写数据库 redis数据恢复原理_数据_05


这时需要对文件进行修复

修复的方法是使用redis-check-aof修复器。

redis-check-aof - - fix appendonly.aof

redis-check-aof --fix ./data/appendonly.aof

以下输出表示修复成功。

redis 回写数据库 redis数据恢复原理_持久化_06


如果文件修复正常,重启数据即可恢复

aof优缺点

优点 :

每一次修改都同步,文件的完整会更加好!

每秒同步一次,可能会丢失一秒的数据。

如果从不同步,效率最高。

缺点 :

相对于数据文件来说,aof远远大于rdb,修复的速度比rdb慢 !

aof运行效率比rdb慢,因为是io读取的操作, 所以redis默认使用rdb进行持久化。

总结
redis的恢复时机
• 如果只配置 AOF ,重启时加载 AOF 文件恢复数据;
• 如果同时配置了 RDB 和 AOF ,启动是只加载 AOF 文件恢复数据;
• 如果只配置 RDB,启动是将加载 dump 文件恢复数据。

扩展
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%大小重写可以改到适当的数值。
如果不开启 AOF ,仅靠Master-Slave Repllcation实现高可用性也可以,能省掉一大笔10,也减少了rewrite时带来的系统波动。代价是如果Master/Slave同时倒掉,会丢失十几分钟的数据,启动脚本也要比较两个Master/Slave中的RDB文件,载入较新的那个,微博就是这种架构。