Redis持久性方案

Redis是一个内存数据库,所有的数据都存储在内存中。为了避免进程退出造成的数据永久丢失,需要定期将Redis中的数据以某种形式从内存保存到硬盘。下一次Redis重启时,通过使用持久文件实现数据恢复。此外,对于灾难备份,您可以将持久性文件复制到远程位置。

Redis提供了许多不同层次的持久性:一个是RDB,另一个是AOF。

RDB持久性可以在指定的时间间隔内生成数据集的时间点快照,并以二进制方式将数据库的快照保存到磁盘。

AOF持续记录服务器执行的所有变更操作命令。AOF文件中的所有命令都以Redis协议的格式保存,新的命令将附加到文件的末尾。Redis还可以在后台重写AOF文件,这样AOF文件的卷就不会超过保存数据集状态所需的实际大小。

Redis既可以使用AOF持久性,也可以使用RDB持久性。这种情况下,Redis重启时会优先使用AOF文件还原数据集,因为AOF文件保存的数据集通常比RDB文件保存的数据集更完整。您甚至可以关闭持久性,以便数据只在服务器运行时存在。

理解RDB坚持和AOF坚持的异同是非常重要的。以下小节将详细介绍这两个持久性函数,并解释它们的异同。

RDB快照

先说Redis的第一个持久化策略,RDB快照。Redis支持将当前内存数据的快照保存为数据文件的持久化机制,但是连续写入的数据库怎么生成快照呢?Redis巧妙地利用fork命令的写时复制机制,将当前进程从一个子进程中分叉出来,子进程根据内存快照将数据循环保存到RDB文件中。

默认情况下,Redis将数据库快照保存在根目录下名为dump.rdb的二进制文件中。保存目录可以通过目录配置指定,dbfilename指定文件名。可以设置Redis,比如“保存N M”,就是说当N秒内数据项有M个变化,满足这个条件时,数据集会自动保存一次。例如,您可以配置为在10分钟内有100次写入时生成快照,也可以配置为在1分钟内有1000次写入时生成快照。支持多个规则一起生效,匹配哪个规则生效。这些规则是在Redis的配置文件中定义的。您也可以通过Redis的CONFIG SET命令在Redis运行时设置规则,而无需重新启动Redis。

例如,以下设置将使Redis在满足“60秒内至少更改了1000个键”的条件后自动保存数据集:

节省60 1000

您也可以调用SAVE或BGSAVE来手动让Redis保存数据集。SAVE命令执行同步操作,并以RDB文件的形式保存所有数据的快照。SAVE命令很少在生产环境中直接使用,因为它会阻塞所有客户端请求,所以不应该在生产环境中使用,可以改用BGSAVE命令。BGSAVE命令由一个fork子进程执行,所以客户端请求不会被阻塞,只有fork子进程会阻塞服务器。此外,当自动触发RDB持久性时,Redis会选择BGSAVE而不是SAVE进行持久性。

Redis自动RDB持久化在内部由serverCron周期性操作函数、脏计数器和lastsave时间戳实现。服务器每100ms执行一次Cron,检查服务器状态,包括检查“save N M”是否满足条件,如果满足,执行BGSAVE;当然,这也包括AOF重写支票。脏计数器是Redis服务器维护的一个状态,记录最后一次执行BGSAVE/SAVE命令后,服务器状态被修改的次数。当BGSAVE/SAVE完成时,脏将被重置为0。lastsave时间戳也是Redis服务器维护的状态,记录BGSAVE/SAVE最后一次成功执行的时间,当前时间减去lastsave必须满足m..

除了手动和自动,还有其他情况会触发BGSAVE:

在主从复制场景中,如果从节点执行完全复制操作,主节点将执行BGSAVE命令,并向从节点发送rdb文件。

执行关机命令时自动执行rdb持久性。

此外,应该理解,写操作是在新的过程中执行的。当生成新的RDB文件时,Redis生成的子进程首先将数据写入临时文件,然后通过原子重命名系统调用将临时文件重命名为RDB文件,这样每当出现故障时,Redis的RDB文件总是可用的。

