Redis持久化方式AOF和RDB

RDB持久化

AOF持久化

全量备份,一次保存整个数据库

增量备份,一次保存一个修改数据库的命令

保存的间隔较长

保存的间隔默认一秒

数据还原速度快

数据还原速度一般

save会阻塞,但bgsave或者自动不会阻塞

无论是平时还是AOF重写,都不会阻塞

更适合数据备份,默认开启

更适合用来保存数据,和一般SQL持久化方式一样,默认关闭

启动优先级 : 低

启动优先级 : 高

体积 : 小

体积 : 大

恢复速度 : 快

恢复速度 : 慢

数据安全性 : 丢数据

数据安全性 : 根据策略决定

轻重 : 重

轻重: 轻

1、Redis持久化

RDB(Redis DataBase)------数据
AOF(AppendOnlyFiel)------命令

默认情况下,RDB开启,AOF关闭。

这两种形式都可以将存储在内存中的数据库数据以文件形式保存到硬盘中,防止数据丢失。文件位置:/var/lib/redis/6379

RDB持久化功能可以将服务器包含的所有数据库数据以二进制文件的形式保存到硬盘中,创建RDB类型的文件,默认为dump.rdb。服务器再次启动时会载入RDB文件,根据RDB文件的内容、还原服务器原有的数据库数据。

1.1 创建RDB文件方式

前两种需要用户手动执行,第三种有redis服务器自动执行

服务器执行客户端发送SAVE命令
服务器执行客户端发送BGSAVE命令
使用save配置选项设置的自动保存条件被满足,服务器自动执行BGSAVE

  • SAVE命令

        执行save命令的过程中,即创建RDB文件过程中,redis服务器将被阻塞,无法处理客户端发送的命令请求,只有在SAVE命令执行完毕之后,,服务器才重新开始处理客户端发送的命令请求。

        如果RDB文件已经存在,那么服务器将自动使用新的RDB文件去代替旧的RDB文件。(为防止rdb文件丢失或被恶意篡改,可以设置定时将rdb文件转移到别的位置,文件命名标明保存时间)

  • BGSAVE命令

        执行bgsave命令同样会创建一个新的RDB文件,但这个命令执行过程中不会造成redis服务器阻塞。

【1、当redis服务器接受到BGSAVE命令时,他不会自动创建RDB文件,而是通过fork()来生成一个子进程,然后由子进程负责创建RDB文件,而自己继续处理客户端的命令请求    2、当子进程创建好RDB文件并退出时,他会向父进程(即负责处理命令请求的redis服务器)发送一个信号,告知他RDB文件已经创建完毕   3、最后redis服务器(父进程)解手子进程创建的RDB文件,BGSAVE执行完毕】

        创建子进程会消耗额外的内存,所以SAVE创建RDB文件的速度会比BGSAVE块,可以集中资源来创建RDB文件。SAVE和BGSAVE没有孰好孰坏之分,如果数据库正在上线当中,用BGSAVE更好;而如果维护停机期间,则使用SAVE,因为此时系统阻塞也没关系,创建速度会更快,任务可以更快得完成。

自动创建RDB文件
        默认redis.conf文件中为如下设置,可自行修改。只要三个条件满足任意一个,服务器就会执行BGSAVE。RDB文件创建后,服务器会将时间计数器和次数计数器清零,重新开始记录

save 900 1 :如果距离上次创建RDB文件已经过去了900秒,且服务器所有数据库总共已经发生了不少于1次修改,那么执行BGSAVE命令

save 300 10 :如果距离上次创建RDB文件已经过去了300秒,且服务器所有数据库总共已经发生了不少于10次修改,那么执行BGSAVE命令

save 60 10000:如果距离上次创建RDB文件已经过去了60秒,且服务器所有数据库总共已经发生了不少于10000次修改,那么执行BGSAVE命令

 

2、常见问题

1.在dump rdb过程中,aof如果停止同步,会不会丢失?  

