Redis系列(五)-Redis的持久化(一篇文章让你了解Redis的RDB和AOF持久化)

持久化作用

Redis 是内存数据库,断电及失,因此需要持久化,默认使用RDB,一般情况下我们无需修改RDB配置,即可使用。

RDB (Redis DataBase)
什么是RDB

Redis会单独创建一个fork子进程来进行持久化,子进程中循环所有的数据,将数据写入到二进制文件中,会先将数据 写入到一个临时文件中,待持久化过程都结束了,在用这个临时文件替换上次持久化好了的文件。整个过程中,主进程是不进行任何IO操作的,确保极高的性能,如果需要进行大规模数据的回复,且对数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加高效。RDB的去电就是最后一次持久化后的数据可能丢失。

流程图:
Redis系列(五)-Redis的持久化(一篇文章让你了解Redis的RDB和AOF持久化)
rdb保存的文件默认是dump.rdb都是可以再配置文件得快照中进行配置的。
Redis系列(五)-Redis的持久化(一篇文章让你了解Redis的RDB和AOF持久化)

RDB触发机制

1、配置文件save的规则满足的情况下,会自动触发rdb,生成rdb文件。

2、执行flushall命令也会触发rdb,自动生成一个生成rdb文件。

3、退出redis,输入命令shutdown,就会关闭redis服务,这个时候也会生成rdb文件。

恢复RDB文件

1、只需要将rdb文件放到Redis启动文件夹下面就可以了,Redis启动的时候会自动加载恢复rdb文件。

2、查看我们需要存放的启动文件夹位置

127.0.0.1:6379> config get dir
1) "dir"
2) "/opt/redis-6.2.6"	# 如果再这个目录下存在dump.rdb文件,Redis启动的时候会自动加载恢复数据
RDB优缺点

优点:

1、适合大规模的数据恢复
2、对数据的完整性不高的时候可以使用

缺点:

1、需要一定的时间间隔进行操作,如果redis意外宕机了,最后一次修改的数据就没有了

2、fork进程的时候会占用一定的内存空间

AOF(Append Only File)
什么是AOF

先来一张流程图:
Redis系列(五)-Redis的持久化(一篇文章让你了解Redis的RDB和AOF持久化)
AOF是将我们所有的命令都记录下来,然后在恢复的时候再重新执行一次,并且只记录写操作的命令,读命令不会记录。只追加文件。因此aof的速度会慢一些,尤其是大数据的情况下,恢复数据也需要很久

AOF保存的默认文件是 appendonly.aof
Redis系列(五)-Redis的持久化(一篇文章让你了解Redis的RDB和AOF持久化)
默认是不开启的,我没需要手动的进行配置。然后我们重启一下Redis就可以生效了。

AOF触发机制

1、修改配置文件,重启Redis触发AOF持久化。

2、配置文件appendfsync的规则满足的情况下,会自动触发aof,生成aof文件

# 1、删除appendonly.aof
[root@VM-0-16-centos bin]# ls
appendonly.aof  busybox-x86_64  dump.rdb  redis-benchmark  redis-check-aof  redis-check-rdb  redis-cli  redis.conf  redis-sentinel  redis-server
[root@VM-0-16-centos bin]# rm -rf appendonly.aof 
[root@VM-0-16-centos bin]# ls
busybox-x86_64  dump.rdb  redis-benchmark  redis-check-aof  redis-check-rdb  redis-cli  redis.conf  redis-sentinel  redis-server
# 2、登录redis修改配置文件后重启
[root@VM-0-16-centos bin]# redis-cli -p 6379
127.0.0.1:6379> auth hecan1992
OK
127.0.0.1:6379> SHUTDOWN
not connected> exit
[root@VM-0-16-centos bin]# ./redis-server /opt/redis-6.2.6/redis.conf 
# 3、查看是是否生成了appendonly.aof
[root@VM-0-16-centos bin]# ls
appendonly.aof  busybox-x86_64  dump.rdb  redis-benchmark  redis-check-aof  redis-check-rdb  redis-cli  redis.conf  redis-sentinel  redis-server
# 4、登录redis赋值key
[root@VM-0-16-centos bin]# redis-cli -p 6379
127.0.0.1:6379> auth hecan1992
OK
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> exit
# 5、查看appendonly.aof文件内容
[root@VM-0-16-centos bin]# vim appendonly.aof 

*2
$6
SELECT
$1
0
*3
$3
set
$2
k1
$2
v1
*3
$3
set
$2
k2
$2
v2
*3
$3
set
$2
k3
$2
v3
*3
$3
set
$2
k4
$2
v4

以上我们成功的开启了AOF并且测试生成了appendonly.aof文件,从文件的内容里面可以看出我们记录了k1,k2,k3,k4的命令记录。

AOF的appendonly.aof文件修复功能

我们做一个很有意思的操作,我们将appendonly.aof文件命令的内容给随便改乱,看会发生什么情况?

