🍊 Redis持久化
持久化是一种非常重要的技术,可以帮助我们恢复数据、保障系统可用性,让我们今天走进这个神奇的世界,详细地了解一下它的工作原理及应用场景。
🎉 什么是持久化?
首先,我们需要明确一下持久化的概念。简单来说,持久化就是将数据保存到磁盘或其他介质中,以便在系统宕机、电源故障等异常情况下,能够快速恢复数据并提供服务。
举个例子来说,如果你在微信上写了一篇长篇大论的文章,但是没保存,突然电脑蓝屏或者微信崩溃了,那你的辛苦劳动就全都白费了。而如果你在写文章的时候,能够将它保存到云盘或者本地磁盘上,即使出现了问题,你也可以轻松地恢复数据。
🎉 持久化的原理
在计算机系统中,内存是一种易失性的存储介质,当电源被切断时,内存中保存的数据就会被清空。因此,在进行数据存储时,我们需要将数据写入到磁盘等非易失性介质中,以保证数据的持久性。
Redis是基于内存的,所以在服务器宕机、重启、断电等情况下,会造成内存数据的丢失。为了防止这种情况的发生,Redis提供了持久化机制,将内存中的数据异步地保存到磁盘,以保证数据的安全性和可靠性。
Redis的持久化机制有三种,分别是RDB持久化、AOF持久化和混合持久化。下面我们就来具体介绍它们的底层实现原理。
📝 RDB持久化
RDB持久化是 Redis 内置的一种持久化方式,它会在某一时间点对 Redis 的数据进行全量备份,将其存储到磁盘中。可以理解为一个快照,这个快照记录了 Redis 数据在某个时间点上的状态。
RDB持久化会生成多个数据文件,每个数据文件都代表了 Redis 在某一个时刻中的数据状态。Redis主进程只需要fork一个子进程,让子进程执行磁盘IO操作来进行RDB持久化。对外提供的读写服务,影响非常小。但是如果数据文件特别大,可能会导致对客户端提供的服务暂停数秒。
RDB持久化需要频繁地将 Redis 的数据写入到磁盘中,因此其对性能的影响比较大。此外,RDB持久化会丢失某一时间段的数据。一般来说,RDB数据快照文件,都是每隔5分钟,或者更长时间生成一次,这个时候就得接受一旦 Redis 进程宕机,那么会丢失最近5分钟的数据。
RDB持久化是Redis的默认持久化方式,它通过在特定的时间点或者达到一定的条件下,将Redis的内存数据快照写入到磁盘上的RDB文件中。RDB文件是一个二进制文件,包含了一个Redis的数据快照,它记录了Redis在某个时间点上的所有数据,可以用来恢复数据。
RDB持久化可以通过配置或者手动执行命令生成RDB文件。通过配置设置Redis在满足一定条件时自动保存数据,要满足的条件可以通过save命令设置。比如我们可以设置让Redis在满足“60秒内至少有1000个键被改动”这个条件时,自动保存一次数据集。手动执行命令可以进入Redis客户端,执行save或者bgsave命令,Redis会将当前内存中的数据快照到一个新的RDB文件里,并覆盖之前的RDB文件。
在RDB生成的过程中,Redis会调用fork()函数,创建一个子进程来完成快照的生成工作。这个子进程会先将当前内存中的所有键和值遍历一遍,然后将它们写入到一个临时文件中。当子进程完成对所有键值对的遍历和写入操作之后,它会用临时文件的内容覆盖原有的RDB文件,完成快照的生成和持久化。
RDB持久化的优点在于它生成的文件非常紧凑和稳定,是快速恢复大量数据的最佳选择。但是它也有一些缺点,例如需要频繁的将整个数据集写入磁盘,这会造成磁盘I/O的瓶颈,影响Redis的性能。同时,由于快照是在一个瞬间进行的,所以如果在生成快照的时候出现宕机,可能会造成数据的损失。
📝 AOF持久化
AOF持久化是另一种持久化方式,它会记录Redis中的所有写操作,以append-only模式写入日志文件。AOF日志文件以append-only模式写入,所以没有任何磁盘寻址的开销,写入性能很高,而且文件不容易破损。
AOF持久化可以更好地保护数据不丢失。一般AOF每隔1秒,通过一个后台线程执行一次fsync操作,最多丢失1秒钟的数据。当然,这种方式也会对性能产生一定的影响。
AOF持久化文件通常比RDB数据快照文件更大。支持的写QPS会比RDB支持的写QPS低,因为AOF一般会配置成每秒fsync一次日志文件,当然,每秒一次fsync,性能也还是很高的。
此外,在AOF日志文件过大时,可以进行后台重写操作,生成一份最小恢复数据的日志以供恢复,这种方式不会影响客户端的读写。
AOF持久化是Redis的另一种持久化方式,它记录了Redis所有执行的写命令,并将它们追加到AOF文件的末尾。这个文件是一个纯文本文件,包含了Redis服务器的所有写操作。
相比于RDB持久化,AOF持久化更加安全,因为它可以记录每一次写操作。在Redis重启的时候,可以通过重新执行AOF文件中的命令来恢复数据。
AOF持久化可以通过配置启用,并且可以设置Redis多久将数据fsync到磁盘一次,这里的fsync就是将内存中的数据刷到磁盘上,保证数据的可靠性。当我们写入许多数据时,Redis会将这些数据先写入到缓冲区中,然后再通过fsync命令将它们刷到磁盘上。
AOF文件里可能有太多没用的指令,所以Redis也提供了自动重写AOF文件的机制,它会定期根据内存的最新数据重新生成AOF文件。我们可以通过修改配置文件达到64M才会自动重写,也可以通过配置文件使AOF文件自上一次重写后文件大小增长了100%才会触发重写。手动执行命令bgrewriteaof重写AOF,Redis会fork出一个子进程去完成重写工作,不会对Redis正常命令处理有太大影响。
📝 混合持久化
仅仅使用RDB持久化或者仅仅使用AOF持久化都会有一些问题。使用RDB持久化,Redis在重启后需要将最近一次快照以及快照后的所有写操作进行重放,这会导致数据丢失。使用AOF持久化,Redis的性能会有所降低。
因此我们可以使用混合持久化的方式。开启两种持久化方式,用AOF来保证数据不丢失,作为数据恢复的第一选择;在AOF文件都丢失或损坏不可用的时候,还可以使用RDB来进行快速的数据恢复。
值得一提的是,Redis 4.0版本之后,还提供了增量RDB持久化(AOF重写的一部分实现方式)。这种方式会根据配置的时间间隔和数据变化情况自动进行RDB快照备份,相对于全量RDB持久化方式,可以大幅降低备份时间。
RDB持久化和AOF持久化各有优点和缺点,而混合持久化可以将两种方式的优点结合起来,达到最好的效果。在实际应用中,要根据自己的需求选择合适的持久化方式。
混合持久化是Redis在2.4版本中引入的新特性,它将RDB持久化和AOF持久化结合在一起,可以让Redis在重启时更快地恢复数据。
混合持久化需要通过配置将AOF和RDB持久化结合在一起,具体实现方式是在AOF文件中写入RDB文件的内容,并将新的数据操作追加到AOF文件的末尾。在Redis重启的时候,先加载RDB文件的内容,再根据AOF文件中的增量命令来进行恢复。这样可以大大提高恢复的速度。
在实现上,开启混合持久化后,AOF在重写时不再是单纯将内存数据转换为RESP命令写入AOF文件,而是将重写这一刻之前的内存做RDB快照处理,并且将RDB快照内容和增量的AOF修改内存数据的命令存在一起,都写入新的AOF文件。新的文件一开始不叫appendonly.aof,等到重写完新的AOF文件才会进行改名,覆盖原有的AOF文件,完成新旧两个AOF文件的替换。
因为混合持久化可以同时保证数据的完整性和可靠性,所以在实际生产环境中大部分情况下都会选择使用混合持久化。
总之,Redis的持久化机制是非常重要的,它可以保证Redis在遇到异常情况时的数据安全性和可靠性。不同的持久化方式有着各自的优缺点,我们需要根据实际情况来选择合适的持久化方式。同时,我们也需要注意持久化机制对Redis性能的影响,不要将频繁的持久化操作和高负载的业务操作同时进行,以免造成性能瓶颈。
📝 save与bgsave
Redis 具有高性能、高可用、高扩展性等优势,但是,它也存在着一些问题,比如会出现数据丢失、数据库备份不够方便等情况。那么,该怎么办呢?这时候,Redis 就推出了两种备份方案,分别是 save 和 bgsave。
save 和 bgsave 都是 Redis 的备份方案,它们的主要目的是用来保护数据库的数据安全性和完整性。但是,它们之间有很大的不同,下面就让我详细介绍一下 save 和 bgsave 的区别。
首先,我们来了解一下 save。save 是一种同步阻塞的备份方案,它会阻塞客户端命令和 Redis 的其他命令,直到备份完成。这样,就会对 Redis 的性能产生一定的影响。save 的备份过程中,所有的数据都会被保存到硬盘中,这样,即使 Redis 出现了异常情况,比如进程崩溃或服务器掉电等,数据也不会丢失。但是,由于 save 是同步阻塞的,所以在备份过程中,Redis 不能响应客户端的任何操作,这样对服务器压力和性能都会造成一定的影响。因此,save 通常只用于单机部署、数据量较小的情况下,对于大规模集群部署来说,它并不适用。
那么,接下来我们就来了解一下 bgsave。与 save 不同,bgsave 是一种异步非阻塞的备份方案,它会在后台进行备份操作,不会影响 Redis 的主要业务。bgsave 的备份过程中,Redis 会先创建一个子进程,该子进程会复制 Redis 的所有数据,并将其保存到硬盘中。当备份完成后,子进程会通知 Redis 主进程,告诉它备份已经完成。bgsave 的备份过程对 Redis 的性能影响很小,因为它是后台进行的,所以 Redis 仍然可以响应客户端的请求。但是,在备份过程中,由于需要复制 Redis 的所有数据,所以会消耗额外的内存空间,这也是 bgsave 的一个缺点。
那么,我们来举个例子来说明一下 save 和 bgsave 的区别吧。比如,有一个在线教育平台,它的后台需要存储很多的视频、音频和图片等多媒体数据。在这种情况下,如果使用 save 进行数据备份,那么在备份的过程中,所有的客户端请求都会被阻塞,这样会对用户体验造成一定的影响,而且在大规模集群部署的情况下,备份的速度也会很慢。但是,如果使用 bgsave 进行数据备份,那么在备份的过程中,用户的请求依然可以得到及时的响应,这样就不会影响用户的体验。当然,由于需要复制 Redis 的所有数据,所以在备份过程中会消耗额外的内存空间,但是相比于 save 来说,这种消耗是可以接受的。
综上所述,save 和 bgsave 都是 Redis 的备份方案,它们在实现方式和备份过程中的影响都不同。save 是同步阻塞的,会阻塞客户端命令和 Redis 的其他命令,在备份过程中对服务器压力和性能都会造成一定的影响。而 bgsave 是异步非阻塞的,可以在后台进行备份操作,不会影响 Redis 的主要业务,在备份过程中对服务器压力和性能的影响很小,但是会消耗额外的内存空间。在实际应用中,我们需要根据具体的业务需求选择合适的备份方案。
- 索新的领域,才能不断地向前推进。我坚信,只要我不断努力,我一定会达到自己的目标。