持久化概述
持久化可以理解为存储,就是把数据存储到一个不会丢失的地方,如果把数据放在内存中,电脑关闭或重启数据就会丢失,放在内存中的数据不会丢失,而放在磁盘上算是一种持久化。
redis的数据存储在内存中,内存是瞬时的,如果linux宕机重启,redis服务器崩溃重启,所有的内存数据就会丢失,为了解决这个问题,redis提供了两种机制对数据进行持久化存储(RDB和AOF两种方式),便于发生故障后能快速恢复数据。
RDB方式
RDB持久化方式是指定的时间间隔内将内存中的数据写入磁盘,在默认情况下,Redis将数据库快照保存在名字为dump.rdb的二进制文件中。在Redis运行时,RDB程序将当前内存中的数据库快照保存到磁盘文件中,在 Redis重启动时,RDB序可以通过载入RDB文件来还原数据库的状态。
Redis的RDB是如何做到持久化的呢?
RDB方式的数据持久化,仅需在redis.conf文件中配置即可:
配置格式:save <指定时间间隔> <执行指定次数更新操作>,
save 900 1
save 300 10
save 60 10000
dbfilename:设置RDB的文件名,默认文件名为dump.rdb
dir:指定AOF和RDB文件的目录
stop-writes-on-bgsave-error:bgsave发生错误时是否停止写入,通常为yes
rdbcompression:rdb文件是否使用压缩格式,yes表示压缩
rdbchecksum:是否对rdb文件进行校验和检验,通常为yes
工作方式
当Redis需要保存dump.rdb文件时,服务器执行以下操作:
1)Redis调用forks,同时拥有父进程和子进程。
2)子进程将数据集写入到一个临时RDB文件中。
3)当子进程完成对新RDB文件的写入时,Redis用新RDB文件替换原来的RDB文件,并删除旧的 RDB 文件。
RDB的三种主要触发机制
save命令(同步数据到磁盘上)
save命令执行是一个同步操作,以RDB文件的方式保存所有数据的快照。由于save命令是同步操作,会占用Redis的主进程。若Redis数据非常多时,save命令执行速度会非常慢,阻塞所有客户端的请求。
bgsave命令(异步保存数据到磁盘上)
bgsave 命令执行一个异步操作,以RDB文件的方式保存所有数据的快照。Redis使用Linux系统的fock()生成一个子进程来将DB数据保存到磁盘,主进程继续提供服务以供客户端调用。如果操作成功,可以通过客户端命令LASTSAVE来检查操作结果。
自动生成RDB
通过配置文件对Redis进行设置,让它在"N秒内数据集至少有M个改动"这一条件被满足时,自动进行数据集保存操作。
RDB优点与缺点
优点
1)如果要进行大规模数据的恢复,RDB方式要比AOF方式恢复速度要快。
2)RDB可以最大化Redis性能,父进程做的就是fork子进程,然后继续接受客户端请求,让子进程负责持久化操作,父进程无需进行IO操作。
3)RDB是一个非常紧凑(compact)的文件,它保存了某个时间点的数据集,非常适合用作备份,同时也非常适合用作灾难性恢复,它只有一个文件,内容紧凑,通过备份原文件到本机外的其他主机上,一旦本机发生宕机,就能将备份文件复制到redis安装目录下,通过启用服务就能完成数据的恢复。
缺点
1)RDB这种持久化方式不太适应对数据完整性要求严格的情况,因为,尽管我们可以用过修改快照实现持久化的频率,但是要持久化的数据是一段时间内的整个数据集的状态,如果在还没有触发快照时,本机就宕机了,那么对数据库所做的写操作就随之而消失了并没有持久化本地dump.rdb文件中。
2)每次进行RDB时,父进程都会fork一个子进程,由子进程来进行实际的持久化操作,如果数据集庞大,那么fork出子进程的这个
AOF方式
以日志的形式记录Redis每一个写操作,将Redis执行过的所有写指令记录到AOF文件中(只记录写操作,读操作不记录),只许追加文件不可以改写文件,redis启动之后会读取appendonly.aof文件来实现重新恢复数据,完成恢复数据的工作。默认不开启,需要将redis.conf中的appendonly的no改为yes启动Redis。
Redis的AOF是如何做到持久化的呢?
AOF方式的数据持久化,仅需在redis.conf文件中配置即可:
appendonly:默认是no,改成yes即开启aof持久化
appendfilename:指定AOF文件名,默认文件名为appendonly.aof
appendfsync:配置aof文件写命令数据的策略,策略方式如下
appendfsync always:每修改同步,每一次发生数据变更都会持久化到磁盘上,性能较差,但数据完整性较好。
appendfsync everysec: 每秒同步,每秒内记录操作,异步操作,如果一秒内宕机,有数据丢失。
appendfsync no:不同步。
dir:指定AOF和RDB文件的目录
auto-aof-rewrite-percentage:当目前aof文件大小超过上一次重写的aof文件大小的百分之多少时会再次进行重写,如果之前没有重写,则以启动时的aof文件大小为依据。
auto-aof-rewrite-min-size:允许重写的最小AOF文件大小
AOF重写
因为AOF的运作方式是不断地将命令追加到文件的末尾,所以随着写入命令的不断增加,这就导致AOF文件可能过于庞大。为了避免这种状况,Redis新增了重写机制,当AOF文件的大小超过所指定的阈值时,
Redis会自动启用AOF文件的内容压缩,只保留可以恢复数据的最小指令集,可以使用命令bgrewiteaof。
重写原理:AOF文件持续增长过大时,会fork出一条新进程来将文件重写,遍历新进程的内存中的数据,每条记录都会有一条set语句,重写aof文件的操作,并没有读取旧的aof文件,
而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,有点类似于快照。
假设Redis的配置项为:
auto-aof-rewrite-min-size 64mb
auto-aof-rewrite-percentage 100
当AOF文件的体积大于64Mb,并且AOF文件的体积比上一次重写之久的体积大了至少一倍(100%)时,Redis将执行 bgrewriteaof 命令进行重写。
AOF重写的作用
1)减少磁盘占用量
2)加速数据恢复
AOF 的优缺点
优点:数据的完整性和一致性更高
缺点:因为AOF记录的内容多,文件会越来越大,数据恢复也会越来越慢。
RDB与AOF如何选择
1)一般来说,如果想达到足以媲美PostgreSQL的数据安全性,应该同时使用两种持久化方式。
2)有很多用户都只使用AOF持久化,但我们并不推荐这种方式:因为定时生成RDB快照(snapshot)非常便于进行数据库备份,并且RDB恢复数据集的速度也要比AOF恢复的速度要快。
3)如果可以承受输分钟内的数据丢失,可以只使用RDB持久化。