不会,所有的操作缓存在内存队列里,dump完后后,统一操作

2.aof重写是什么?

aof重写就是把内存中的数据逆化成命令,写入到aof文件,以解决aof日志过大的问题

3.如果rdb和aof文件都存在,优先使用谁恢复数据?

在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件完整

4.rdb和aof是否可以同时用?

可以,推荐同时使用

5.恢复时,rdb和aof哪个更快?

rdb快,因为rdb是数据的内存映射,直接载入到内存,而aof是命令,需要逐条执行

6.如何在不用【config set】命令的情况下,将Redis持久化由RDB切换到AOF

利用主从,从机配置AOF重启后,将生成的AOF文件复制至主机Redis数据目录,主机配置AOF后再重启。

注:在 Redis 2.2 或以上版本,通过【config set】可以在不重启的情况下,从 RDB 切换到 AOF。

1)为最新的 dump.rdb 文件创建一个备份。

2)将备份放到一个安全的地方。

3)执行以下两条命令: redis-cli> CONFIG SET appendonly yes redis-cli> CONFIG SET save ""

4)确保命令执行之后,数据库的键的数量没有改变。

5)确保写命令会被正确地追加到 AOF 文件的末尾。

步骤 3 执行的第一条命令开启了AOF功能:<font style="color:red">Redis会阻塞直到初始AOF文件创建完成为止</font>,之后Redis会继续处理命令请求, 并开始将写入命令追加到 AOF 文件末尾。

步骤 3 执行的第二条命令用于关闭RDB功能。这一步是可选的,如果你愿意的话,也可以同时使用RDB和AOF这两种持久化功能。

不过别忘了在redis.conf中打开AOF功能!否则的话,服务器重启之后,之前通过【CONFIG SET】设置的配置就会被遗忘,程序会按原来的配置来启动服务器。

3、 RDB持久化的配置

RDB是在某个时间点将数据写入一个临时文件,持久化结束后,用这个临时文件替换上次持久化的文件,达到数据恢复。 
优点:使用单独子进程来进行持久化,主进程不会进行任何IO操作,保证了redis的高性能 
缺点:RDB是间隔一段时间进行持久化,如果持久化之间redis发生故障,会发生数据丢失。所以这种方式更适合数据要求不严谨的时候

        创建RDB文件需要将服务器所有的数据库的数据保存起来,这是一个非常耗费资源和时间的操作,所以服务器需要隔一段时间才创建一个新的RDB文件,也就是说,创建RDB文件的操作不能执行得过于频繁,否则就会严重得影响服务器性能。

        相比而言,AOF持久化的巨大优势就是用户可以根据自己的需要对AOF持久化进行调整,让redis在遭遇意外停机时不丢失任何数据,或者只丢失一秒钟的数据。

这里说的这个执行数据写入到临时文件的时间点是可以通过配置来自己确定的,通过配置redis在n秒内如果超过m个key被修改这执行一次RDB操作。这个操作就类似于在这个时间点来保存一次Redis的所有数据,一次快照数据。所有这个持久化方法也通常叫做snapshots。

RDB默认开启,redis.conf中的具体配置参数如下;

 1 #dbfilename:持久化数据存储在本地的文件
 2 dbfilename dump.rdb
 3 #dir:持久化数据存储在本地的路径,如果是在/redis/redis-3.0.6/src下启动的redis-cli,则数据会存储在当前src目录下
 4 dir ./
 5 #snapshot触发的时机,save <seconds> <changes>  
 6 #如下为900秒后,至少有一个变更操作,才会snapshot  
 7 #对于此值的设置,需要谨慎,评估系统的变更操作密集程度  
 8 #可以通过“save “””来关闭snapshot功能  
 9 #save时间,以下分别表示更改了1个key时间隔900s进行持久化存储;更改了10个key300s进行存储;更改10000个key60s进行存储。
