Redis持久化RDB与AOF

2017年12月19日13:56:14 发表评论 1,199 views
摘要

众所周知,redis是内存数据库,它把数据存储在内存中,这样在加快读取速度的同时也对数据安全性产生了新的问题,即当redis所在服务器发生宕机后,redis数据库里的所有数据将会全部丢失。
为了解决这个问题,redis提供了持久化功能——RDB和AOF。通俗的讲就是将内存中的数据写入硬盘中。

广告也精彩

一、RDB和AOF优缺点

1.1 RDB的优点?

RDB是一个非常紧凑(compact)的文件,体积小网络传输快,它保存了Redis在某个时间点上的数据集。这种文件非常适合用于进行备份,恢复速度比AOF快很多。当然,与AOF相比,RDB最重要的优点之一是对性能的影响相对较小。父进程在保存RDB文件时唯一要做的就是fork出一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无须执行任何磁盘 I/O 操作。

1.2 RDB的缺点?

RDB文件的致命缺点在于其数据快照的持久化方式决定了必然做不到实时持久化,而在数据越来越重要的今天,数据的大量丢失很多时候是无法接受的,因此AOF持久化成为主流。此外,RDB文件需要满足特定格式,兼容性差(如老版本的Redis不兼容新版本的RDB文件)。

1.3 AOF的优点?

与RDB持久化相对应,AOF的优点在于支持秒级持久化兼容性好。你可以设置不同的fsync策略,比如无fsync,每秒钟一次fsync,或者每次执行写入命令时fsync。AOF的默认策略为每秒钟fsync一次,在这种配置下,Redis仍然可以保持良好的性能,并且就算发生故障停机,也最多只会丢失一秒钟的数据。AOF文件是一个只进行追加操作的日志文件(append only log),因此对AOF文件的写入不需要进行seek(查找),即使日志因为某些原因而包含了未写入完整的命令(比如写入时磁盘已满,写入中途停机,等等), redis-check-aof 工具也可以轻易地修复这种问题。

Redis可以在AOF文件体积变得过大时,自动地在后台对AOF进行重写: 重写后的新AOF文件包含了恢复当前数据集所需的最小命令集合。 整个重写操作是绝对安全的,因为 Redis 在创建新 AOF 文件的过程中,会继续将命令追加到现有的AOF文件里面,即使重写过程中发生停机,现有的AOF文件也不会丢失。 而一旦新AOF文件创建完毕,Redis就会从旧AOF文件切换到新AOF文件,并开始对新AOF文件进行追加操作。AOF文件有序地保存了对数据库执行的所有写入操作,这些写入操作以Redis协议的格式保存,因此AOF文件的内容非常容易被人读懂,对文件进行分析(parse)也很轻松。导出(export)AOF文件也非常简单: 举个例子, 如果你不小心执行了FLUSHALL命令,但只要AOF文件未被重写,那么只要停止服务器,移除AOF文件末尾的FLUSHALL命令,并重启 Redis, 就可以将数据集恢复到FLUSHALL执行之前的状态。

1.4 AOF的缺点?

AOF文件的体积通常要大于RDB文件的体积大、且恢复速度慢。对于相同的数据集来说,根据所使用的fsync策略,AOF的速度可能会慢于RDB。在一般情况下,每秒fsync的性能依然非常高,而关闭fsync可以让AOF的速度和RDB一样快
另外,AOF在过去曾经发生过这样的bug,因为个别命令的原因,导致AOF文件在重新载入时,无法将数据集恢复成保存时的原样。虽然这种bug在AOF文件中并不常见,但是对比来说,RDB几乎是不可能出现这种bug的。

1.5 RDB和AOF,我应该用哪一个?

首先要明白无论是RDB还是AOF,持久化的开启都是要付出性能方面代价的:对于RDB持久化,一方面是bgsave在进行fork操作时Redis主进程会阻塞,另一方面,子进程向硬盘写数据也会带来IO压力。但如果业务能容忍几分钟到10几分钟的数据丢失(且不使用备库),RDB是一个不错的选择;不然,就选择AOF。

对于AOF持久化,向硬盘写数据的频率大大提高(everysec策略下为秒级),IO压力更大,甚至可能造成AOF追加阻塞问题(后面会详细介绍这种阻塞),此外,AOF文件的重写与RDB的bgsave类似,会有fork时的阻塞和子进程的IO压力问题。相对来说,由于AOF向硬盘中写数据的频率更高,因此对Redis主进程性能的影响会更大。

1.6 RDB 与 AOF 对比总结

Redis持久化RDB与AOF