这种持久化的方式叫做快照。但是,我们可以清楚地看到,RDB有其缺点,即一旦数据库出现问题,存储在我们的RDB文件中的数据就不是全新的,并且从最后一个RDB文件生成到Redis停机时间的所有数据都会丢失。在某些服务中,如果间隔内的数据丢失是可以容忍的,我们还建议这些服务使用RDB进行持久化,因为开放RDB的成本并不高。但是,对于其他要求高数据安全性并且不能容忍数据丢失的应用程序,RDB无能为力,因此Redis引入了另一个重要的持久性机制,AOF日志持久性。

为了尽可能减少RDB文件的数量,Redis默认使用LZF算法压缩RDB文件。虽然压缩需要时间,但它可以大大减少RDB文件的数量,因此默认情况下压缩是打开的,参数是rdbcompression。需要注意的是,RDB文件的压缩并不是针对整个文件,而是针对数据库中的字符串,并且只有当字符串达到一定长度时才进行压缩。

除了压缩之外,您还可以检查由参数rdbchecksum设置的RDB文件,默认值为“是”。写文件和读文件的时候都管用。在写入和启动文件时,关闭校验和可以将性能提高约10%,但在数据损坏时无法找到校验和。

另外,如果bgsave有错误,Redis是否停止执行写命令。Redis提供了一个参数stop-writes-on-bgsave-error,设置为yes,这样当硬盘出现问题时,可以及时发现,避免大量数据丢失;如果设置为否,Redis将继续执行写命令,而不管bgsave的错误。当对Redis服务器的系统进行监控时,该选项应设置为“否”..

说说FORK的开销吧。

父进程可以通过fork操作创建子进程,而第一代Unix系统实现了一个傻瓜一样的进程创建:执行fork系统调用时,内核复制父进程的整个user 空,并将副本分配给子进程。这种行为非常耗时,因为它需要完成以下任务:为子进程页表分配页面、为子进程分配页面、初始化子进程页表、将父进程页复制到子进程的相应页面。

目前Linux的fork是用写时复制页面实现的。写时复制是一种可以延迟甚至避免复制数据的技术。此时,内核并不复制整个进程地址空,而是让父进程和子进程共享同一个副本。只有在需要写的时候,才会复制数据,这样每个进程都有自己的副本。也就是说,资源只有在需要写入的时候才会被复制,而在此之前,资源只能以只读方式共享。这种技术会延迟地址空之间的页面复制,直到发生实际写入。所以即使fork内存进程大,内存消耗和时间消耗也是很小的。

现在子进程虽然不会在fork期间复制父进程的data 空,但是会复制内存页表;父进程的data 空越大,内存页表越大,fork期间复制的时间越长。这个问题也是Redis内存不能太大的原因之一,当然,延长的恢复时间也是Redis内存不能太大的原因。

AOF圆木

通过以上分析,我们知道RDB快照丢失最近写入但尚未保存在快照中的数据的概率很高。虽然数据安全不是某些程序最重要的考虑因素,但快照功能不适合那些追求数据安全的程序。从1.1版开始,Redis增加了一个更实时的持久性方法,即AOF持久性。AOF日志的全名是仅附加文件。我们可以从名称中看到它是一个附加的日志文件。与RDB相比,AOF具有更好的实时性,因此成为主流的持久性方案。

MySQL数据库的AOF文件和binlog的区别在于,AOF是纯文本格式,具有兼容性好、可读性强、易于处理、操作简单、避免二次开销等优点。它记录的内容是Redis标准命令。打开AOF暂留命令如下:

仅附录是

appendfilename "appendonly.aof "

从现在开始,每当Redis执行一个改变数据集的命令,这个命令就会被追加到AOF文件的末尾。这样,当Redis重新启动时,程序可以重新执行AOF文件中的命令来重建数据集。

由于Redis的每个写命令都需要记录,所以不需要触发AOF。以下描述AOF的执行流程:

命令追加

Redis首先将写命令追加到缓冲区,而不是直接写入文件,主要是为了避免每次都将写命令直接写入硬盘,导致硬盘IO成为Redis加载的瓶颈。

文件写入和文件同步

Redis为AOF缓存提供了多种文件同步策略,涉及操作系统的写功能和fsync功能。描述如下:

