Redis(四):持久化之---AOF持久化的配置和原理

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介:

AOF持久化及AOF重写的配置:


默认AOF方式是关闭的,如下图:

wKiom1eCXvyjrKL6AAFSGLyzA5Q846.jpg-wh_50

如果要开启的话,就是把no改写成yes。如下图:

wKioL1eCXwSTC5H8AAAkOy29djo700.jpg-wh_50

默认文件名称appendonly.aof,你也可以修改文件名。默认保存目录同样也是配置文件中dir配置项中的设置,它和RDB共用一个目录。如下图:

wKiom1eCXwzzL43_AAAgurUvs48363.jpg-wh_50

默认同步策略是每秒,如下图:

wKioL1eCXx3BezMBAAAheXW2VM4565.jpg-wh_50

我们对数据库做一些操作然后查看一下appendonly.aof文件内容

wKiom1eCXyWjnzxMAAAtqM_jRwI519.jpg-wh_50

它会记录所有写操作内容。

*2 表示2个参数
$6 表示第一个参数长度为6
SELECT 第一个参数
$1 第二个参数长度为1
0 第二个参数

AOF重写策略

wKioL1eCX-mD8Dx5AAFihO2iDMI666.jpg-wh_50


AOF持久化实现原理:


AOF持久化开启后,当对数据库进行一次更新操作后,更新命令就会被追加到aof_buf缓冲区的末尾,然后由缓冲区写入到AOF文件。

AOF文件中记录的内容就是对数据更新操作的指令。这个文件本身就是以文本来记录的,如下图

wKiom1eCYBnzWFM3AAAtqM_jRwI354.jpg-wh_50

当需要恢复数据的时候,通过执行AOF文件中记录的更新指令,就可以完成。人为的看里面的指令,然后手动敲命令也可以完成。


AOF重写实现原理:


因为AOF持久化是通过记录命令的方式来保存数据库状态的,随着时间的推移AOF文件肯定会逐渐增大,如果不加以控制会对AOF持久化性能以及数据恢复造成影响。下面举例来更加形象的说明重写的必要:

我们以一个压缩列表为例

wKiom1eCYFfg-vTCAAB-iEt0rmQ375.jpg-wh_50

根据AOF的原理,那么上面红色方框中的5条命令都要追加到AOF文件中,其实我们看到最后list的状态就是BCDEF值。也就是说为例实现最后的状态,需要追加5条命令。所以在大量内存读写的业务里AOF文件增长的很快,为例解决这个问题,Redis提供了AOF重写功能。

AOF重写就是创建一个新的AOF文件来替换现有的AOF文件,实际上AOF重写并不对现有的旧AOF文件进行操作。

以上面例子来说,当进行重写的时候直接从数据库里去获取list的最新状态,然后在新的AOF文件中直接写一条rpushlist B C D E F命令,从而避免写5条的操作,这样AOF文件的增长速度就会降低,同时容量也不会特别大。

