Redis AOF 持久化
RDB 持久化存在一个缺点是一定时间内做一次备份,如果redis意外down掉的话,就会丢失最后一次快照后的所有修改(数据有丢失)。对于数据完整性要求很严格的需求,怎么解决呢?
本篇博客接着来介绍Redis的另一种持久化方式——AOF。
1、AOF简介
Redis的持久化方式之一RDB是通过保存数据库中的键值对来记录数据库的状态。而另一种持久化方式 AOF 则是通过保存Redis服务器所执行的写命令来记录数据库状态。
比如对于如下命令:
RDB 持久化方式就是将 str1,str2,str3 这三个键值对保存到 RDB文件中,而 AOF 持久化则是将执行的 set,sadd,lpush 三个命令保存到 AOF 文件中。
2、AOF 配置
在 redis.conf 配置文件的?APPEND ONLY MODE 下:
①、appendonly:默认值为no,也就是说redis 默认使用的是rdb方式持久化,如果想要开启 AOF 持久化方式,需要将 appendonly 修改为 yes。
②、appendfilename?:aof文件名,默认是"appendonly.aof"
③、appendfsync:aof持久化策略的配置;
no表示不执行fsync,由操作系统保证数据同步到磁盘,速度最快,但是不太安全;
always表示每次写入都执行fsync,以保证数据同步到磁盘,效率很低;
everysec表示每秒执行一次fsync,可能会导致丢失这1s数据。通常选择 everysec ,兼顾安全性和效率。
④、no-appendfsync-on-rewrite:在aof重写或者写入rdb文件的时候,会执行大量IO,此时对于everysec和always的aof模式来说,执行fsync会造成阻塞过长时间,no-appendfsync-on-rewrite字段设置为默认设置为no。如果对延迟要求很高的应用,这个字段可以设置为yes,否则还是设置为no,这样对持久化特性来说这是更安全的选择。? ?设置为yes表示rewrite期间对新写操作不fsync,暂时存在内存中,等rewrite完成后再写入,默认为no,建议yes。Linux的默认fsync策略是30秒。可能丢失30秒数据。默认值为no。
⑤、auto-aof-rewrite-percentage:默认值为100。aof自动重写配置,当目前aof文件大小超过上一次重写的aof文件大小的百分之多少进行重写,即当aof文件增长到一定大小的时候,Redis能够调用bgrewriteaof对日志文件进行重写。当前AOF文件大小是上次日志重写得到AOF文件大小的二倍(设置为100)时,自动启动新的日志重写过程。
⑥、auto-aof-rewrite-min-size:64mb。设置允许重写的最小aof文件大小,避免了达到约定百分比但尺寸仍然很小的情况还要重写。
⑦、aof-load-truncated:aof文件可能在尾部是不完整的,当redis启动的时候,aof文件的数据被载入内存。重启可能发生在redis所在的主机操作系统宕机后,尤其在ext4文件系统没有加上data=ordered选项,出现这种现象? redis宕机或者异常终止不会造成尾部不完整现象,可以选择让redis退出,或者导入尽可能多的数据。如果选择的是yes,当截断的aof文件被导入的时候,会自动发布一个log给客户端然后load。如果是no,用户必须手动redis-check-aof修复AOF文件才可以。默认值为 yes。
3、开启 AOF
将 redis.conf 的?appendonly 配置改为 yes 即可。
AOF 保存文件的位置和 RDB 保存文件的位置一样,都是通过 redis.conf 配置文件的 dir 配置:
可以通过?config get dir 命令获取保存的路径。
4、AOF 文件恢复
重启 Redis 之后就会进行 AOF 文件的载入。
异常修复命令:redis-check-aof --fix 进行修复
5、 AOF 重写
由于AOF持久化是Redis不断将写命令记录到 AOF 文件中,随着Redis不断的进行,AOF 的文件会越来越大,文件越大,占用服务器内存越大以及 AOF 恢复要求时间越长。为了解决这个问题,Redis新增了重写机制,当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集。可以使用命令 bgrewriteaof 来重新。
比如对于如下命令:
如果不进行 AOF 文件重写,那么 AOF 文件将保存四条 SADD 命令,如果使用AOF 重写,那么AOF 文件中将只会保留下面一条命令:
1 sadd animals
"dog"
"tiger"
"panda"
"lion"
"cat"
也就是说 AOF 文件重写并不是对原文件进行重新整理,而是直接读取服务器现有的键值对,然后用一条命令去代替之前记录这个键值对的多条命令,生成一个新的文件后去替换原来的 AOF 文件。
AOF 文件重写触发机制:通过 redis.conf 配置文件中的 auto-aof-rewrite-percentage:默认值为100,以及auto-aof-rewrite-min-size:64mb 配置,也就是说默认Redis会记录上次重写时的AOF大小,默认配置是当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发。
这里再提一下,我们知道 Redis 是单线程工作,如果 重写 AOF 需要比较长的时间,那么在重写 AOF 期间,Redis将长时间无法处理其他的命令,这显然是不能忍受的。Redis为了克服这个问题,解决办法是将 AOF 重写程序放到子程序中进行,这样有两个好处:
①、子进程进行 AOF 重写期间,服务器进程(父进程)可以继续处理其他命令。
②、子进程带有父进程的数据副本,使用子进程而不是线程,可以在避免使用锁的情况下,保证数据的安全性。
使用子进程解决了上面的问题,但是新问题也产生了:因为子进程在进行 AOF 重写期间,服务器进程依然在处理其它命令,这新的命令有可能也对数据库进行了修改操作,使得当前数据库状态和重写后的 AOF 文件状态不一致。
为了解决这个数据状态不一致的问题,Redis 服务器设置了一个 AOF 重写缓冲区,这个缓冲区是在创建子进程后开始使用,当Redis服务器执行一个写命令之后,就会将这个写命令也发送到 AOF 重写缓冲区。当子进程完成 AOF 重写之后,就会给父进程发送一个信号,父进程接收此信号后,就会调用函数将 AOF 重写缓冲区的内容都写到新的 AOF 文件中。
这样将 AOF 重写对服务器造成的影响降到了最低。
6、AOF的优缺点
优点:
①、AOF 持久化的方法提供了多种的同步频率,即使使用默认的同步频率每秒同步一次,Redis 最多也就丢失 1 秒的数据而已。
②、AOF 文件使用 Redis 命令追加的形式来构造,因此,即使 Redis 只能向 AOF 文件写入命令的片断,使用 redis-check-aof 工具也很容易修正 AOF 文件。
③、AOF 文件的格式可读性较强,这也为使用者提供了更灵活的处理方式。例如,如果我们不小心错用了 FLUSHALL 命令,在重写还没进行时,我们可以手工将最后的 FLUSHALL 命令去掉,然后再使用 AOF 来恢复数据。
缺点:
①、对于具有相同数据的的 Redis,AOF 文件通常会比 RDF 文件体积更大。
②、虽然 AOF 提供了多种同步的频率,默认情况下,每秒同步一次的频率也具有较高的性能。但在 Redis 的负载较高时,RDB 比 AOF 具好更好的性能保证。
③、RDB 使用快照的形式来持久化整个 Redis 数据,而 AOF 只是将每次执行的命令追加到 AOF 文件中,因此从理论上说,RDB 比 AOF 方式更健壮。官方文档也指出,AOF 的确也存在一些 BUG,这些 BUG 在 RDB 没有存在。
那么对于 AOF 和 RDB 两种持久化方式,我们应该如何选择呢?
如果可以忍受一小段时间内数据的丢失,毫无疑问使用 RDB 是最好的,定时生成 RDB 快照(snapshot)非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快,而且使用 RDB 还可以避免 AOF 一些隐藏的 bug;否则就使用 AOF 重写。但是一般情况下建议不要单独使用某一种持久化机制,而是应该两种一起用,在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整。Redis后期官方可能都有将两种持久化方式整合为一种持久化模型。
redis持久化存储的方式有rdb序列化存储和aof(append only file)。aof就是将操作和数据以格式化指令的方式追加到操作日志的尾部,在append操作返回后,才进行实际的数据变更。AOF文件保存了历史所有的操作过程;当redis server需要数据恢复的时候,可以直接从该文件中读取日志进行重做就可以还原。
AOF配置
打开aof配置,只要在配置文件里面写入对应的参数开关,并写上对应的aof文件的位置即可。
appendonly yes
appendfilename "/data/redis/appendonly.aof"
aof写磁盘有三种方式
appendfsync always
每次都是要刷入磁盘 这样的话就是会卡io
appendfsync everysec
每秒刷一次
appendfsync no
操作系统自己刷
aof重写
aof文件是以追加的方式追加日志,随着时间的推移,这个文件就会越来越大;并且一些key已经被删除了,日志里面还记录了一些操作里面,就不必要了,记录太多也会影响启动恢复速度。这时候就可以将aof文件进行序列化操作,然后再进行aof,这样子文件就会变小。
auto-aof-rewrite-percentage 100
涨的百分比 0就是不rewrite
auto-aof-rewrite-min-size 64mb
最小开始rewrite的大小
redis 重写是启用一个新的子进程,然后在子进程里面把rdb里面的数据序列化到新的aof文件中。在子进程写rdb的过程中,使用pipe通信来把主进程新的修改接收保存。在rbd写完之后追加到aof文件中。报告写入完成,停止接收新的修改最后结束。主进程把aof文件替换。也把子进程到主进程切换过程中的写入追加到aof。aof_fd切换成新的fd。整个流程完成。
aof优点
使用 AOF Redis 会更具有可持久性(durable):你可以有很多不同的 fsync 策略:没有 fsync,每秒 fsync,每次请求时 fsync。使用默认的每秒 fsync 策略,写性能也仍然很不错(fsync 是由后台线程完成的,主线程继续努力地执行写请求),即便你也就仅仅只损失一秒钟的写数据。
AOF 日志是一个追加文件,所以不需要定位,在断电时也没有损坏问题。即使由于某种原因文件末尾是一个写到一半的命令(磁盘满或者其他原因),redis-check-aof 工具也可以很轻易的修复。
AOF 文件里面包含一个接一个的操作,以易于理解和解析的格式存储。你也可以轻易的导出一个 AOF 文件。例如,即使你不小心错误地使用 FLUSHALL 命令清空一切,如果此时并没有执行重写,你仍然可以保存你的数据集,你只要停止服务器,删除最后一条命令,然后重启 Redis 就可以。
aof缺点
aof的文件会比rdb文件大,恢复起来相对比较慢。
AOF 可能比 RDB 慢,这取决于准确的 fsync 策略。通常 fsync 设置为每秒一次的话性能仍然很高,如果关闭 fsync,即使在很高的负载下也和 RDB 一样的快。不过,即使在很大的写负载情况下,RDB 还是能提供能好的最大延迟保证。
Redis是一个基于BSD开源许可的内存数据结构存储系统,由于redis具有卓越的高并发读写特性,其主要用于用作数据库、缓存和消息代理。redis具有内置的复制、lua、lru、事务和不同级别的磁盘持久性,并通过哨兵机制和集群自动分区功能提供高可用性。本文主要介绍包含RDB(Redis DataBase)持久化、AOF(Append Only File)持久化、RDB和AOF混合持久化等持久化策略。
Redis以下几种持久性选项范围:
RDB持久性按指定的时间间隔执行数据集的时间点快照。
AOF持久性会记录服务器接收的每个写入操作,这些操作将在服务器启动时再次播放,以重建原始数据集。使用与Redis协议本身相同的格式记录命令,并且采用仅追加方式。当日志太大时,Redis可以在后台重写日志。
可以在同一实例中同时合并AOF和RDB。在这种情况下,当Redis重新启动时,AOF文件将用于重建原始数据集,因为它可以保证是最完整的。
如果希望只用作缓存服务器,对数据的持久性无要求,也可以完全禁用持久性。
下面着重介绍RDB和AOF持久化的特点和应用场景。
RDB持久化
RDB持久化的优点
RDB 是 Redis 默认的持久化方案。在指定的时间间隔内,写操作达到指定的次数,则会将内存中的数据写入到磁盘RDB文件中。由于RDB文件是一个非常紧凑的文件,比较容易备份,所以RDB对于灾难恢复非常有用。RDB最大限度地提高了Redis的性能,因为Redis父进程的持久化操作是通过分叉子进程实现,而父进程不会执行磁盘I O等操作。与AOF相比,RDB允许大型数据集更快地重启。
RDB持久化的缺点
RDB持久化的写入方式决定了该持久化策略并不能完全保证数据的安全性。RDB需要经常使用fork()才能使用子进程将其持久化在磁盘上。如果数据集很大,Fork()可能很耗时,并且如果数据集很大且CPU性能不佳,则可能导致Redis停止为客户端服务几毫秒甚至一秒钟。该过程如果出现宕机,则可能造成数据丢失。
RDB持久化配置
打开 redis.conf 文件,定位到 SNAPSHOTTING 对应内容
save <seconds> <changes>
# save ""
save 900 1
save 300 10
save 60 10000
dbfilename dump.rdb
dir ./
rdbcompression yes
save <指定时间间隔> <执行指定次数更新操作>,满足条件就将内存中的数据同步到硬盘中。官方出厂配置默认是 900秒内有1个更改,300秒内有10个更改以及60秒内有10000个更改,则将内存中的数据快照写入磁盘。关闭RDB,则把上面配置注释即可。
dbfilename指定本地数据库文件名,默认文件名为 dump.rdb,文件格式.rdb结尾。
dir指定数据库存放目录为当前目录
rdbcompression开启数据压缩,默认为yes,Redis采用LZF压缩方式。
RDB的触发与恢复
触发RDB快照的方式有save策略触发,flush命令(清空数据库所有数据),shutdown(关闭redis)命令,三种方式都是调用redis的bgsave机制实现快照触发。
RDB文件恢复数据的方式是将dump.rdb 文件拷贝到redis的安装目录的bin目录下,重启redis服务即可。
AOF持久化
AOF持久化的优势
AOF可以弥补RDB的不足(数据的不一致性),它采用日志的形式来记录每个写操作,并追加到文件中。Redis 重启的会根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。
使用AOF Redis更加持久,提供不同的fsync策略:完全没有fsync,每秒fsync,每个查询fsync。使用默认策略fsync时,每秒的写入性能仍然很好(fsync是使用后台线程执行的,并且在没有进行fsync的情况下,主线程将尽力执行写入操作。)
AOF日志是仅追加的日志,因此即便是断电故障,也不会出现磁盘寻道或损坏问题。即使由于某种原因(磁盘已满或其他)导致日志错误,也可以使用redis-check-aof工具=轻松修复。
AOF持久化的缺点
对于同一数据集,AOF文件通常大于等效的RDB文件。在特定的fsync策略下,AOF比RDB的效率低。通常,在将fsync设置为每秒的情况下,性能仍然很高,并且在禁用fsync的情况下,即使在高负载下,它也应与RDB一样快。即使在巨大的写负载的情况下,RDB仍然能够提供有关最大延迟的更多保证。但是如果fsync策略为aways,则随着集群负载增大,AOF记录的内容越来越大多,文件会越来越大,数据恢复也会越来越慢。
AOF持久化配置
打开 redis.conf 文件,定位到APPEND ONLY MODE 对应内容
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
说明:
appendonly 配置redis 默认关闭,开启需要手动把no改为yes
appendfilename指定本地数据库文件名,默认值为 appendonly.aof
appendfsync everysec指定更新日志条件为每秒更新,共三种策略(aways,everyse,no)
auto-aof-rewrite-min-size配置重写触发机制,当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发。
AOF触发与恢复
AOF主要根据配置文件策略触发,可以是每次执行触发,可以是每秒触发,可以不同步。
AOF的恢复主要是将appendonly.aof 文件拷贝到redis的安装目录的bin目录下,重启redis服务即可。但在实际开发中,可能因为某些原因导致appendonly.aof 文件异常,从而导致数据还原失败,可以通过命令redis-check-aof --fix appendonly.aof 进行修复
AOF的工作原理是将写操作追加到文件中,文件的冗余内容会越来越多。所以Redis 新增了重写机制,通过auto-aof-rewrite-min-size控制。当AOF文件的大小超过所设定的阈值时,Redis就会对AOF文件的内容压缩。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