# 1、查看redis启动目录下的文件并删除dump.rdb
[root@VM-0-16-centos bin]# ls
appendonly.aof  busybox-x86_64  redis-benchmark  redis-check-aof  redis-check-rdb  redis-cli  redis.conf  redis-sentinel  redis-server
[root@VM-0-16-centos bin]# rm -rf dump.rdb 
[root@VM-0-16-centos bin]# ls
appendonly.aof  busybox-x86_64  redis-benchmark  redis-check-aof  redis-check-rdb  redis-cli  redis.conf  redis-sentinel  redis-server
# 2、登录redis客户端将redis服务器关闭
[root@VM-0-16-centos bin]# redis-cli -p 6379
127.0.0.1:6379> auth hecan1992
OK
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> SHUTDOWN
not connected> exit
# 3、修改appendonly.aof,再文件的末尾随便乱加了一些内容
[root@VM-0-16-centos bin]# vim appendonly.aof 
[root@VM-0-16-centos bin]# cat appendonly.aof 
*2
$6
SELECT
$1
0
*3
$3
set
$2
k1
$2
v1
*3
$3
set
$2
k2
$2
v2
*3
$3
set
$2
k3
$2
v3
*3
$3
set
$2
k4
$2
v4
fgGgegsagaggsgdzgggdgq		# 乱加的内容
# 4、重新启动redis,我们发现启动失败了
[root@VM-0-16-centos bin]# ./redis-server /opt/redis-6.2.6/redis.conf 
[root@VM-0-16-centos bin]# ps -ef|grep redis
root     14516 13825  0 09:25 pts/0    00:00:00 grep --color=auto redis

我们发现,当我们将appendonly.aof文件做了修改后,redis是启动不起来的。我们需要修复appendonly.aof文件。

Redis再启动的根目录下,给我们提供了一个修复的工具redis-check-aof

# 1、命令:redis-check-aof --fix appendonly.aof   修复文件
[root@VM-0-16-centos bin]# redis-check-aof --fix appendonly.aof 
0x              8b: Expected prefix '*', got: 'f'
AOF analyzed: size=163, ok_up_to=139, ok_up_to_line=34, diff=24
This will shrink the AOF from 163 bytes, with 24 bytes, to 139 bytes
Continue? [y/N]: y
Successfully truncated AOF
# 2、查看修复后的文件
[root@VM-0-16-centos bin]# cat appendonly.aof 
*2
$6
SELECT
$1
0
*3
$3
set
$2
k1
$2
v1
*3
$3
set
$2
k2
$2
v2
*3
$3
set
$2
k3
$2
v3
*3
$3
set
$2
k4
$2
v4
# 3、我们发现文件已经成功修复,再次测试redis的启动和链接都成功了
[root@VM-0-16-centos bin]# ./redis-server /opt/redis-6.2.6/redis.conf 
[root@VM-0-16-centos bin]# ps -ef|grep redis
root     16926     1  0 09:38 ?        00:00:00 ./redis-server *:6379
root     16957 13825  0 09:38 pts/0    00:00:00 grep --color=auto redis
[root@VM-0-16-centos bin]# redis-cli -p 6379
127.0.0.1:6379> auth hecan1992
OK
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> 

总结:当文件appendonly.aof出现问题的时候,再根目录下我们执行命令:redis-check-aof --fix appendonly.aof可对文件进行修复。

AOF的重写

查看redis.conf配置文件发现:
Redis系列(五)-Redis的持久化(一篇文章让你了解Redis的RDB和AOF持久化)
aof文件是默认的文件无限追加,文件会越来越大。当我们在配置文件中开启文件no-appendfsync-on-rewrite为yes并设置文件尺寸大小时,Redis会自动的检测到aof文件是否大于64M。如果大于64M,Redis会自动的fork一个新的进程来将我们的aof文件进行重写。

AOF优缺点

优点:

1、每一次修改都同步,文件的完整性会更好

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

3、从不同步,效率最高

appendfsync always  #每次修改都会sync 消耗性能
appendfsync everysec  #每秒执行一次sync,可能会丢失这1s的数据
appendfsync no      #不执行sync,这个时候操作系统自己同步数据,速度最快

缺点:

1、相对于数据文件来说,AOF远远大于RDB,修复数据比RDB慢。

2、AOF的运行效率也比RDB慢,所以Redis默认配置是RDB

扩展
  1. RDB持久化方式能够在指定的时间间隔内对你的数据进行快照存储
  2. AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始数据,AOF命令以Redis协议追加保存每次写的操作到文件末尾,Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大
  3. 只做缓存,如果你只希望你的数据在服务器运行的时候存在,完全可以不用任何持久化
  4. 同时开启两种持久化方式
    1:在这种情况下,当redis重启的时候会优先加载AOF文件来恢复数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整
    2:RDB的数据不实时,同时使用两者时服务器重启也只会找AOF文件,那要不要只使用AOF呢?作者建议不要,因为RDB更适合用于备份数据库(AOF在不断变化不好备份),快速重启,而且不会有AOF可能潜在的bug,留着作为一个万一的手段
  5. 性能建议
    1:因为RDB文件只用作后背用途,建议旨在Slave上持久化RDB文件,而且只要15分钟备份一次就够了,只保留save 900 1这条规则
    2:如果Enable AOF,好处是在最恶劣情况下也只会丢失不超过两秒的数据,启动脚本较简单只load自己的AOF文件就可以了,代价一是带来了持续的IO,二是AOF rewriter过程中产生的新数据写到新文件造成的阻塞是不可避免的。只要硬盘许可,应该尽量减少AOF rewrite的频率,AOF重写的基础大小默认值64M太小了,可以射到5G以上,默认超过原大小100%大小重写可以改到适当的数值
    3:如果不Enable AOF,仅靠Master-Slave Repllcation实现高可用也可以,能省掉一大笔IO,也减少了rewrite时带来的系统波动。代价是如果Master/Slave同时倒掉,会丢失十几分钟的数据,启动脚本也要比较Master/slave中的RDB文件,载入较新的那个,微博就是这种架构
鸣谢

本文为狂神说Redis学习笔记

学习地址:https://www.bilibili.com/video/BV1S54y1R7SB?p=28

上一篇:Redis 初见


下一篇:图解Redis持久化底层实现原理——RDB/AOF