为了提高文件写入的效率,在现代操作系统中,当用户调用write函数将数据写入文件时,操作系统通常会将数据临时存储到内存缓冲区中,只有当缓冲区填满或超过指定的时限后,缓冲区中的数据才能实际写入硬盘。这个操作虽然提高了效率,但是也带来了安全问题:如果计算机停止,内存缓冲区的数据会丢失;因此,系统还提供了fsync、fdatasync等同步功能,可以强制操作系统立即将缓冲区中的数据写入硬盘,从而保证数据安全。

AOF缓存的文件同步策略由参数appendfsync控制,每个值的含义如下:

始终:命令写入aof_buf后,立即调用系统fsync操作同步到aof文件,fsync完成后线程返回。在这种情况下,每次有写命令,都必须同步到AOF文件,硬盘IO就成了性能瓶颈。Redis只能支持几百个TPS左右的写入,严重降低了Redis的性能;即使有固态硬盘,每秒也只能处理数万条命令,会大大降低SSD的寿命。

否:命令写入aof_buf后,调用系统写操作,不对aof文件进行fsync同步;同步是操作系统的责任。通常同步周期为30秒。在这种情况下,文件同步时间是不可控的,缓冲区中会积累大量数据,因此数据安全性无法保证。

Everysec:命令写入aof_buf后,调用系统写操作,写完成后线程返回;一个特殊的线程每秒调用一次fsync同步文件操作。Everysec是以上两种策略的折中,是性能和数据安全的平衡,所以是Redis的默认配置,也是推荐的配置。

文件重写

因为AOF的工作方式是不断在文件末尾添加命令,所以随着写命令数量的增加,AOF文件的大小会越来越大。例如,如果您为一个计数器调用INCR 100次,AOF文件需要使用100个条目来保存计数器的当前值。但实际上,只需一个SET命令就足以保存计数器的当前值,剩下的99条记录其实是多余的。此外,还有一些过时的数据,无效的数据也可以删除。

过大的AOF文件不仅会影响服务器的正常运行,还会导致数据恢复时间过长。为了处理这种情况,Redis支持一个有趣的特性,它可以在不中断服务客户端的情况下重建AOF文件。执行BGREWRITEAOF命令,Redis将生成一个新的AOF文件,其中包含重建当前数据集所需的最少命令。

AOF重写的生成过程类似于RDB快照,巧妙利用了写时复制机制。也是fork的子进程,子进程根据内存快照和命令合并规则写入新的AOF文件。当主进程叉在完成子线程后继续接受请求时,所有的写命令仍然按照appendfsync策略写入aof缓冲区并同步到硬盘,从而保证了原AOF机制的正确性。但是,由于fork操作使用写时复制技术,因此子进程只能在fork操作期间共享内存数据。由于父进程仍在响应该命令,Redis使用aof重写缓冲区来保存这部分新日志,以防止这部分数据在生成新的AOF文件期间丢失。也就是说,在bgrewriteaof的执行过程中,Redis的写命令被附加到两个缓冲区,aof_buf和AOF _ rewrite _ buf。

当子进程完成写入新的AOF文件时,它会向父进程发送一个信号,而父进程会更新统计信息,这可以通过信息持久性来查看。然后,父进程将AOF重写缓冲区中的数据写入新的AOF文件,这确保了新的AOF文件保存的数据库状态与服务器的当前状态一致。然后调用原子重命名命令,用新的AOF文件替换旧的AOF文件,并完成AOF重写。

这里需要注意,因为主进程会将aof _ rewrite _ buf缓存附加到新的日志文件中。当主进程追加日志时,它将不会处理其他请求。如果aof_rewrite_buf特别大,比如几百米,可能会导致Redis几秒甚至几十秒不响应。

从上面的过程可以看出,RDB和AOF操作是高性能的顺序IO操作。当通过RDB文件或AOF日志恢复数据库时,数据也会按顺序读取并加载到内存中。因此,不会导致随机读取磁盘。

文件重写的触发分为手动触发和自动触发:

手动触发:直接调用bgrewriteaof命令,类似于bgsave:所有fork子进程都做特定的工作,只有发生fork时才会全部阻塞。

自动触发:根据自动重写最小大小和自动重写百分比参数以及aof_current_size和aof_base_size状态,确定触发时机。