10 save 900 1
11 save 300 10
12 save 60 10000
13 #当snapshot时出现错误无法继续时,是否阻塞客户端“变更操作”,“错误”可能因为磁盘已满/磁盘故障/OS级别异常等  
14 stop-writes-on-bgsave-error yes  
15 #是否启用rdb文件压缩,默认为“yes”,压缩往往意味着“额外的cpu消耗”,同时也意味这较小的文件尺寸以及较短的网络传输时间  
16 rdbcompression yes  

snapshot触发的时机,是有“间隔时间”和“变更次数”共同决定,同时符合2个条件才会触发snapshot,否则“变更次数”会被继续累加到下一个“间隔时间”上。snapshot过程中并不阻塞客户端请求。snapshot首先将数据写入临时文件,当成功结束后,将临时文件重名为dump.rdb。

使用RDB恢复数据: 
自动的持久化数据存储到dump.rdb后。实际只要重启redis服务即可完成(启动redis的server时会从dump.rdb中先同步数据)

客户端使用命令进行持久化save存储:

./redis-cli -h ip -p port save
./redis-cli -h ip -p port bgsave

4、AOF持久化的配置

  4.1 AOF重写原理:

AOF 是redis的一种持久化方式,用来记录所有的写操作,但是随着时间增加,aof文件会越来越大,所以需要进行重写,将内存中的数据重新以命令的方式写入aof文件。
在重写的过程中,由于redis还会有新的写入,为了避免数据丢失,会开辟一块内存用于存放重写期间产生的写入操作,等到重写完毕后会将这块内存中的操作再追加到aof文件中。

  4.2 优缺点:

优点:可以保持更高的数据完整性,如果设置追加file的时间是1s,如果redis发生故障,最多会丢失1s的数据;且如果日志写入不完整支持redis-check-aof来进行日志修复;AOF文件没被rewrite之前(文件过大时会对命令进行合并重写),可以删除其中的某些命令(比如误操作的flushall)。 
缺点:AOF文件比RDB文件大,且恢复速度慢。

  4.3 什么情况触发rewrite?

127.0.0.1:6379> config get auto-aof-rewrite-percentage
1) "auto-aof-rewrite-percentage"
2) "200"
127.0.0.1:6379> config set auto-aof-rewrite-percentage 800
OK

auto-aof-rewrite-percentage 是设置aof rewrite触发时机的一个参数,当当前的aof文件大小超过上一次rewrite后aof文件的百分比后触发rewrite。

200 改为 800 ,即当前的aof文件超过上一次重写后aof文件的8倍时才会再次rewrite

   

  • AOF持久化默认是关闭的,默认是打开RDB持久化
  • appendonly yes,(在redis.conf中修改appendonly 的策略,将no改成yes即可)此配置可以打开AOF持久化机制,在生产环境里面,一般来说AOF都是要打开的,除非你说随便丢个几分钟的数据也无所谓
  • 打开AOF持久化机制之后,redis每次接收到一条写命令,就会写入日志文件中,当然是先写入os cache的,然后每隔一定时间再fsync一下
  • 而且即使AOF和RDB都开启了,redis重启的时候,也是优先通过AOF进行数据恢复的,因为aof数据比较完整
  • 可以配置AOF的fsync策略,有三种策略可以选择(redis提供了3中aof记录同步选项):

一种是每次写入一条数据就执行一次fsync; 一种是每隔一秒执行一次fsync; 一种是不主动执行fsync

appendfsync always: 每次写入一条数据,立即将这个数据对应的写日志fsync到磁盘上去,性能非常非常差,吞吐量很低; 确保说redis里的数据一条都不丢,那就只能这样了appendfsync everysec: 每秒将os cache中的数据fsync到磁盘,这个最常用的,生产环境一般都这么配置,性能很高,QPS还是可以上万的(QPS指每秒钟请求次数)appendfsync no: 仅仅redis负责将数据写入os cache就撒手不管了,然后后面os自己会时不时有自己的策略将数据刷入磁盘,不可控了

