一、总体介绍
1.Redis数据安全问题
官网介绍:http://www.redis.io
前面我们提到,Redis是一个缓存中间件,它的最大特点是使用内存从而使其性能强悍。但是使用内存的方式有一个致命的特点就是数据没办法持久化保存。然而Redis持久化存储有两种持久化方案,RDB(Redis DataBase)和 AOF(Append-Only File)。其中RDB是将内存中的数据进行快照存储到磁盘,AOF则为可回放的命令日志记录redis内的所有操作。它们各有特点也相互独立。Redis4之后支持RDB-AOF混合持久化的方式,结合了两者的优点,可以通过 aof-use-rdb-preamble 配置项可以打开混合开关。
2.什么是持久化
将内存中的数据写入到磁盘,永久保存
3.持久化的模式
1.RDB模式
2.AOF模式
二、快照持久化(RDB)概述
RDB(Redis DataBase)是将Redis内存中的数据进行Snaptshot快照存储在磁盘内,是Redis的默认持久化方案。使用RDB持久化默认有三种策略,该持久化策略在redis.conf中可配置,会以一段时间内有指定次数据修改的规则触发快照动作,快照文件名为dump.rdb,该文件默认使用LZF压缩算法 。每当Redis服务重启的时候会从该文件中加载数据进内存。
RDB持久化除了可以根据配置中的策略触发,也可以手动触发,使用save和bgsave命令即可。这两个命令的区别的save会阻塞服务器进程,在进行save的过程中,服务器不能处理任何请求,而bgsave会通过一个子进程在后台处理rdb持久化。事实上save和bgsave调用的都是rdbSave函数,因此Redis不允许save和bgsave同时运行,这也是为了避免出现竞争导致rdb文件数据不准确。
bgsave操作使用CopyOnWrite机制进行写时复制,是由一个子进程将内存中的最新数据遍历写入临时文件,此时父进程仍旧处理客户端的操作,当子进程操作完毕后再将该临时文件重命名为dump.rdb替换掉原来的dump.rdb文件,因此无论bgsave是否成功,dump.rdb都不会受到影响。
另外在主从全量同步、debug reload以及shutdown的情况下也会触发RDB数据持久化。
三、RDB模式含义
可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot)并写入磁盘, 也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里
四、RDB备份执行
Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到 一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。 整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能 如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失。
五、Fork
#1.Fork的作用是复制一个与当前进程一样的进程。新进程的所有数据(变量、环境变量、程序计数器等) 数值都和原进程一致,但是是一个全新的进程,并作为原进程的子进程
#2.在Linux程序中,fork()会产生一个和父进程完全相同的子进程,但子进程在此后多会exec系统调用,出于效率考虑,Linux中引入了“写时复制技术”
#3.一般情况父进程和子进程会共用同一段物理内存,只有进程空间的各段的内容要发生变化时,才会将父进程的内容复制一份给子进程。
六、RDB持久化流程
1.默认情况下,Redis保存数据集快照到磁盘,名为dump.rdb的二进制文件。你可以设置让Redis在N秒内至少有M次数据集改动时保存数据集,或者你也可以手动调用SAVE或者BGSAVE命令。
2.在上文中我们已经在配置文件中做过对应的配置:
例如,这个配置会让Redis在每个60秒内至少有1000次键改动时自动转储数据集到磁盘:
save 60 1000
3.当 Redis 需要保存 dump.rdb 文件时,服务器执行以下操作:
Redis 调用 fork() ,同时拥有父进程和子进程。
子进程将数据集写入到一个临时的 RDB 文件中。当子进程完成对新 RDB 文件的写入时, Redis 用新RDB 文件替换原来的 RDB 文件,并删除旧的 RDB 文件。
4.这种方式使得 Redis 可以从写时复制机制中获益。
七、 快照持久化快照相关配置
#编辑配置文件
[root@db01 ~]# vim /service/redis/6379/redis.conf
bind 172.16.1.51 127.0.0.1
port 6379
daemonize yes
pidfile /service/redis/6379/redis_6379.pid
loglevel notice
logfile /service/redis/6379/redis_6379.log
requirepass 123
dir "/etc/redis"
dbfilename dump.rdb
stop-write-on-bgsave-error yes
rdbchecksum yes
rdbcompression yes
save 900 1
save 300 10
save 60 10000
save m n
#配置快照(rdb)促发规则,格式:save <seconds> <changes>
#save 900 1 900秒内至少有1个key被改变则做一次快照
#save 300 10 300秒内至少有300个key被改变则做一次快照
#save 60 10000 60秒内至少有10000个key被改变则做一次快照
#关闭该规则使用svae “”
dbfilename dump.rdb
#rdb持久化存储数据库文件名,默认为dump.rdb
stop-write-on-bgsave-error yes
#yes代表当使用bgsave命令持久化出错时候停止写RDB快照文件,no表明忽略错误继续写文件。推荐yes。
rdbchecksum yes
#在写入文件和读取文件时是否开启rdb文件检查,检查是否有无损坏,如果在启动是检查发现损坏,则停止启动。在存储快照后,还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。推荐yes。
dir "/etc/redis"
#rdb数据文件存放目录,rdb快照文件和aof文件都会存放至该目录,也可以修改,默认为Redis启动时命令行所在的目录下,请确保有写权限。
rdbcompression yes
#对于存储到磁盘中的快照,可以设置是否开启RDB文件压缩,该功能可以节约磁盘空间。如果是的话,redis会采用LZF算法进行压缩。如果你不想消耗CPU来进行压缩的话,可以设置为关闭此功能。推荐yes。
八、RDB备份
#1.备份
1)先通过config get dir 查询rdb文件的目录
2)将*.rdb的文件拷贝到别的地方
#2.恢复
1)先停止redis
2)将rdb文件放到指定目录下
3)启动redis
九、 RDB优势
1.RDB是一种表示某个即时点的Redis数据的紧凑文件。RDB文件适合用于备份。例如,你可能想要每小时归档最近24小时的RDB文件,每天保存近30天的RDB快照。这允许你很容易的恢复不同版本的数据集以容灾。
2.RDB非常适合于灾难恢复,作为一个紧凑的单一文件,可以被传输到远程的数据中心。
3.RDB最大化了Redis的性能,因为Redis父进程持久化时唯一需要做的是启动(fork)一个子进程,由子进程完成所有剩余工作。父进程实例不需要执行像磁盘IO这样的操作。
4.RDB在重启保存了大数据集的实例时比AOF要快。
十、RDB劣势
1.当你需要在Redis停止工作(例如停电)时最小化数据丢失,RDB可能不太好。你可以配置不同的保存点(save point)来保存RDB文件(例如,至少5分钟和对数据集100次写之后,但是你可以有多个保存点)。然而,你通常每隔5分钟或更久创建一个RDB快照,所以一旦Redis因为任何原因没有正确关闭而停止工作,你就得做好最近几分钟数据丢失的准备了。
2.RDB需要经常调用fork()子进程来持久化到磁盘。如果数据集很大的话,fork()比较耗时,结果就是,当数据集非常大并且CPU性能不够强大的话,Redis会停止服务客户端几毫秒甚至一秒。AOF也需要fork(),但是你可以调整多久频率重写日志而不会有损(trade-off)持久性(durability)。
十一、停止和手动备份
1.停止备份
在配置文件中就设置save “”或在命令行中 config set save “”。
2.手动开始备份
save:会立即生成dump.rdb,但是会阻塞往redis内存中写入数据。
bgsave:后台异步备份。
如果是使用flushdb命令,会把之前的快照更新成当前的空状态,所以执行了flushdb后更新的快照是没有数据的。
3.save与bgsave对比
命令 | save | bgsave |
---|---|---|
IO类型 | 同步 | 异步 |
是否阻塞 | 是 | 否(阻塞发生在fork) |
优点 | 不会消耗额外内存 | 不阻塞客户端命令 |
缺点 | 阻塞客户端命令 | 创建fork,消耗内存 |
十二、RDB优缺点总结
#1.优点:对数据完整性和一致性要求不高更适合使用、适合大规模的数据恢复、节省磁盘空间、恢复速度快、主从复制也是基于RDB持久化功能实现的。
#2.缺点:会有数据丢失、导致服务停止几秒、消耗性能较高