自动AOF重写-最小大小表示执行aof重写时的最小文件大小,默认值为64MB。

自动AOF重写百分比表示当前AOF大小与上一次重写中的总大小之比,即增长率达到设定值。

只有同时满足自动AOF重写最小大小和自动重写百分比两个参数,才会自动触发重写操作,即BG重写操作。

其中,可以通过config get命令查看参数:

127.0.0.1:6391 >配置获取自动重写最小大小

1)“自动改写最小尺寸”

2) "64000000"

127.0.0.1:6391 >配置获取自动重写百分比

1)“自动重写百分比”

2) "100"

可以通过信息持久性查看状态:

127.0.0.1:6379 >信息持久性

#坚持

aof_enabled:1

aof _ write _ in _ progress:0

aof _ write _ scheduled:0

aof _ last _ write _ time _ sec:0

aof _ current _ rewrite _ time _ sec:-1

aof_last_bgrewrite_status:ok

aof_last_write_status:ok

aof_current_size:40876638

aof_base_size:2217565

aof _ pending _重写:0

aof_buffer_length:0

aof _ write _ buffer _ length:0

aof_pending_bio_fsync:0

aof _ delay _ fsync:0

另外,在aof重写过程中,是否采用增量式“文件同步”策略由参数aof-write-increment-fsync控制,默认为“是”,必须为“是”。在重写过程中,每32M数据执行一次文件同步,这可以减少将“大量大文件”写入磁盘的操作数量。

bgrewriteaof机制在一个子进程中重写一个aof,从而不阻塞主进程处理其他命令,解决了aof文件过大的问题。现在,问题出现了。同时,在执行BGRewriteOf操作和主进程写一个文件操作时,两者都会操作磁盘,而BGRewriteOf往往涉及大量的磁盘操作,在写一个文件时会导致主进程阻塞。现在出现了no-appendfsync-on-write参数。

如果这个参数设置为no,是最安全的方式,不会丢失数据,但是会忍受阻塞的问题。如果设置为yes呢?这相当于将appendfsync设置为no,这意味着不执行任何磁盘操作,只写入一个缓冲区,所以这不会造成阻塞,但是如果此时Redis挂起,数据就会丢失。丢失了多少数据?在Linux操作系统默认设置下,数据最多会丢失30s。所以,如果应用系统受不了延迟,能容忍少量数据丢失,则设置为yes。如果应用系统不能承受数据丢失,则设置为否。

AOF更新战略?

如前所述,在AOF,如果AOF缓冲区的文件同步策略是everysec,那么:在主线程中,将命令写入aof_buf,然后调用系统写操作,写完成后主线程返回;一个特殊的文件同步线程每秒调用一次fsync文件同步操作。这种方法的问题是,如果硬盘负载过高,fsync操作可能会超过1s;如果Redis主线程继续高速向aof_buf写命令,硬盘上的负载可能会越来越大,IO资源消耗会更快;如果此时Redis进程异常退出,丢失的数据会越来越多,可能会超过1s。

为此,Redis的处理策略如下:每次主线程执行AOF时,都会比较最后一次fsync的成功时间;如果距离上次小于2s,主线程直接返回;如果超过2s,主线程将阻塞,直到最后一次fsync同步完成。所以如果系统硬盘负载太大,fsync速度会太慢,导致Redis主线程堵塞;此外,在每秒配置下,AOF最多可能丢失2个数据,而不是1个。具体来说,看看对Redis AOF更新策略的分析

定位aof附加阻塞问题的方法监视信息持久性中的延迟同步,当AOF附加阻塞发生时,索引被累加。此外,当AOF被阻止时的Redis日志:fsync的异步操作花费太长时间.不等待同步完成就写入AOF缓冲区,这可能会降低Redis的速度。

如果AOF附加阻塞频繁发生,则系统硬盘负载过大;可以考虑更换IO速度较快的硬盘,或者通过IO监控分析工具分析系统的IO负载。

流水线有什么区别?

对于流水线的操作,具体流程是客户端一次性发送N个命令,然后等待这N个命令的返回结果一起返回。采用管道化意味着放弃对每个命令返回值的确认。在这种情况下,n个命令在同一个执行过程中执行。因此,当appendfsync设置为everysec时,可能会有一些偏差,因为这n个命令的执行时间可能会超过1秒甚至2秒。但是可以保证最长时间不会超过这N个命令的执行次数之和。

