德化规划与建设局网站,新媒体平台,优化搜索关键词,成都市 网站建设博客地址#xff1a;blog.zysicyj.top Redis为什么要引入持久化机制 Redis引入持久化机制是为了解决内存数据库的数据安全性和可靠性问题。虽然内存数据库具有高速读写的优势#xff0c;但由于数据存储在内存中#xff0c;一旦服务器停止或崩溃#xff0c;所有数据将会丢失… 博客地址blog.zysicyj.top Redis为什么要引入持久化机制 Redis引入持久化机制是为了解决内存数据库的数据安全性和可靠性问题。虽然内存数据库具有高速读写的优势但由于数据存储在内存中一旦服务器停止或崩溃所有数据将会丢失。持久化机制的引入旨在将内存中的数据持久化到磁盘上从而在服务器重启后能够恢复数据提供更好的数据保护和可靠性。 以下是持久化机制的几个主要原因 「1. 数据安全和可靠性」 通过将数据持久化到磁盘上即使在服务器崩溃或异常停止的情况下也可以保证数据不会丢失。持久化机制可以防止重要的数据在突发情况下遭受损失。 「2. 数据恢复」 持久化机制允许在服务器重启后将数据重新加载到内存中从而实现数据的恢复。这对于业务的连续性和可用性非常重要。 「3. 数据灾难恢复」 持久化机制对于灾难恢复也很有帮助。在不幸发生硬件故障、电力中断等情况下持久化机制可以帮助恢复数据。 「4. 数据迁移」 持久化机制也有助于将数据从一个服务器迁移到另一个服务器。你可以通过备份持久化文件并在另一台服务器上进行恢复来完成数据迁移。 虽然持久化机制带来了磁盘IO和性能开销但它为Redis提供了更强大的数据保护能力。根据应用的需求可以根据数据的重要性和数据丢失的容忍度来选择适当的持久化方式或者结合两种方式以提供更高的数据保护级别。 Redis提供了哪些持久化机制 Redis提供了两种主要的持久化机制分别是RDB快照Snapshotting和AOF日志Append-Only File。这两种机制可以根据不同的需求和场景来选择使用。 「1. RDB快照Snapshotting」 RDB快照是一种全量持久化方式它会周期性地将内存中的数据以二进制格式保存到磁盘上的RDB文件。RDB文件是一个经过压缩的二进制文件包含了数据库在某个时间点的数据快照。RDB快照有助于实现紧凑的数据存储适合用于备份和恢复。 「优点」 RDB快照在恢复大数据集时速度较快因为它是全量的数据快照。 由于RDB文件是压缩的二进制文件它在磁盘上的存储空间相对较小。 适用于数据备份和灾难恢复。 「缺点」 RDB快照是周期性的全量持久化可能导致某个时间点之后的数据丢失。 在保存快照时Redis服务器会阻塞可能对系统性能造成影响。 「2. AOF日志Append-Only File」 AOF日志是一种追加式持久化方式它记录了每个写操作命令以追加的方式将命令写入AOF文件。通过重新执行AOF文件中的命令可以重建出数据在内存中的状态。AOF日志提供了更精确的持久化适用于需要更高数据安全性和实时性的场景。 「优点」 AOF日志可以实现更精确的数据持久化每个写操作都会被记录。 在AOF文件中数据可以更好地恢复因为它保存了所有的写操作历史。 AOF日志适用于需要实时恢复数据的场景如秒级数据恢复要求。 「缺点」 AOF日志相对于RDB快照来说可能会占用更多的磁盘空间因为它是记录每个写操作的文本文件。 AOF日志在恢复大数据集时可能会比RDB快照慢因为需要逐条执行写操作。 根据不同的需求可以选择RDB快照、AOF日志或两者结合使用。你可以根据数据的重要性、恢复速度要求以及磁盘空间限制来选择合适的持久化方式。有时候也可以通过同时使用两种方式来提供更高的数据保护级别。 AOF日志是如何实现的 首先大家要知道AOF是写后日志“写后”的意思是Redis先执行命令把数据写入内存然后才记录日志如下图所示 AOF 为什么要先执行命令再记日志呢 AOFAppend-Only File持久化机制中为什么要先执行命令再记录日志而不是相反这涉及到数据的一致性和持久性。 AOF的设计目标之一是保证数据的持久性即在服务器重启后能够恢复出与重启前一致的数据状态。为了实现这个目标AOF的操作顺序非常重要。 「先执行命令再记录日志的原因」 「数据一致性」 如果先记录日志再执行命令假设记录日志成功而执行命令失败例如服务器崩溃那么日志中记录的操作实际上没有被应用会导致数据在重启后与预期不一致。 「可恢复性」 先执行命令再记录日志可以保证在服务器重启后即使在崩溃前未能将操作记录到日志中也可以通过重新执行AOF日志中的命令将数据恢复到正确的状态。 「避免日志丢失」 如果先记录日志再执行命令如果在记录日志之前发生了服务器崩溃会导致操作丢失而这些操作可能已经影响了数据的一致性。 当然这里面还有一个非常重要的原因「它是在命令执行后才记录日志所以不会阻塞当前的写操作」。 因此为了确保数据的持久性和一致性Redis选择了先执行命令再记录日志的方式。这样可以保证只有在操作真正成功执行后才会将操作记录到AOF日志中从而在服务器重启后能够准确地重放这些操作保持数据的正确性。 AOF日志里面记录了什么内容呢 AOFAppend-Only File日志记录了每个写操作命令以追加的方式将命令写入AOF文件。这些写操作命令被以一种协议格式通常是RESP协议写入AOF文件以文本形式保存。下面是AOF日志中记录的内容示例 假设执行了以下操作 SET key1 value1INCR key2LPUSH list1 item1 对应的AOF日志内容可能是 *3\r\n$3\r\nSET\r\n$4\r\nkey1\r\n$6\r\nvalue1\r\n*2\r\n$4\r\nINCR\r\n$4\r\nkey2\r\n*3\r\n$5\r\nLPUSH\r\n$5\r\nlist1\r\n$5\r\nitem1\r\n 在这个示例中每个写操作都以RESP协议格式记录在AOF文件中以一系列字节数组来表示命令和参数。每个写操作的记录由多行组成以\r\n分隔。 *3表示命令参数的个数为3。 $3\r\nSET\r\n表示第一个参数为长度为3的字符串 SET。 $4\r\nkey1\r\n表示第二个参数为长度为4的字符串 key1。 $6\r\nvalue1\r\n表示第三个参数为长度为6的字符串 value1。 这样的记录方式允许在AOF文件中按照操作的顺序逐条重放写操作命令从而实现数据在服务器重启后的恢复。由于AOF记录的是写操作命令本身所以在执行AOF文件中的命令时可以完全还原数据的状态。 AOF日志潜在的问题 AOFAppend-Only File写日志是Redis的持久化机制之一它记录了每个写操作命令以追加的方式将命令写入AOF文件。尽管AOF具有许多优点但也存在一些风险和潜在的问题需要注意和管理 「1. 磁盘IO开销」 AOF日志以追加写入方式工作每次写入操作都会直接追加到AOF文件末尾。这意味着频繁的写入操作可能会导致磁盘IO开销增加可能会影响系统的性能和响应时间。 「2. 磁盘空间占用」 AOF日志记录的是每个写操作命令本身相比于RDB快照AOF文件可能会更大。如果写入操作频繁AOF文件可能会不断增大占用过多的磁盘空间。 「3. 数据一致性」 尽管AOF的先执行命令再记录日志的机制保证了数据一致性但如果在记录日志前发生服务器崩溃尚未记录的操作可能会丢失可能导致数据一致性问题。 「4. AOF文件损坏」 由于AOF文件是以文本格式记录的命令如果AOF文件在写入或存储过程中受到损坏可能导致数据恢复时出现问题甚至无法正确恢复数据。 「5. AOF重写耗时」 AOF重写是为了减小AOF文件的大小但它是一个耗时的操作可能会对系统性能产生影响尤其是在大数据集的情况下。 「6. AOF重写可能引发的问题」 AOF重写过程中可能会因为各种原因导致数据丢失例如中断的重写过程、文件系统问题等。在执行AOF重写时需要谨慎对待确保数据的完整性。 「7. AOF文件合并」 在一些场景下可能需要将多个AOF文件合并成一个这样的操作需要小心处理以避免数据丢失或错误。 「8. 硬件故障」 虽然AOF可以提供持久性保证但硬件故障例如磁盘故障可能会导致AOF文件丢失或损坏需要适当的备份和恢复策略。 为了减轻AOF写日志带来的风险可以采取一些措施如选择适当的AOF同步策略、定期备份AOF文件、监控AOF文件的大小和状态、定期执行AOF重写、备份数据等。这些策略可以帮助减少潜在的问题并提高系统的可靠性。 AOF日志三种写回策略 AOFAppend-Only File持久化机制在Redis中有三种不同的写回sync策略用于控制何时将AOF缓冲区中的写入操作刷新到磁盘上的AOF文件。这些策略决定了AOF日志的同步频率影响了数据的持久性和性能。以下是这三种写回策略 「1. always始终同步」 在这个策略下每次执行写入操作之后Redis都会立即将写入操作刷新到磁盘确保写入操作已经持久化。虽然这种方式能够提供最高的数据保证但也是性能开销最大的一种方式因为每次写入操作都会引起磁盘IO。 「优点」 最高的数据保证即使系统崩溃也只会丢失上一个写入操作。 「缺点」 性能开销较大频繁的磁盘IO可能影响系统的性能和响应时间。 「2. everysec每秒同步」 在这个策略下Redis会每秒一次将AOF缓冲区中的写入操作批量刷新到磁盘上的AOF文件。这样可以在一定程度上平衡数据保证和性能。 「优点」 较高的数据保证每秒一次的同步保证了不会丢失过多的写入操作。 性能开销相对较低因为是每秒一次的批量刷新。 「缺点」 在一秒内的操作可能会丢失。 「3. no不同步」 这个策略下Redis不会主动将AOF缓冲区中的写入操作刷新到磁盘而是由操作系统来决定何时将数据写入磁盘。这是性能开销最小的方式但数据持久性相对较低。 「优点」 最小的性能开销几乎不会影响系统的响应时间。 最高的性能表现写入操作不会导致频繁的磁盘IO。 「缺点」 数据持久性较低如果系统崩溃可能会丢失多个写入操作。 选择合适的AOF写回策略取决于数据的重要性和性能需求。如果数据安全性最为重要可以选择always策略。如果在数据一致性和性能之间需要平衡可以选择everysec策略。如果对性能要求较高而可以接受一定程度的数据丢失可以选择no策略。根据实际情况可以根据需求来配置AOF的写回策略。 这里呢给大家总结一下各种配置的优缺点 日志文件太大了怎么办 AOFAppend-Only File重写是为了减小AOF文件的大小避免AOF文件不断增大导致的磁盘空间占用问题。AOF重写是一种以全量的方式生成新的AOF文件其中记录的是一个数据集的写入操作这个数据集的大小通常比原始AOF文件小很多。 AOF重写的工作原理如下 「触发重写」 AOF重写可以手动触发也可以根据配置自动触发。当满足一定条件例如AOF文件大小超过指定百分比或最小大小时Redis会启动AOF重写过程。 「后台进程启动」 当AOF重写触发时Redis会启动一个子进程这个子进程会负责执行AOF重写操作。 「创建数据集快照」 在子进程中Redis会创建一个数据集的内存快照即内存中数据在某个时间点的快照。 「遍历数据集」 子进程开始遍历数据集中的键并将写操作转换成命令序列。 「生成新AOF文件」 子进程会将遍历期间生成的命令序列追加到新的AOF文件中这个新文件是紧凑的只包含了数据集在某个时间点的写入操作。 「替换原AOF文件」 当新的AOF文件生成完成后子进程会将原始的AOF文件替换为新的AOF文件。这一步通常很快因为新的AOF文件相对较小。 「主线程继续服务」 在AOF重写过程中主线程仍然可以继续处理客户端请求响应读取操作等不会被阻塞。 AOF重写的优势在于它可以生成一个更小、更紧凑的AOF文件避免了不断增大的AOF文件所带来的磁盘空间和读写开销。此外新的AOF文件只包含了写入操作没有之前的读操作因此它在恢复数据时不需要考虑之前的读操作。 AOF重写可以通过多种方式触发 手动触发可以使用 BGREWRITEAOF命令手动触发AOF重写。 自动触发可以通过设置 auto-aof-rewrite-percentage和 auto-aof-rewrite-min-size来自动触发AOF重写。当AOF文件大小达到指定的百分比或最小大小时Redis会自动启动AOF重写。 需要注意的是AOF重写是一个资源密集型操作可能会影响系统的性能特别是在大数据集的情况下。因此在进行AOF重写时应该考虑其对系统性能的影响并确保系统具备足够的资源来执行重写操作。 下面举例说明一下 这里大家能看到经过优化后AOF日志文件会缩小很多但是要把整个数据库的最新数据的操作日志都写回磁盘仍然是一个非常耗时的过程。这时我们就要继续关注另一个问题了。 重写会不会阻塞主线程 AOF重写不会阻塞Redis的主线程。Redis的AOF重写是作为一个后台进程子进程来执行的不会影响主要的服务线程。 AOF重写过程中Redis会创建一个子进程来遍历数据集将写操作转换为命令序列并生成新的AOF文件。主线程仍然可以继续处理客户端请求响应读取操作等。 这种设计使得Redis能够在不中断服务的情况下执行AOF重写从而减少对系统的影响。但需要注意的是虽然AOF重写不会阻塞主线程但它仍然是一个资源密集型操作可能会占用较多的CPU和内存资源因此在进行AOF重写时需要考虑系统的资源情况避免影响其他业务操作。 RDB快照是如何实现的 RDBRedis DataBase是Redis的一种持久化机制用于将数据从内存中保存到磁盘上以便在服务器重启时恢复数据。RDB通过创建一个快照Snapshot来保存数据库在某个时间点的数据状态然后将这个快照保存到磁盘上的一个二进制文件中。 「RDB的实现过程」 「创建快照」 当RDB持久化被触发时可以手动触发或根据配置自动触发Redis会生成一个数据集的内存快照。这个快照包含了数据库在某个时间点的所有键值对以及相关的数据结构信息。 「快照数据序列化」 在创建快照后Redis会将快照中的数据进行序列化将键、值、过期时间等信息按照一定的格式编码成二进制数据。 「保存到文件」 将序列化后的数据保存到磁盘上的RDB文件中。RDB文件的扩展名通常为.rdb。 「持久化完成」 一旦RDB文件保存完成持久化过程结束。这个RDB文件包含了数据库在快照时间点的完整数据状态。 「RDB的优缺点」 「优点」 「紧凑的数据格式」 RDB文件是一个二进制文件采用了紧凑的编码格式因此在磁盘上占用的空间相对较小。 「快速恢复」 在恢复数据时通过加载RDB文件可以快速地将数据恢复到指定时间点的状态。 「适用于备份和恢复」 RDB文件适用于进行数据备份、迁移和灾难恢复可以方便地复制到其他服务器上。 「缺点」 「数据丢失」 由于RDB是周期性的全量持久化可能会导致某个时间点之后的数据丢失。 「IO开销」 RDB持久化时需要将整个数据集写入磁盘可能在大数据集上引起IO开销影响性能。 「耗时」 在生成RDB快照的过程中如果数据集很大可能会占用较多的CPU资源导致短时间内的性能下降。 总的来说RDB持久化适用于需要紧凑的备份和数据迁移以及在服务器重启时需要快速恢复数据的场景。但需要注意的是RDB的全量持久化可能会导致某些数据的丢失因此在选择持久化方式时需要权衡数据的重要性和性能需求。 给哪些内存数据做快照 在RDB持久化中Redis会对内存中的各种数据进行快照将数据保存到RDB文件中。这些内存数据包括 「字符串类型数据」 包括使用SET命令设置的字符串键值对。 「哈希表Hash」 包括使用HSET、HMSET等命令设置的哈希键值对。 「列表List」 包括使用LPUSH、RPUSH等命令添加的列表元素。 「集合Set」 包括使用SADD等命令添加的集合元素。 「有序集合Sorted Set」 包括使用ZADD等命令添加的有序集合元素。 「Bitmaps、HyperLogLogs、Streams」 包括这些特殊数据类型的内容。 「过期时间」 快照会记录每个键的过期时间以便在恢复数据时进行过期判断。 「数据库配置」 包括数据库的配置信息如数据库编号、键空间的选项等。 「服务器信息」 包括服务器的信息如版本号、运行模式等。 「客户端连接信息」 包括客户端连接的信息。 需要注意的是RDB持久化是一种全量持久化机制它会在某个时间点生成一个数据库的快照将所有内存中的数据保存到RDB文件中。这种方式有一些优点如紧凑的数据格式和快速恢复但也有缺点如可能造成数据丢失和IO开销。在选择使用RDB持久化时需要权衡这些优缺点根据业务需求来确定是否适合使用。 哪些命令能生成RDB文件 RDB文件是通过执行持久化操作来生成的而不是通过特定的命令来生成。在Redis中可以手动触发RDB持久化操作也可以根据配置自动触发。以下是生成RDB文件的方式 「手动触发」 使用SAVE命令可以手动触发RDB持久化操作该命令会「阻塞服务器」的主线程直到RDB文件生成完成为止。这个命令适合用于测试或紧急情况下的数据备份。 示例 SAVE 「后台触发」 使用BGSAVE命令可以在后台触发RDB持久化操作这个命令会派生一个子进程来执行RDB持久化「不会阻塞服务器」的主线程。这是比较常用的生成RDB文件的方式。 示例 BGSAVE 「自动触发」 可以通过配置文件中的参数来自动触发RDB持久化操作。在配置文件redis.conf中可以设置save参数用于指定在何时执行RDB持久化操作例如 save 900 1save 300 10save 60 10000 这表示当900秒内至少发生1次写操作、300秒内至少发生10次写操作、60秒内至少发生10000次写操作时自动触发BGSAVE命令。 无论是手动触发还是后台触发RDB持久化操作都会生成一个RDB文件其中包含了内存中的数据快照。需要注意的是RDB持久化是一个资源密集型操作可能会影响服务器的性能特别是在数据集较大的情况下。因此在选择何时执行RDB持久化时需要根据业务需求和性能要求做出权衡。 快照时数据能修改吗 这里大家可能会想到bgsave命令避免阻塞。这里大家可能会有误区「避免阻塞和正常处理读写请求并不是一回事」。此时主线程确实没有阻塞可以正常接收请求但是为了保证快照完整性它只能处理读操作因为不能修改正在执行快照的数据。 那么Redis是如何解决这个问题的呢 实际上Redis 6.0 版本引入了「写时复制Copy-On-WriteCOW技术」来保证在执行快照RDB时数据是可修改的。这个特性被称为 RDB快照时复制RDB Snapshotting。 在 Redis 6.0 中当进行 RDB 快照持久化时Redis 会执行以下步骤来确保数据可修改 Redis 创建一个子进程。 在子进程中将内存中的数据进行写时复制创建出一个副本而不会影响主进程的数据。 子进程将副本数据写入 RDB 文件这个过程是在子进程的上下文中执行的不会影响主进程。 这个操作在实际执行过程中是子进程复制了主线程的页表所以通过页表映射能读到主线程的原始数据而当有新数据写入或数据修改时主线程会把新数据或修改后的数据写到一个新的物理内存地址上并修改主线程自己的页表映射。所以子进程读到的类似于原始数据的一个副本而主线程也可以正常进行修改。 因此RDB 快照时主进程仍然可以继续处理写操作而子进程则负责将数据写入 RDB 文件。这样写时复制技术确保了在生成 RDB 快照期间数据是可修改的同时保持了数据的一致性。 需要注意的是这种特性仅适用于 Redis 6.0 及以上版本并且在 RDB 快照时起作用。在生成 AOF 文件时Redis 仍然会阻塞主线程以确保数据一致性。 可以每秒做一次快照吗 虽然理论上可以每秒钟做一次快照RDB持久化但实际上这样做可能会对Redis服务器的性能产生显著的影响特别是在负载较重的情况下。 每秒钟生成快照会引起以下一些问题 「性能开销」 快照操作需要遍历内存中的所有数据并将数据序列化到磁盘中。频繁的快照操作会占用大量的CPU和内存资源影响服务器的性能导致响应时间变长。 「IO压力」 每秒钟生成的快照会导致频繁的磁盘写入增加了磁盘IO的负担可能影响其他应用程序和操作系统的正常运行。 「数据丢失」 每秒钟生成的快照可能会导致数据丢失因为生成快照的操作需要一定的时间如果在两次快照之间发生了写操作那么这段时间内的数据会丢失。 通常情况下每秒钟生成快照并「不是一个推荐的做法」。更合理的做法是根据业务需求和系统资源来选择合适的持久化频率。如果数据的一致性要求很高可以考虑使用AOF持久化机制它可以在不同程度上提供数据的保护和持久性而且可以通过设置不同的写回策略来平衡性能和数据保护。如果数据的一致性要求相对较低可以选择适当的RDB持久化频率避免频繁的IO和性能开销。 为什么推荐AOF和RDB混合使用 推荐在Redis中同时使用AOFAppend-Only File持久化和RDBRedis DataBase持久化的原因是这两种持久化机制可以相互补充提供更好的数据保护、恢复能力和性能优化。 以下是推荐同时使用AOF和快照的主要原因 「数据恢复能力」 AOF持久化记录了所有写操作的日志这使得在发生意外情况时如服务器崩溃可以精确地恢复数据到崩溃前的状态。而RDB持久化通过全量快照提供了快速的数据恢复能力。结合使用两者可以在AOF日志的基础上通过加载最近的RDB快照来加速恢复。 「数据安全性」 AOF持久化记录了每个写操作可以确保每个写操作都被持久化到日志中。RDB持久化则提供了一个点对点的数据备份。同时使用这两种持久化机制可以提供更高的数据安全性。 「性能优化」 AOF持久化对于读操作的性能影响较小因为读操作不涉及AOF文件的写入。而RDB持久化对于快速的全量数据恢复很有帮助。通过结合使用AOF和RDB可以在一定程度上平衡数据保护和性能要求。 「多层次的备份」 使用AOF和RDB您可以获得多层次的数据备份。AOF日志可以提供精确的操作日志RDB快照可以提供全量备份。这样即使其中一个持久化机制出现问题另一个仍然可以提供数据保护。 综上所述使用AOF和RDB两种持久化机制的组合能够提供更全面的数据保护、灾难恢复和性能优化。在配置Redis持久化时根据业务需求和性能要求结合使用这两种机制可以实现更好的数据管理和保护。 如何配置呢 在 Redis 中同时使用 AOF 持久化和 RDB 持久化的配置是很常见的这样可以兼顾数据的持久性和恢复性能。以下是一个将 AOF 持久化和 RDB 持久化混合使用的示例配置 打开 Redis 配置文件通常是 redis.conf。 启用 AOF 持久化 找到以下行并确保其被设置为以下值以启用 AOF 持久化 appendonly yes 设置 AOF 重写策略可选 可以设置 AOF 重写的触发条件以便控制 AOF 文件的大小和写入频率。例如 auto-aof-rewrite-percentage 100auto-aof-rewrite-min-size 64mb 启用 RDB 持久化 默认情况下Redis 会使用 RDB 持久化但要确保以下行没有被注释掉 save 900 1save 300 10save 60 10000 设置 RDB 快照文件名可选 如果希望为 RDB 快照指定特定的文件名可以添加以下行 dbfilename dump.rdb 这会将 RDB 快照文件命名为 dump.rdb。 设置 RDB 快照保存路径可选 如果希望将 RDB 快照保存到特定的路径可以添加以下行 dir /path/to/rdb/directory 这会将 RDB 快照保存到指定的目录。 重启 Redis 服务器 在对配置文件进行更改后需要重新启动 Redis 服务器以使配置生效。 使用以上配置Redis 将同时使用 AOF 持久化和 RDB 持久化提供了多层次的数据保护和恢复机制。AOF 持久化记录写操作提供操作日志用于数据恢复。RDB 持久化提供了全量备份用于快速恢复整个数据集。混合使用这两种机制可以充分利用它们各自的优点提供更全面的数据持久性和保护。 关于AOF和RDB的选择三点建议 数据不能丢失时内存快照和 AOF 的混合使用是一个很好的选择 如果允许分钟级别的数据丢失可以只使用 RDB 如果只用 AOF优先使用 everysec 的配置选项因为它在可靠性和性能之间取了一个平衡。 本文由 mdnice 多平台发布