我们可以简单的认为AOF就是日志文件,此文件只会记录“变更操作”(例如:set/del等),如果server中持续的大量变更操作,将会导致AOF文件非常的庞大,意味着server失效后,数据恢复的过程将会很长;事实上,一条数据经过多次变更,将会产生多条AOF记录,其实只要保存当前的状态,历史的操作记录是可以抛弃的;因为AOF持久化模式还伴生了“AOF rewrite”。 
AOF的特性决定了它相对比较安全,如果你期望数据更少的丢失,那么可以采用AOF模式。如果AOF文件正在被写入时突然server失效,有可能导致文件的最后一次记录是不完整,你可以通过手工或者程序的方式去检测并修正不完整的记录,以便通过aof文件恢复能够正常;同时需要提醒,如果你的redis持久化手段中有aof,那么在server故障失效后再次启动前,需要检测aof文件的完整性。

AOF默认关闭,开启方法,修改配置文件reds.conf:appendonly yes

 1 #此选项为aof功能的开关,默认为“no”,可以通过“yes”来开启aof功能  
 2 ##只有在“yes”下,aof重写/文件同步等特性才会生效  
 3 appendonly yes  
 4 
 5 #指定aof文件名称  
 6 appendfilename appendonly.aof  
 7 
 8 #指定aof操作中文件同步策略,有三个合法值:always everysec no,默认为everysec  
 9 appendfsync everysec  
10 #在aof-rewrite期间,appendfsync是否暂缓文件同步,"no"表示“不暂缓”,“yes”表示“暂缓”,默认为“no”  
11 no-appendfsync-on-rewrite no  
12 
13 #aof文件rewrite触发的最小文件尺寸(mb,gb),只有大于此aof文件大于此尺寸是才会触发rewrite,默认“64mb”,建议“512mb”  
14 auto-aof-rewrite-min-size 64mb  
15 
16 #相对于“上一次”rewrite,本次rewrite触发时aof文件应该增长的百分比。  
17 #每一次rewrite之后,redis都会记录下此时“新aof”文件的大小(例如A),那么当aof文件增长到A*(1 + p)之后  
18 #触发下一次rewrite,每一次aof记录的添加,都会检测当前aof文件的尺寸。  
19 auto-aof-rewrite-percentage 100 

  4.4、AOF持久化的数据恢复实验

(1)先仅仅打开RDB,写入一些数据,然后kill -9杀掉redis进程,接着重启redis,发现数据没了,因为RDB快照还没生成
(2)打开AOF的开关,启用AOF持久化
(3)写入一些数据,观察AOF文件中的日志内容
其实你在appendonly.aof文件中,可以看到刚写的日志,它们其实就是先写入os cache的,然后1秒后才fsync到磁盘中,只有fsync到磁盘中了,才是安全的,要不然光是在os cache中,机器只要重启,就什么都没了
(4)kill -9杀掉redis进程,重新启动redis进程,发现数据被恢复回来了,就是从AOF文件中恢复回来的
redis进程启动的时候,直接就会从appendonly.aof中加载所有的日志,把内存中的数据恢复回来

    4.5、AOF破损文件的修复

如果redis在append数据到AOF文件时,机器宕机了,可能会导致AOF文件破损
用redis-check-aof --fix命令来修复破损的AOF文件

 5、AOF和RDB同时工作

(1)如果RDB在执行snapshotting操作,那么redis不会执行AOF rewrite; 如果redis再执行AOF rewrite,那么就不会执行RDB snapshotting

(2)如果RDB在执行snapshotting,此时用户执行BGREWRITEAOF命令,那么等RDB快照生成之后,才会去执行AOF rewrite

(3)同时有RDB snapshot文件和AOF日志文件,那么redis重启的时候,会优先使用AOF进行数据恢复,因为其中的日志更完整

原文地址:https://www.cnblogs.com/mzcx/p/11424835.html