如果AOF的文件有问题怎么办?

当程序正在写入AOF文件时,服务器可能会停止。如果停止导致AOF文件损坏,Redis将在重新启动时拒绝加载AOF文件,从而确保数据一致性不会被破坏。出现这种情况时,您可以使用以下方法修复错误的AOF文件:创建现有AOF文件的备份。然后,使用Redis附带的Redis-check-of-fix程序修复原始AOF文件。

然后可以选择使用diff -u来比较修复后的AOF文件和原始AOF文件的备份,并检查这两个文件之间的差异。再次重启Redis服务器,等待服务器加载修复后的AOF文件,恢复数据。

但是,如果AOF文件的结尾不完整。),并且打开了aof-load-truncated参数,将在日志中输出一条警告,Redis将忽略aof文件的结尾并成功启动。缺省情况下,加载截断参数打开。

RDB和AOF的优缺点

RDB的优势?

RDB是一个非常紧凑的文件,它体积小,网络传输速度快。它保存了Redis在某个时间点的数据集。这种文件非常适合备份,而且恢复速度比AOF快得多。当然,与AOF相比,RDB最重要的优势之一是对性能的影响相对较小。当父进程保存RDB文件时,唯一要做的事情是分叉出一个子进程,然后这个子进程将处理所有下一步的保存工作,并且父进程不需要执行任何磁盘输入/输出操作。

RDB的缺点?

RDB文件的致命缺点是数据快照持久化的方式决定了不可能实时持久化。今天,当数据变得越来越重要时,丢失大量数据通常是不可接受的,因此AOF持久性已成为主流。此外,RDB文件需要满足特定的格式,兼容性差。

AOF的优势?

与RDB持久性相比,AOF具有支持二级持久性和兼容性好的优点。您可以设置不同的fsync策略,如无fsync、每秒fsync或每次执行写命令时fsync。AOF的默认策略是每秒一次同步。在这种配置下,Redis仍然可以保持良好的性能,即使出现故障关机,最多也只会丢失一秒钟的数据。AOF文件是一个仅附加的日志,所以不需要寻找写AOF文件。即使日志由于某些原因包含不完整的命令。),redis-check-aof工具可以很容易地解决这个问题。

当AOF文件的容量变得太大时,Redis可以在后台自动重写AOF:重写后的新AOF文件包含恢复当前数据集所需的最小命令集。整个重写操作是绝对安全的,因为在创建新的AOF文件的过程中,Redis会继续向现有的AOF文件追加命令,即使重写过程中出现宕机,现有的AOF文件也不会丢失。一旦创建了新的AOF文件,Redis将从旧的AOF文件切换到新的AOF文件,并开始追加新的AOF文件。AOF文件有序地保存在数据库上执行的所有写操作,这些写操作以Redis协议的格式解析保存,因此AOF文件的内容可以很容易地被读取和分析。导出)AOF AOF文件也很简单:例如,如果你不小心执行了FLUSHALL命令,但是只要AOF文件没有被重写,只要停止服务器,删除AOF文件末尾的FLUSHALL命令,重新启动Redis,将数据集恢复到执行FLUSHALL之前的状态。

AOF有什么缺点?

AOF文件的容量通常大于RDB文件,并且恢复速度很慢。根据所使用的同步同步策略,对于相同的数据集,AOF可能比RDB慢。正常情况下,每秒fsync的性能还是很高的,关闭fsync可以让AOF和RDB一样快。另外,AOF过去也有过这样的bug,因为有些命令,当AOF文件重新加载时,数据集无法恢复到保存时的原始状态。虽然这种bug在AOF文件中并不常见,但RDB几乎不可能出现这种bug。

我应该用哪个,RDB还是AOF?

首先要明白,无论是RDB还是AOF,持久性的开放都要付出性能代价:对于RDB持久性,一方面bgsave执行fork操作时Redis主进程会阻塞,另一方面子进程在向硬盘写入数据时会带来IO压力。但是,如果企业能够容忍几分钟到10分钟的数据丢失,RDB是一个不错的选择;否则,选择AOF。

