持久化:
即把数据存储于断电后不会丢失的设备中,通常是硬盘.
一:常见的持久化方式:
主从:通过从服务器保存和持久化,如mongoDB的replication sets配置
日志:操作生成相关日志,并通过日志来恢复数据
couchDB对于数据内容,不修改,只追加,则文件本身就是日志,不会丢失数据
二:redis的数据持久化:
相对memcacher来讲,这是redis的一大优势。redis是一个支持持久化的内存数据库,也就是说redis 需要经常讲内存中的数据同步到硬盘来保证持久化。redis 支持两种持久化方式:
1 snapshotting(快照)方式也称为RDB方式。
2 Append-only file(AOF)方式。
下面我们来具体说一下两种方式的工作原理及配置。
RDB:
快照是默认的持久化方式。这种方式是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb 。可以通过配置设置自动做快照持久化的方式。
工作原理:
每隔N分钟或N次写操作后, 从内存dump数据形成rdb文件,压缩放在备份目录
注:红色部分可通过参数来配置
相关配置:
save 900 1 #刷新快照到硬盘中,必须满足两者要求才会触发,即900秒之后至少1个关键字发生变化。
save 300 10 #必须是300秒之后至少10个关键字发生变化。
save 60 10000 #必须是60秒之后至少10000个关键字发生变化。
stop-writes-on-bgsave-error yes #后台存储错误停止写。
rdbcompression yes #使用LZF压缩rdb文件。
rdbchecksum yes #存储和加载rdb文件时校验。
dbfilename dump.rdb #设置rdb文件名。
dir ./ #设置工作目录,rdb文件会写入该目录。
例如下图配置文件中:
则表示为:60秒内有1000次变化,保存。
300秒 有10次变化 保存
900秒有1次变化 保存。
AOF
工作原理:
在使用AOF时,redis会将每一个收到的写命令都通过write函数追加到文件中。当redis重启时,会通过重新执行文件保存的写命令来在内存中重建整个数据库的内容。
相关配置:
首先需要开启AOF持久化操作,同样需要修改redis.conf文件,需要注意的是开启后会清空redis中的数据,因此在安装完redis后就需要开启AOF操作。
appendonly no # 是否打开 aof日志功能
appendfsync always # 每1个命令,都立即同步到aof. 安全,速度慢
appendfsync everysec # 每秒写1次每秒钟强制写入磁盘一次,在性能和持久化方面最了很好的折衷
appendfsync no # 写入工作交给操作系统,由操作系统判断缓冲区大小,统一写入到aof. 同步频率低,速度快,
no-appendfsync-on-rewrite yes: # 正在导出rdb快照的过程中,要不要停止同步aof
auto-aof-rewrite-percentage 100 #aof文件大小比起上次重写时的大小,增长率100%时,重写
auto-aof-rewrite-min-size 64mb #aof文件,至少超过64M时,重写
AOF的重写:
场景:假如只有一个key 反复操作100,结果是就形成了多条aof。这样有两个弊端:
一是备份文件太大(保存了对该key一百次的执行命令)。
二是恢复过程多次无效操作。(在恢复的时候,会恢复100次,将我们所有的操作过程全部执行一遍。100个动作也都要重复一遍。)。但其实我们只需要最后的一个结果。AOF重写就是解决这个问题。
原理:当达到我们设定的某个比例或大小时,我们就删除文件的执行过程,而把所有的key当成是重新set进去的。把内存中的key和val逆化成相应的命令。
如下:
auto-aof-rewrite-percentage 100
#aof文件大小比起上次重写时的大小,增长率100%时,重写
auto-aof-rewrite-min-size 64mb
#aof文件,至少超过64M时,重写
值得注意的是:只有第一个命令时,这样就导致前期每重写一个命令就重写一次。所以设置而了第二个命令,文件也要大于64M。
测试:
我们进行一个演示。我设置aof文件达到32m的时候,进行文件重写。
测试开始,发送了2000命令。
执行过程:
检测过程:通过不断的查询aof的日志大小。发现开始的时候日志是不断增大的,等过一段时间在查看的时候,日志变小了。说明其进行了重写。删除了文件的执行过程,而把所有的key当成是重新set进去的。
备注:同时还可以直接命令重写。
RDB和AOF的对比
①是否会丢失数据,严重性。
两者都会丢失数据。RDB由于配置的是每隔N分钟或N次写操作后,进行一次备份。那如果出现故障,会将丢失最后一次快照后的所有修改。
AOF有三种配置,
appendfsync always
# 每1个命令,都立即同步到aof. 安全,速度慢
appendfsync everysec
# 每秒写1次每秒钟强制写入磁盘一次,在性能和持久化方面最了很好的折衷
appendfsync no
# 写入工作交给操作系统,由操作系统判断缓冲区大小,统一写入到aof. 同步频率低,速度快
一般我们采用折中的everysec方式,那么数据丢失也就是丢失故障发生的当前一秒的数据。相对RDB方式,其安全性提高了n个数量级。
②两种方式,哪种方式恢复数据块快。
RDB,因为RDB方式是大的二进制块。因为其是数据库内存映射直接载入到内存。而aof是命令,需要逐条执行命令。
③两种方式 会不会影响redis的性能。
都会。因为redis是单线程。尽管2.4之后还出现了后台线程来优化aof。但不可否认,每次进行日志备份时,都需要占用IO,从而减少了redis 响应其他操作的次数。
总结:
redis有RDB和AOF两种数据持久化操作。从原理上说rdb是快照备份,aof是写日志备份。从数据安全的上说,rdb丢失的数据会更多,aof能减少数据的丢失。从数据恢复的角度来说,rdb要比aof进行的快。因此,各有不同。具体使用哪种方式,取决于我们对性能,对数据安全的要求和具体业务。