redis 系列17 持久化 AOF
一.概述
除了上篇介绍的RDB持久化功能之外,Redis还提供了AOF(Append Only File)持久化功能。与RDB保存数据库中的键值对来记录数据库状态不同,AOF是通过保存redis服务器所执行的写命令来记录数据库状态的。AOF持久化方式记录每次对服务器写的操作,当服务器启动时,就会通过载入和执行AOF文件中保存的命令来还原服务器关闭之前的数据库状态,并在服务器载入AOF文件并还原数据库状态时打印日志。
被写入AOF文件的所有命令都是纯文本格式,可以直接打开一个AOF文件来观察。所有写命令是以追加(append)形式,保存到文件末尾。Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大。
1.1 AOF持久化的实现
AOF持久化功能的实现可以分为命令追加(append),文件写入,文件同步(sync)三个步骤。
(1) 命令追加
当AOF执行处于打开状态时,服务器在执行完一个写命令之后,会以协议格式将被执行的写命令追加到服务器状态的AOF_buf缓冲区的末尾。
struct redisServer {
//..
//aof 缓冲区
ads aof_buf
//..
}
(2) AOF文件写入与同步
Redis的服务器进程就是一个事件循环(loop),这个循环中的文件事件负责接收客户端的命令请求,以及向客户端发送命令回复。在服务器每次结束一个事件循环之前,都会调用内部flushAppendOnlyFile函数,考虑是否需要将aof_buf缓冲区中的内容写入和保存到AOF文件里面。flushAppendOnlyFile函数的行为由服务器配置appendfsync选项的值来决定。appendfsync是指数据同步到磁盘文件(AOF)的方式,默认配置是everysec选项。当同步频率是everysec值时,并且距离上次同步AOF文件已经超过一秒时,那么服务器会先将aof_buf中的内容写入到AOF文件中。
127.0.0.1:>config get Appendfsync
) "appendfsync"
) "everysec"
Appendfsync模式 |
对应flushAppendOnlyFile函数行为 |
no |
当设置appendfsync为no的时候,Redis不会主动调用fsync去将AOF日志内容同步到磁盘,所以这一切就完全依赖于操作系统的调试了。对大多数Linux操作系统,是每30秒进行一次fsync,将缓冲区中的数据写到磁盘上。从效率上讲该模式最快, 但同步到磁盘不及时,是最不安全的选择。 |
Everysec (推荐) |
当设置appendfsync为everysec的时候,Redis会默认每隔一秒进行一次fsync调用,将缓冲区中的数据写到磁盘,从效率上讲该模式足够快(和使用 RDB 持久化差不多),并且当出现故障停机时,数据库也只丢失一秒钟的命令。 |
always |
当设置appendfsync为always时,每一次写操作都会调用一次fsync,这时数据是最安全的,当然,由于每次都会执行fsync,所以其性能也会受到影响,效率上讲该模式最慢的。 |
1.2 AOF文件载入与数据还原
因为AOF文件里面包含了重建数据库状态所需的所有写命令,所以服务器只要读入并重新执行一遍AOF文件里面保存的写命令,就可以还原服务器关闭之前的数据库状态。Redis读取AOF文件并还原数据库状态的详细步骤如下:
(1) 创建一个伪客户端(因为Redis的命令只能在客户端上下文中执行),用于载入AOF文件时所使用的命令直接来源于AOF文件,而不是来自网络连接的命令。
(2) 从AOF文件中分析并读出一条写命令。
(3) 使用伪客户端执行被读出的写命令。
(4) 重复执行步骤2和3,直到AOF文件中的所有命令都被处理完为止。
比如:服务器首先读入并执行select 0 命令,之后是set msg hello命令,再之后是sadd fruits apple banana cherry命令等等,这些命令都执行完之后,服务器的数据库就被还原到之前的状态了。
1.3 AOF重写
因为AOF持久化是通过保存被执行的写命令来记录数据库状态的,所以随着服务器运行时间的流逝,AOF文件中的内容会越来越多,文件 的体积也会越来越大,随着AOF文件的体积越大,数据还原所需的时间就越多。为了解决AOF文件体积膨胀的问题,Redis提供了AOF文件重写功能。通过该功能,Redis服务器可以创建一个新的AOF文件来替代现有的AOF文件,新旧两个AOF文件所保存的数据库状态相同,但新的AOF文件不会包含任何浪费空间的冗余命令,所以新AOF文件体积比旧的AOF文件体积要小得多。
AOF文件重写并不需要对现有的AOF文件进行任何读取,分析或者写入操作,这个重写功能是通过读取服务器当前的数据库状态来实现的。比如:使用写命令 rpush list "A", rpush list "B", rpush list "C", rpush list "D" 此时必须在AOF文件中写入四条命令。重写可以是直接从数据库中读取键list的值,然后用一条rpush list "A","B","C","D"命令来代替。
1.4 AOF 后台重写
重写作为一种辅助维护,Redis不希望AOF重写造成服务器无法处理请求,所以Redis决定将AOF重写程序放到子进程里执行。对AOF 文件进行重写,执行bgrewriteaof命令, Redis将生成一个新的 AOF 文件,这个文件包含重写当前数据集所需的最少命令。bgrewriteaof后台重写实现步骤如下:
(1) Redis执行 fork() ,现在同时拥有父进程和子进程。
(2)子进程开始将新 AOF 文件的内容写入到临时文件。
(3)对于所有新执行的写入命令,父进程一边将它们累积到一个内存缓存中,一边将这些改动追加到现有 AOF 文件的末尾,这样样即使在重写的中途发生停机,现有的 AOF 文件也还是安全的。
(4)当子进程完成重写工作时,它给父进程发送一个信号,父进程在接收到信号之后,将内存缓存中的所有数据追加到新 AOF 文件的末尾。
(5)现在Redis原子地用新文件替换旧文件,之后所有命令都会直接追加到新 AOF 文件的末尾。
1.5 AOF优点
(1) 可以使用不同的fsync(同步)策略:无fsync、每秒fsync、每次写的时候fsync。使用默认的每秒fsync策略,Redis的性能依然很好(fsync是由后台线程进行处理的,主线程会尽力处理客户端请求),一旦出现故障,你最多丢失1秒的数据。
(2) AOF文件是一个只进行追加的日志文件,所以不需要写入seek,某些原因(如:宕机)未执行完整的写入命令,你也可使用redis-check-aof工具修复这些问题。
(3) AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写.整个重写操作是绝对安全,即使重写过程中发生停机,现有的 AOF 文件也不会丢失。一旦新 AOF 文件创建完毕,Redis就会从旧 AOF 文件切换到新 AOF 文件,并开始对新 AOF 文件进行追加操作。
(4) AOF 文件有序地保存了对数据库执行的所有写入操作,这些写入操作以Redis协议的格式保存,因此 AOF 文件的内容非常容易被人读懂,对文件进行分析(parse)也很轻松。导出(export) AOF 文件也非常简单。举个例子:如果你不小心执行了 FLUSHALL 命令,但只要 AOF 文件未被重写,那么只要停止服务器,移除 AOF 文件末尾的 FLUSHALL 命令,并重启Redis,就可以将数据集恢复到 FLUSHALL 执行之前的状态。
1.5 AOF缺点
(1) 对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积。
(2) 根据所使用的fsync(同步)策略,AOF 的速度可能会慢于 RDB 。在一般情况下,每秒fsync的性能依然非常高,而关闭fsync可以让 AOF 的速度和 RDB 一样快,即使在高负荷之下也是如此。不过在处理巨大的写入载入时,RDB 可以提供更有保证的最大延迟时间(latency)。
1.6 如何选择使用哪种持久化方式
一般来说,如果想达到足以媲美PostgreSQL的数据安全性,应该同时使用两种持久化功能。如果你非常关心你的数据,但仍然可以承受数分钟以内的数据丢失,那么你可以只使用 RDB 持久化。
有很多用户都只使用 AOF 持久化,但我们并不推荐这种方式:因为定时生成 RDB 快照(snapshot)非常便于进行数据库备份,并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快,除此之外,使用 RDB 还可以避免之前提到的 AOF 程序的 bug 。注意: 因为以上提到的种种原因,未来可能会将 AOF 和 RDB 整合成单个持久化模型。
二. AOF持久化配置
redis默认是关闭AOF机制,需要在配置文件中打开AOF, 注意通过 CONFIG SET 设置的配置重启Redis服务后就会失效,如果要永久有效,需在redis.conf中打开AOF功能。脚本如下:
127.0.0.1:>config set appendonly yes
OK
打开后每当Redis执行一个改变数据集的命令时(如:set),这个命令就会被追加到AOF文件的末尾,这样当redis重新启动时,程序就可以通过重新执行AOF文件中的命令来达到重建数据集的目的。
2.1 AOF配置相关选项
选项 |
取值 |
说明 |
Appendonly |
no|yes |
是否开启AOF机制 |
Appendfilename |
"appendonly.aof" |
Aof文件名 |
Appendfsync |
no|appendfsync|always |
AOF持久化同步频率 |
no-appendfsync-on-rewrite |
No | yes |
在日志进行BGREWRITEAOF时,如果设置为yes表示新写操作不进行同步fsync,只是暂存在缓冲区里,避免造成磁盘IO操作冲突,等重写完成后在写入。redis中默认为no |
auto-aof-rewrite-percentage |
100 |
当前AOF文件大小是上次日志重写时的AOF文件大小两倍时,发生BGREWRITEAOF操作。 |
auto-aof-rewrite-min-size |
64mb |
当前AOF文件执行BGREWRITEAOF命令的最小值,避免刚开始启动Reids时由于文件尺寸较小导致频繁的BGREWRITEAOF。 |
aof-load-truncated |
yes |
Redis再恢复时,忽略最后一条可能存在问题的指令 |
aof-use-rdb-preamble |
no |
新增RDB-AOF混合持久化格式,在开启了这个功能之后,AOF重写产生的文件将同时包含RDB格式的内容和AOF格式的内容 |
2.2 演示
下面测试AOF持久化,AOF文件是可识别的纯文本,文件的内容就是一个个的Redis标准命令,下面使用两个set命令:
127.0.0.1:> set name1 "zs"
OK
127.0.0.1:> set name2 "ls"
OK
下面查看AOF文件, 可以发现里面是一个个命令, 上面执行的写命令对应的文件内容如下:
[hsr@xuegod64 redis]$ cat appendonly.aof
name1
$
zs
*
$
set
$
name2
$
ls
redis 系列17 持久化 AOF的更多相关文章
- 二、redis系列之持久化
1. 绪言 redis是一种内存数据库,它把数据存储在服务器的内存当中,这样极大地保证了redis数据库的性能,但也为数据安全带来了隐患——redis所在服务器重启或者发生宕机后,redis数据库里的 ...
- Redis系列(四)--持久化
持久化就是将数据的更新异步的保存到磁盘中 持久化方式: 1.快照:某个时间点数据的备份 MySQL dump.Redis RDB 2.写日志:MySQL BinLog.HBASE Hlog.Redis ...
- redis 系列16 持久化 RDB
一.概述 Redis是内存数据库,一旦服务器进程退出,服务器中的数据库内存数据状态也会消失.为了解决这个问题,Redis提供了RDB 持久化功能,这个功能可以将redis在内存中的数据库状态保存到磁盘 ...
- 深入理解Redis系列之持久化
redis持久化配置 redis.conf // RDB配置 save 900 1 save 300 10 save 60 10000 // AOF配置 appendonly yes //AOF三种同 ...
- 【目录】redis 系列篇
随笔分类 - redis 系列篇 redis 系列27 Cluster高可用 (2) 摘要: 一. ASK错误 集群上篇最后讲到,对于重新分片由redis-trib负责执行,关于该工具以后再介绍.在进 ...
- redis系列:RDB持久化与AOF持久化
前言 什么是持久化? 持久化(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘).持久化的主要应用是将内存中的对象存储在数据库中,或者存储在磁盘文件中.XML数 ...
- Redis系列(三):Redis的持久化机制(RDB、AOF)
本篇博客是Redis系列的第3篇,主要讲解下Redis的2种持久化机制:RDB和AOF. 本系列的前2篇可以点击以下链接查看: Redis系列(一):Redis简介及环境安装. Redis系列(二): ...
- NoSql数据库Redis系列(4)——Redis数据持久化(AOF)
上一篇文章我们介绍了Redis的RDB持久化,RDB 持久化存在一个缺点是一定时间内做一次备份,如果redis意外down掉的话,就会丢失最后一次快照后的所有修改(数据有丢失).对于数据完整性要求很严 ...
- Redis系列之----Redis的两种持久化机制(RDB和AOF)
Redis的两种持久化机制(RDB和AOF) 什么是持久化 Redis的数据是存储在内存中的,内存中的数据随着服务器的重启或者宕机便会不复存在,在生产环境,服务器宕机更是屡见不鲜,所以,我们希望 ...
随机推荐
- 微服务框架——SpringCloud(三)
1.Zuul服务网关 作用:路由转发和过滤,将请求转发到微服务或拦截请求.Zuul默认集成了负载均衡功能. 2.Zuul实现路由 a.新建springboot项目,依赖选择 Eureka Discov ...
- .Net异步关键字async/await的最终理解
由于之前的项目中自己突然想试试异步action,于是使用了一下,突然就对异步action的执行流程以及原理及其好处产生了兴趣,再参考了一些文章之后,就做了下归类. 我们可以不需要太深入的理解底层,但是 ...
- 展开被 SpringBoot 玩的日子 《 二 》 WEB 开发
上篇文章介绍了Spring boot初级教程 :< spring boot(一):入门篇 >,方便大家快速入门.了解实践Spring boot特性:本篇文章接着上篇内容继续为大家介绍spr ...
- Python序列化proto中repeated修饰的数据
一.repeated修饰复合数据结构,即message时 1.使用message的add方法初始化新实例 2.分别对新实例中的每个元素赋值:或使用CopyFrom(a)拷贝a中的元素值 message ...
- Python面向对象编程指南
Python面向对象编程指南(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1SbD4gum4yGcUruH9icTPCQ 提取码:fzk5 复制这段内容后打开百度网 ...
- 利用jquery-barcode.js实现生成条形码
jquery-barcode官网 js下载地址-github 代码示范(官网上也有) <!DOCTYPE html> <html> <head> <meta ...
- Pycharm安装+python安装+环境配置
Pycharm 工具: 1.安装jdk(64位):jdk-8u65-windows-x64.exe 路径:C:\Program Files\Java(默认路径) 2.配置环境 步骤一: 系统变量→新建 ...
- TCP协议中是如何保证报文可靠传输的
1.什么是TCP的可靠传输 它向应用层提供的数据是无差错的.有序的.无丢失的,换言之就是:TCP最终递交给应用层的数据和发送者发送的数据是一模一样的. 2.TCP保证可靠传输的办法有哪些? TCP采用 ...
- vue 学习
1.安装vue.js 学习链接: https://cn.vuejs.org/v2/guide/ vue官方文档 vscode 软件框架 https://doc.vux.li/zh-CN/ vux文档
- python错误和异常
一:语法错误syntax errors 熟悉语法! 二:异常 ①打印错误信息时,异常的类型作为异常的内置名显示,并以调用栈的形式显示具体信息 ②常见的异常: ...