关于AOF持久性,向硬盘写入数据的频率大大增加,IO压力更大,甚至可能导致添加AOF的阻塞问题。此外,AOF文件的重写类似于RDB的bgsave,在子进程的fork和io压力问题时会出现阻塞。相对来说,由于AOF向硬盘写入数据的频率更高,对Redis主进程的性能影响会更大。

在实际的生产环境中,根据数据量、应用程序对数据的安全要求以及预算限制等不同情况,会有不同的持久性策略。例如根本不使用任何持久性,使用RDB或AOF,或者同时启用RDB和AOF持久性。另外,持久化的选择必须和Redis的主从策略一起考虑,因为主从复制和持久化还具有数据备份的功能,主从可以独立选择持久化方案。比如完全关闭大师暂留,让大师的表现可以做到最好;而奴隶只能依靠AOF。但这种情况下,如果主服务因故障而停机,如果系统中存在自动上拉机制,那么主重启后数据将为空,从同步数据将变为空,这意味着数据丢失。所以尽量避免这种情况。

RDB和AOF的互动?

在版本号大于等于2.4的Redis中,在执行BGSAVE的过程中不能执行BGREWRITEAOF。相反,BGSAVE不能在BGREWRITEAOF执行期间执行。这可以防止两个Redis守护程序同时在磁盘上执行大量I/O操作。

如果正在执行BGSAVE,并且用户明确调用了BG write of命令,服务器将以OK状态回复用户,并通知用户BG write of已被安排执行:一旦执行了BGSAVE,将正式开始BG write of。当Redis启动时,如果同时打开了RDB持久性和AOF持久性,程序会优先使用AOF文件还原数据集,因为AOF文件中存储的数据通常是最完整的。

导入RDB和AOF数据

这些持久化的数据有什么用,当然是为了重启后的数据恢复。Redis是一个内存数据库,无论是RDB还是AOF,它都只是一个保证数据恢复的措施。因此,当使用RDB或AOF进行恢复时,Redis将读取RDB或AOF文件并将它们重新加载到内存中。相比MySQL等数据库的启动时间会长很多,因为MySQL不需要将数据加载到内存中。

但是相对来说,MySQL在开始提供服务时,其访问的热数据会慢慢加载到内存中,这通常叫做预热,在预热完成之前性能不会太高。Redis的优点是一次将数据加载到内存中,一次预热。这样,只要Redis启动,Redis提供的服务就会非常快。

然而,RDB和AOF在创业时间上存在一些差异。RDB的创业时间会更短有两个原因。首先,RDB文件中的每个数据只有一条记录,可能没有像AOF日志那样的数据多次操作的记录。因此,每条数据只需写入一次。另一个原因是,RDB文件的存储格式与内存中Redis数据的编码格式一致,因此不需要对数据进行编码。CPU消耗比AOF日志加载小得多。

注意:当redis启动时,如果rdb持久化和aof持久化都打开,程序将首先使用aof还原数据集,因为aof保存的数据通常是最完整的。如果aof文件丢失,数据库内容在启动后为空。

注意:如果您想将正在运行的redis数据库从RDB切换到AOF,建议首先使用动态切换,然后修改配置文件并重新启动数据库。

在Redis 2.2或更高版本中,您可以在不重启的情况下从RDB切换到AOF:

为最新的dump.rdb文件创建备份,并将备份放在安全的地方。执行以下两个命令:

127.0.0.1:6379 >配置设置目录/应用程序/redis/数据/redis-8836

127.0.0.1:6379 >仅配置集附件是

127.0.0.1:6379 >配置集保存""

确保在执行该命令后,数据库中的键的数量没有改变。确保写入命令正确地附加到AOF文件的末尾。

第二步是打开AOF功能。Redis将一直阻塞,直到创建初始AOF文件。之后,Redis将继续处理命令请求,并开始将写命令附加到AOF文件的末尾。

步骤3用于关闭RDB功能。此步骤是可选的。如果您愿意,您可以同时使用RDB和AOF持久性函数。

1.《aof 配置方案:Redis持久化RDB和AOF》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。

2.《aof 配置方案:Redis持久化RDB和AOF》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。

3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/jiaoyu/1679276.html