还好的是redis提出了AOF重写的机制

  • AOF重写原理:既是重新创建一个精简化的AOF文件,里面去掉了多余的冗余命令,并对原AOF文件进行覆盖。这保证了AOF文件大小处于让人可以接受的地步。
  • AOF重写配置:auto-aof-rewrite-percentage和auto-aof-rewrite-min-size配置触发AOF重写的条件

关于重写,下面会更相信的描述。。。。。。

二、Redis持久化方案

传送门:
一、持久化之全量写入:RDB
二、持久化之增量写入:AOF
三、RDB重写和AOF重写

众所周知,redis是内存数据库,它把数据存储在内存中,这样在加快读取速度的同时也对数据安全性产生了新的问题,即当redis所在服务器发生宕机后,redis数据库里的所有数据将会全部丢失。
为了解决这个问题,redis提供了持久化功能——RDB和AOF。通俗的讲就是将内存中的数据写入硬盘中。

1、持久化之全量写入:RDB

[redis@6381]$ more /usr/local/redis/conf/redis.conf 
save 900 1
save 300 10
save 60 10000
dbfilename "dump.rdb"          #持久化文件名称
dir "/data/dbs/redis/6381"    #持久化数据文件存放的路径

上面是redis配置文件里默认的RDB持久化设置,前三行都是对触发RDB的一个条件,例如第一行的意思是每900秒钟里redis数据库有一条数据被修改则触发RDB,依次类推;只要有一条满足就会调用BGSAVE进行RDB持久化。第四行dbfilename指定了把内存里的数据库写入本地文件的名称,该文件是进行压缩后的二进制文件,通过该文件可以把数据库还原到生成该文件时数据库的状态。第五行dir指定了RDB文件存放的目录。

配置文件修改需要重启redis服务,我们还可以在命令行里进行配置,即时生效,服务器重启后需重新配置

[redis@iZ254r8s3m6Z redis]# bin/redis-cli
127.0.0.1:6379> CONFIG GET save         #查看redis持久化配置
1) "save"
2) "900 1 300 10 60 10000"
127.0.0.1:6379> CONFIG SET save "21600 1000" #修改redis持久化配置
OK

2,而RDB持久化也分两种:SAVE和BGSAVE

  • SAVE是阻塞式的RDB持久化,当执行这个命令时redis的主进程把内存里的数据库状态写入到RDB文件(即上面的dump.rdb)中,直到该文件创建完毕的这段时间内redis将不能处理任何命令请求。

  • BGSAVE属于非阻塞式的持久化,它会创建一个子进程专门去把内存中的数据库状态写入RDB文件里,同时主进程还可以处理来自客户端的命令请求。但子进程基本是复制的父进程,这等于两个相同大小的redis进程在系统上运行,会造成内存使用率的大幅增加。
    (本人在生产中就碰到过这问题,redis本身内存使用率就60%,总的内存使用率在百分之七八十左右,持久化的时候立马飙到百分之一百三十多,告警邮件是每天几十封/(ㄒoㄒ)/ 最后根据需求选择了AOF持久化)

2、持久化之增量写入:AOF

与RDB的保存整个redis数据库状态不同,AOF是通过保存对redis服务端的写命令(如set、sadd、rpush)来记录数据库状态的,即保存你对redis数据库的写操作,以下就是AOF文件的内容

[redis@iZ]$ more appendonly.aof 
*2
$6
SELECT
$1
0
*3
$3
SET
$47
DEV_USER_LEGAL_F9683BE0E27F1A06C0CB869CEC7E3B22
$11
¬
*3
$3
SET
$47

先让我们看看如何配置AOF。
复制代码

[redis@iZ]$ more ~/redis/conf/redis.conf
dir "/data/dbs/redis/6381"           #AOF文件存放目录
appendonly yes                       #开启AOF持久化,默认关闭
appendfilename "appendonly.aof"      #AOF文件名称(默认)
appendfsync no                       #AOF持久化策略
auto-aof-rewrite-percentage 100      #触发AOF文件重写的条件(默认)
auto-aof-rewrite-min-size 64mb       #触发AOF文件重写的条件(默认)

要弄明白上面几个配置就得从AOF的实现去理解:

  • AOF的持久化是通过命令追加、文件写入和文件同步三个步骤实现的。当reids开启AOF后,服务端每执行一次写操作(如set、sadd、rpush)就会把该条命令追加到一个单独的AOF缓冲区的末尾,这就是命令追加;
  • 然后把AOF缓冲区的内容写入AOF文件里。