AOF重写程序aof_rewrite函数去完成创建新的AOF文件的任务,但是该函数并不会由Redis主进程去直接调用,而是使用子进程后台去执行(BGREWRITEAOF,该命令其实就是执行aof_rewrite,只不过是由子进程去调用的),这时主进程就会不被阻塞,那么就可以在执行重写的过程中父进程可以继续对外提供响应。整个过程如下:

  • 当重写被触发时父进程调用一个函数,该函数创建一个子进程用于执行BGREWRITEAOF,该子进程创建一个临时文件,然后父进程继续对外提供读写服务

  • 子进程遍历数据库,将每个键值的最新状态输出到临时文件中,在BGREWRITEAOF过程中,父进程把所有对数据库的更新命令同时写入到AOF缓冲区和AOF重写缓冲区(aof_rewrite_buf_blocks),AOF缓冲区(aof_buf)会继续同步到现有AOF文件中(一般情况下在AOF重写期间不建议把AOF缓冲区的内容同步到现有的AOF文件中,这会降低性能,默认为NO

  • AOF重写完成后子进程通知父进程,父进程调用信号处理函数

  • 信号处理函数会阻塞父进程对外提供读写操作(时间很短,不阻塞就又会出现数据不一致的情况),然后将AOF重写缓冲区的内容写入到新的AOF文件中,最后用新的AOF文件替换现有AOF文件(更名操作)


APPENDFSYNC选项说明:


参数 说明
always aof_buf缓冲区中的所有内容写入同步AOF文件中,立即执行write()fsync()系统调用。对于数据的安全性最高,但是执行最慢,如果出现故障只会丢失一个事件循环的内容。
everysec aof_buf缓冲区的所有内容写入AOF文件,如果上次同步AOF的时间距离本次超过1秒,则执行同步,每隔一秒执行一次write()fsync()系统调用。数据安全性居中,执行快,仅会丢失1秒的数据。
no aof_buf缓冲区的所有内容写入AOF文件,但是何时同步由操作系统决定,仅执行write()系统调用。写入动作效率高,但是不执行同步,但是单次同步消耗时间最长,数据安全性最低,会丢失上一次同步之后的所有数据。

这里要特别说明一下Linux系统的文件写入和同步原理,为什么要说这个,因为不解释一下这个过程,你就很难理解APPENDFSYNC选项中的no参数,如果把Always理解为总是、一直或者实时;而把everysec理解为每秒的话,那no的含义难道是不执行AOF文件同步吗?如果不同步文件,那开启AOF持久化干嘛呢?

Redis调用appendfsync函数的时候,其实是先调用一个write()函数,然后再调用sync()或者fsync()函数(对于任何程序来说只要想把数据写入磁盘其过程都一样,有些也有例外)。

用户空间:常规进程所在区域,用户发起的,此区域的代码不能直接访问硬件

内核空间:操作系统所在区域,能和设备控制器通讯

当调用了write()函数时,该函数一旦返回正常值,我们可能就认为数据已经写入到了磁盘,但实际上,操作系统在实现磁盘文件的IO时,为了保证IO的效率,会在内存中使用一段专门的地址空间,该空间叫做内核空间,而内核空间之内又会有一段是用作IO的数据缓冲区(这个缓冲区和之前说的aof_buf缓冲区不是一个概念,虽然都在内存中),write()函数的作用就是把数据写入到内核空间的IO缓冲区中。

wKioL1eCYaiDhKUNAABora4npp4231.jpg

内核空间的IO缓冲区也有一定大小,当该缓冲区没有写满时或者没有到一个同步周期时,会持续的把write()函数传递的数据写入到该缓冲区中,而当该缓冲区写满或者到了一个同步周期,则会把该缓冲区的内容提交到输出队列,当需要数据到达队列队首的时候,开始执行真正的磁盘IO操作,把数据写入磁盘(这里虽然用来写入磁盘,但是真正的动作不是移动而是复制,复制完成之后,内核空间的IO缓冲区才会释放该数据占用的空间)。这种方式叫做延迟写入。

所以这就会出现一个问题,当调用了write()函数后并不等于数据真的保存到了磁盘,但是这里又会有一个错觉,就是你再次请求该文件的时候,可以显示你最后一次更新的内容,其实这个内容并不是从磁盘上读取过来的,而是从用户空间的缓冲区读取的。接着刚才提到的问题,如果数据在内核空间的IO缓冲区内,而此时操作系统出现故障、断电等异常情况就会造成数据丢失。

为了解决数据丢失问题,Unix系统提供了syncfsyncfdatasync三个函数。

函数 功能
sync 函数返回0表示成功,该函数负责把所有内核空间中IO缓冲区内修改过的内容推送到输入队列,然后就返回,它并不等待所有磁盘IO操作完成。所以即使调用了sync函数,也不等于成功保存到磁盘了。
fsync 函数返回0表示成功,与sync不同,它只会对指定文件描述符的单一文件生效,强制与该文件相连的所有修改过的数据传送到磁盘上,并且等待磁盘IO完毕,然后返回。当该函数返回0时,才真正表示成功保存到磁盘。数据库会在调用了write()之后调用fsync()
fdatasync 它与fsync类似,它只影响文件数据部分,不涉及数据属性,比如inode信息。所以相对于fsync它需要较少的写磁盘操作。

所以看了上面的内容,你就知道APPENDFSYNCno参数的含义.




      本文转自linuxjavachen  51CTO博客,原文链接:http://blog.51cto.com/littledevil/1822967,如需转载请自行联系原作者




相关文章
|
存储 缓存 NoSQL
Redis 服务器全方位介绍:从入门到核心原理
Redis是一款高性能内存键值数据库,支持字符串、哈希、列表等多种数据结构,广泛用于缓存、会话存储、排行榜及消息队列。其单线程事件循环架构保障高并发与低延迟,结合RDB和AOF持久化机制兼顾性能与数据安全。通过主从复制、哨兵及集群模式实现高可用与横向扩展,适用于现代应用的多样化场景。合理配置与优化可显著提升系统性能与稳定性。
368 0
|
3月前
|
NoSQL 安全 关系型数据库
Redis:持久化的两种方式
Redis持久化机制主要包括RDB和AOF两种方式。RDB通过生成数据快照进行持久化,支持手动或自动触发,具有加载速度快、文件紧凑等特点,但无法实时保存数据。AOF则记录每个操作命令,保障数据更安全,支持多种写入策略,并可通过重写机制优化文件大小。两者各有优劣,常结合使用以兼顾性能与数据安全。
|
2月前
|
缓存 负载均衡 监控
135_负载均衡:Redis缓存 - 提高缓存命中率的配置与最佳实践
在现代大型语言模型(LLM)部署架构中,缓存系统扮演着至关重要的角色。随着LLM应用规模的不断扩大和用户需求的持续增长,如何构建高效、可靠的缓存架构成为系统性能优化的核心挑战。Redis作为业界领先的内存数据库,因其高性能、丰富的数据结构和灵活的配置选项,已成为LLM部署中首选的缓存解决方案。
|
3月前
|
存储 缓存 NoSQL
Redis持久化深度解析:数据安全与性能的平衡艺术
Redis持久化解决内存数据易失问题,提供RDB快照与AOF日志两种机制。RDB恢复快、性能高,但可能丢数据;AOF安全性高,最多丢1秒数据,支持多种写回策略,适合不同场景。Redis 4.0+支持混合持久化,兼顾速度与安全。根据业务需求选择合适方案,实现数据可靠与性能平衡。(238字)
|
3月前
|
存储 缓存 监控
Redis分区的核心原理与应用实践
Redis分区通过将数据分散存储于多个节点,提升系统处理高并发与大规模数据的能力。本文详解分区原理、策略及应用实践,涵盖哈希、范围、一致性哈希等分片方式,分析其适用场景与性能优势,并探讨电商秒杀、物联网等典型用例,为构建高性能、可扩展的Redis集群提供参考。
192 0
|
5月前
|
NoSQL 安全 Linux
设置Redis在CentOS7上的自启动配置
这些步骤总结了在CentOS 7系统上设置Redis服务自启动的过程。这些命令提供了一个直接且明了的方式,确保Redis作为关键组件在系统启动时能自动运行,保障了依赖于Redis服务的应用的稳定性和可用性。
491 9
|
6月前
|
存储 监控 NoSQL
流量洪峰应对术:Redis持久化策略与内存压测避坑指南
本文深入解析Redis持久化策略与内存优化技巧,涵盖RDB快照机制、AOF重写原理及混合持久化实践。通过实测数据揭示bgsave内存翻倍风险、Hash结构内存节省方案,并提供高并发场景下的主从复制冲突解决策略。结合压测工具链构建与故障恢复演练,总结出生产环境最佳实践清单。
196 9
|
9月前
|
NoSQL Redis
Redis的数据持久化策略有哪些 ?
Redis 提供了两种方式,实现数据的持久化到硬盘。 1. RDB 持久化(全量),是指在指定的时间间隔内将内存中的数据集快照写入磁盘。 2. AOF持久化(增量),以日志的形式记录服务器所处理的每一个写、删除操作 RDB和AOF一起使用, 在Redis4.0版本支持混合持久化方式 ( 设置 aof-use-rdb-preamble yes )
|
NoSQL Redis
03- Redis的数据持久化策略有哪些 ?
Redis的数据持久化包括两种策略:RDB(全量快照)和AOF(增量日志)。RDB在指定时间间隔将内存数据集保存到磁盘,而AOF记录所有写操作形成日志。从Redis 4.0开始,支持RDB和AOF的混合持久化,通过设置`aof-use-rdb-preamble yes`。
173 1
|
NoSQL 安全 Redis
redis持久化策略
Redis 提供了两种主要的持久化策略:RDB(Redis DataBase)和AOF(Append Only File)。RDB通过定期快照将内存数据保存为二进制文件,适用于快速备份与恢复,但可能因定期保存导致数据丢失。AOF则通过记录所有写操作来确保数据安全性,适合频繁写入场景,但文件较大且恢复速度较慢。两者结合使用可增强数据持久性和恢复能力,同时Redis还支持复制功能提升数据可用性和容错性。
224 5