看上去第二步就已经完成AOF持久化了那第三步是干什么的呢?
这就需要从系统的文件写入机制说起:一般我们现在所使用的操作系统,为了提高文件的写入效率,都会有一个写入策略,即当你往硬盘写入数据时,操作系统不是实时的将数据写入硬盘,而是先把数据暂时的保存在一个内存缓冲区里,等到这个内存缓冲区的空间被填满或者是超过了设定的时限后才会真正的把缓冲区内的数据写入硬盘中。也就是说当redis进行到第二步文件写入的时候,从用户的角度看是已经把AOF缓冲区里的数据写入到AOF文件了,但对系统而言只不过是把AOF缓冲区的内容放到了另一个内存缓冲区里而已,之后redis还需要进行文件同步把该内存缓冲区里的数据真正写入硬盘上才算是完成了一次持久化。而何时进行文件同步则是根据配置的appendfsync来进行:

appendfsync有三个选项:alwayseverysecno

  • 选择always的时候服务器会在每执行一个事件就把AOF缓冲区的内容强制性的写入硬盘上的AOF文件里,可以看成你每执行一个redis写入命令就往AOF文件里记录这条命令,这保证了数据持久化的完整性,但效率是最慢的,却也是最安全的;

  • 配置成everysec的话服务端每执行一次写操作(如set、sadd、rpush)也会把该条命令追加到一个单独的AOF缓冲区的末尾,并将AOF缓冲区写入AOF文件,然后每隔一秒才会进行一次文件同步把内存缓冲区里的AOF缓存数据真正写入AOF文件里,这个模式兼顾了效率的同时也保证了数据的完整性,即使在服务器宕机也只会丢失一秒内对redis数据库做的修改;

  • 将appendfsync配置成no则意味redis数据库里的数据就算丢失你也可以接受,它也会把每条写命令追加到AOF缓冲区的末尾,然后写入文件,但什么时候进行文件同步真正把数据写入AOF文件里则由系统自身决定,即当内存缓冲区的空间被填满或者是超过了设定的时限后系统自动同步。这种模式下效率是最快的,但对数据来说也是最不安全的,如果redis里的数据都是从后台数据库如mysql中取出来的,属于随时可以找回或者不重要的数据,那么可以考虑设置成这种模式。

三、RDB重写和AOF重写

重写概念简述

 我们只要知道AOF重写既是重新创建一个精简化的AOF文件,里面去掉了多余的冗余命令,并对原AOF文件进行覆盖。这保证了AOF文件大小处于让人可以接受的地步。而上面的auto-aof-rewrite-percentage和auto-aof-rewrite-min-size配置触发AOF重写的条件。

Redis 会记录上次重写后AOF文件的文件大小,而当前AOF文件大小跟上次重写后AOF文件大小的百分比超过auto-aof-rewrite-percentage设置的值,同时当前AOF文件大小也超过auto-aof-rewrite-min-size设置的最小值,则会触发AOF文件重写。以上面的配置为例,当现在的AOF文件大于64mb同时也大于上次重写AOF后的文件大小,则该文件就会被AOF重写。
最后需要注意的是,如果redis开启了AOF持久化功能,那么当redis服务重启时会优先使用AOF文件来还原数据库。

1.RDB

- RDB文件用于保存和还原Rdix服务器所有数据库中的所有键值对数据。
- SAVE命令由服务器进程直接执行保存操作,会阻塞服务器。
- BGSAVE命令由子进程执行保存操作,不会阻塞服务器。
- 服务器状态中会保存所有用save选项设置的保存条件,当任意一个保存条件被满足时,服务器会自动执行BGSAVE命令。
- RDB文件是一个经过压缩的二进制文件,由多个部分组成。
- 对于不同类型的键值对,RDB文件会使用不同的方式来保存它们。

2.AOF

- AOF文件通过保存所有修改数据库的写命令请求来记录服务器的数据库状态
- 命令请求会先保存到AOF缓冲区里面,之后再定期写入并同步到AOF文件。
- appendfsync选项的不同值对AOF持久化功能的安全性一级Redis服务器的性能有很大影响。 always 每个事件都同步AOF everysec 每隔一秒就要在子线程对AOF进行一次同步 no 何时同步由操作系统决定
- 服务器只要载入并重新执行保存在AOF文件中的命令,就可还原数据库。
- AOF重写可以产生一个新的AOF文件,新AOF文件和原AOF保存的数据库状态一样,但体积更小
- 在执行BGREWRITEAOF命令时,Redis会维护一个AOF重写缓冲区,该缓冲区会在子进程创建新的AOF文件期间,记录服务器执行的所有写命令。当子进程完成创建新AOF文件之后,服务器会将重写缓冲区中的所有内容追加到新的AOF文件的末尾。最后,服务器用新的AOF文件替换旧的AOF文件,以此来完成AOF文件重写操作。
  • QQ精品交流群
  • weinxin
  • 微信公众号
  • weinxin
广告也精彩
admin

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: