前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Redis持久化机制

Redis持久化机制

作者头像
栗筝i
发布2023-10-16 14:38:30
3190
发布2023-10-16 14:38:30
举报
文章被收录于专栏:迁移内容

Redis 作为一种内存数据库,其高速度的读写性能吸引了大量的用户。然而,作为数据库,数据的安全性也是我们需要考虑的重要因素。如果 Redis 仅仅将数据存储在内存中,那么一旦发生断电或者系统崩溃等情况,数据将会丢失,这对于任何一个系统来说都是无法接受的。因此,Redis 提供了持久化机制来保证数据的安全性。在这篇博客中,我们将详细介绍 Redis 的两种持久化机制:RDB 和 AOF,以及它们的工作原理、使用场景和优缺点。

1、Redis持久化机制
1.1、Redis持久化机制简介

Redis 是个基于内存的数据库。那服务一旦宕机,内存中数据必将全部丢失。所以丢失数据的恢复对于 Redis 是十分重要的,我们首先想到是可以从数据库中恢复,但是在由 Redis 宕机时(说明相关工作正在运行)且数据量很大情况下,从数据库恢复的话,会为数据库带来巨大的压力,进而导致程序相应缓慢。因此实现数据的持久化,避免从后端数据库中恢复数据,对于Redis 是十分必要的。

此外,Redis 可以通过创建快照来获得存储在内存里面的数据。创建快照之后,可以对快照进行备份,可以将快照复制到其他服务器从而创建具有相同数据的服务器副本(Redis 主从结构,主要用来提高 Redis 性能),还可以将快照留在原地以便重启服务器的时候使用,其中 Redis 最常用的快照持久化机制分为两种,即 RDB 与 AOF。

1.2、混合使用 RDB 和 AOF

在 Redis 中,可以同时开启 RDB 和 AOF 持久化,这种方式被称为混合持久化。混合持久化结合了 RDB 和 AOF 的优点,既可以提供高效的数据备份(RDB),又可以提供高度的数据安全性(AOF)。

当混合持久化开启时,Redis 会优先使用 AOF 文件来恢复数据,因为 AOF 文件的数据通常比 RDB 文件的数据更完整。如果 AOF 文件不存在,那么 Redis 会使用 RDB 文件来恢复数据。

混合持久化的配置方法如下:

  1. 在 redis.conf 配置文件中,将 appendonly 参数设置为 yes,开启 AOF 持久化。
  2. save 参数设置为你需要的值,开启 RDB 持久化。例如,你可以设置为 save 900 1,这样当 900 秒内有至少 1 个 key 发生变化时,Redis 就会创建一个 RDB 文件。
  3. (可选)如果你希望在 Redis 重启时,能够尽可能快地加载数据,你可以将 aof-use-rdb-preamble 参数设置为 yes。这样,AOF 文件的开头会包含一个 RDB 数据段,Redis 可以先快速地加载这个数据段,然后再加载 AOF 文件的剩余部分。

需要注意的是,虽然混合持久化可以提供更高的数据安全性,但同时开启 RDB 和 AOF 持久化会消耗更多的磁盘空间和 I/O 资源。因此,你应该根据你的实际需求和资源情况,来决定是否使用混合持久化。


2、RDB(Redis DataBase)
2.1、RDB持久化简介

RDB 持久化是通过创建数据集的时间点快照来实现的。在指定的时间间隔内,如果满足指定的写操作数量,Redis 就会在后台启动一个新的子进程,将所有数据写入到一个临时文件中,当临时文件写入完成后,再替换原来的文件,达到数据持久化的目的。RDB 是默认的持久化方式,它的优点是可以最大化 Redis 的性能,且 RDB 文件非常适合用于数据备份,或者将数据迁移到另一个 Redis 实例。但是,如果你需要更高的数据安全性,比如不能丢失任何修改操作,那么 AOF 持久化可能更适合你。

2.2、RDB持久化过程

Redis 数据库的 RDB 持久化方式是一种快照式的数据备份方式。在指定的时间间隔内,如果满足指定的写操作数量,Redis 就会在后台启动一个新的子进程,将当前所有数据写入到一个临时文件中,当临时文件写入完成后,再替换原来的 RDB 文件,达到数据持久化的目的。

  1. 判断是否需要执行 RDB 持久化:Redis 会根据配置文件中的规则(例如,每过多少秒,如果有多少次写操作,就进行一次 RDB 持久化),以及是否收到了 SAVEBGSAVE 命令,来决定是否需要执行 RDB 持久化。
  2. 创建子进程:如果需要执行 RDB 持久化,Redis 会创建一个子进程来进行持久化操作。这样做的好处是,父进程可以继续处理客户端的请求,而不需要等待持久化操作完成。
  3. 写入临时文件:子进程会将当前所有数据写入到一个临时文件中。这个临时文件是一个二进制文件,其中包含了 Redis 在持久化开始时的所有数据。
  4. 替换原来的 RDB 文件:当临时文件写入完成后,子进程会用这个临时文件替换原来的 RDB 文件。这样做的好处是,即使在替换过程中发生错误(例如,磁盘空间不足),原来的 RDB 文件也不会被破坏。
  5. 通知父进程:最后,子进程会通知父进程它已经完成了持久化操作。父进程在接到这个通知后,会更新自己的状态,例如,它会记录下最后一次成功执行 RDB 持久化的时间。

需要注意的是,这个过程中的很多细节,例如如何创建子进程,如何写入临时文件,如何替换 RDB 文件,都是由操作系统来完成的,Redis 只需要调用相应的系统调用即可。

2.3、RDB持久化命令

Redis 中与 RDB 持久化相关的命令主要有以下两个:

  1. SAVE:该命令会立即执行一个 RDB 持久化操作,保存当前数据库的所有数据到磁盘。需要注意的是,SAVE 命令会阻塞 Redis 服务器,直到 RDB 文件创建完毕为止,在这期间,Redis 无法处理任何其他命令。
  2. BGSAVE:该命令会在后台异步执行一个 RDB 持久化操作。BGSAVE 命令会创建一个子进程来进行持久化操作,父进程则继续处理其他命令。这种方式的优点是非阻塞,但需要注意的是,如果在执行 BGSAVE 的过程中,如果再次触发 BGSAVESAVE 命令,或者尝试执行 BGREWRITEAOF 命令,Redis 会拒绝,因为 Redis 防止同时存在多个子进程进行持久化操作。

在实际使用中,通常推荐使用 BGSAVE 命令,因为它不会阻塞 Redis 服务器。但是,如果你需要立即创建一个数据库的快照,例如用于备份数据,那么可以使用 SAVE 命令。

2.4、RDB参数设置

在 Redis 的配置文件中,有一些参数是和 RDB 持久化相关的,主要包括以下几个:

  1. save:这个参数用于设置自动触发 RDB 持久化的条件。它的值是一个或多个 <seconds> <changes> 对,表示在过去 <seconds> 秒内,如果有 <changes> 次写操作,就自动执行一次 RDB 持久化。例如,save 900 1 表示在过去 900 秒内,如果有 1 次写操作,就自动执行一次 RDB 持久化。
  2. stop-writes-on-bgsave-error:这个参数用于设置当 RDB 持久化发生错误时,是否停止写操作。如果它的值为 yes,那么当 RDB 持久化发生错误时,Redis 会停止所有写操作。
  3. rdbcompression:这个参数用于设置是否对 RDB 文件进行压缩。如果它的值为 yes,那么 Redis 会使用 LZF 算法对 RDB 文件进行压缩,以减少 RDB 文件的大小。
  4. rdbchecksum:这个参数用于设置是否对 RDB 文件进行校验和检查。如果它的值为 yes,那么 Redis 会在 RDB 文件的末尾添加一个 CRC64 校验和,用于在载入 RDB 文件时检查数据的完整性。
  5. dbfilename:这个参数用于设置 RDB 文件的文件名。
  6. dir:这个参数用于设置 RDB 文件的保存目录。

以上就是 Redis 中和 RDB 持久化相关的主要参数。你可以根据你的实际需求,调整这些参数的值,以达到最佳的持久化效果。

2.5、RDB源码简述

对于 Redis 的 RDB 持久化的源码,主要涉及到两个函数:rdbSaverdbSaveBackground

rdbSave 函数是执行 RDB 持久化的主要函数,它会将当前数据库的数据保存到指定的 RDB 文件中。这个函数会阻塞 Redis 服务器,直到 RDB 文件创建完毕为止。

rdbSaveBackground 函数则是在后台执行 RDB 持久化的函数,它会创建一个子进程来执行 rdbSave 函数,这样父进程就可以继续处理客户端的请求。

以下是这两个函数的简化版的源码:

代码语言:javascript
复制
/* Save the DB on disk. Return REDIS_ERR on error, REDIS_OK on success */
int rdbSave(char *filename) {
    /* ...省略创建和写入 RDB 文件的代码... */
    return REDIS_OK;
}

/* Save the DB in background. Return REDIS_ERR on error, REDIS_OK on success */
int rdbSaveBackground(char *filename) {
    pid_t childpid;
    long long start;

    /* ...省略一些错误处理和日志记录的代码... */

    /* Create a child process that will actually perform the dump. */
    childpid = fork();
    if (childpid == 0) {
        /* Child */
        closeListeningSockets(0);
        redisSetProcTitle("redis-rdb-bgsave");
        if (rdbSave(filename) == REDIS_OK) {
            exitFromChild(0);
        } else {
            exitFromChild(1);
        }
    } else {
        /* Parent */
        /* ...省略一些错误处理和日志记录的代码... */
        return REDIS_OK;
    }
    return REDIS_ERR;
}

以上就是 Redis RDB 持久化的主要源码。需要注意的是,这里省略了很多细节,例如如何创建 RDB 文件,如何将数据写入到 RDB 文件,以及如何处理各种可能的错误等。如果你想深入了解这部分的源码,可以直接查看 Redis 的源码。

2.6、RDB优缺点

RDB 持久化的优点:

  1. RDB 是一个非常紧凑的文件,代表了 Redis 在某个时间点的数据快照。
  2. RDB 可以最大化 Redis 的性能,父进程在保存 RDB 文件时唯一要做的就是 fork 一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无需执行任何磁盘 I/O 操作。
  3. RDB 非常适用于备份场景,你可以在夜间进行备份,因为 RDB 文件只表示某个时间点的数据快照,所以它对于灾难恢复非常有用。

RDB 持久化的缺点:

  1. 如果你需要尽可能避免在 Redis 发生故障时丢失数据,那么 RDB 不是一个好的选择。因为 RDB 文件是定期产生的,如果 Redis 发生故障,那么你将丢失最后一次快照以来的所有数据。
  2. RDB 需要 fork 子进程来进行持久化,如果数据集很大时,fork 可能会非常耗时,造成服务器阻塞。
2.7、RDB注意事项

RDB注意事项(特征):

  1. RDB 持久化是通过创建数据集的时间点快照来实现的,因此如果在两次快照之间 Redis 发生故障,则这段时间的数据将会丢失。
  2. RDB 文件是在 Redis 内存数据集的一个时间点上生成的,所以它对于数据恢复非常有用,特别是在数据意外丢失的情况下。
  3. RDB 在保存和加载时非常快,因为它是直接由磁盘进行单一的 I/O 操作,不像 AOF 持久化方式需要执行多个命令。
  4. RDB 在备份(master 实例进行 bgsave,然后将 RDB 文件复制到其他地方)或者数据集大的时候,数据恢复速度比 AOF 快。

3、AOF(Append Only File)
3.1、AOF简介

AOF 持久化记录了服务器接收到的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。AOF 文件的更新操作是追加模式,因此对于写入命令的丢失问题,AOF 文件在写入时就已经将数据保存到了磁盘,大大降低了丢失数据的可能性。并且,Redis 还可以对 AOF 文件进行后台重写,使得 AOF 文件的体积保持在最小。但是,相比于 RDB,AOF 文件通常更大,且恢复速度更慢。

3.2、AOFB持久化过程

Redis 的 AOF(Append Only File)持久化过程主要包括以下几个步骤:

  1. 记录写命令:当 Redis 执行一个会改变数据的命令(例如 SETDEL 等)时,它会将这个命令追加到 AOF 缓冲区。
  2. 写入磁盘:Redis 会根据配置(appendfsync 参数)来决定何时将 AOF 缓冲区的内容写入到磁盘。有三种可能的配置:每次有写命令就立即写入磁盘(always);每秒写入一次(everysec);完全由操作系统来决定何时写入(no)。
  3. 文件重写:随着时间的推移,AOF 文件可能会越来越大。Redis 提供了 AOF 重写功能,可以创建一个新的 AOF 文件,这个新的 AOF 文件和原来的 AOF 文件可以达到相同的效果,但体积更小。AOF 重写可以手动触发,也可以根据配置(auto-aof-rewrite-percentageauto-aof-rewrite-min-size 参数)自动触发。
  4. 恢复数据:当 Redis 重启时,它会读取 AOF 文件,然后重新执行 AOF 文件中的所有命令,以此来恢复数据。

需要注意的是,虽然 AOF 持久化在默认配置下可以提供更好的数据安全性(只会丢失一秒的数据),但它需要更多的磁盘空间,且可能会降低 Redis 的写性能。

3.3、AOFB持久化重写

AOF 持久化的重写机制主要是为了减小 AOF 文件的大小。随着 Redis 的运行,AOF 文件中记录的命令会越来越多,文件的大小也会越来越大。但是,很多旧的命令可能已经不再需要,因为它们修改的数据可能已经被后来的命令再次修改。因此,Redis 提供了 AOF 重写机制,可以创建一个新的 AOF 文件,这个新的 AOF 文件可以达到和原来的 AOF 文件相同的效果,但文件的大小会小很多。

AOF 持久化的重写主要有两个作用:

  1. 减小 AOF 文件的大小:随着 Redis 的运行,AOF 文件中记录的命令会越来越多,文件的大小也会越来越大。但是,很多旧的命令可能已经不再需要,因为它们修改的数据可能已经被后来的命令再次修改。AOF 重写可以创建一个新的 AOF 文件,这个新的 AOF 文件可以达到和原来的 AOF 文件相同的效果,但文件的大小会小很多。
  2. 提高数据恢复的速度:如果 AOF 文件中的命令非常多,那么在 Redis 启动时,需要花费很长的时间来重新执行这些命令,以恢复数据。通过 AOF 重写,可以减少 AOF 文件中的命令数量,从而提高数据恢复的速度。

AOF 重写的过程主要包括以下几个步骤:

  1. Redis 主进程 fork 出一个子进程。
  2. 子进程遍历当前数据库中的所有数据,对每一条数据,生成一条或多条等效的命令,然后将这些命令写入到新的 AOF 文件。
  3. 当子进程完成新的 AOF 文件的创建后,它会向主进程发送一个信号,告诉主进程新的 AOF 文件已经创建完毕。
  4. 主进程收到子进程的信号后,会用新的 AOF 文件替换旧的 AOF 文件。

需要注意的是,AOF 重写虽然有很多好处,但是它也是一个非常消耗资源的操作,特别是在数据集很大的时候。因此,你应该根据你的实际情况,合理地触发 AOF 重写。例如,你可以在 Redis 负载较低的时候,或者在有足够的磁盘空间的时候,触发 AOF 重写。

AOF 重写过程中,Redis 主进程还会继续处理客户端的命令。为了保证数据的一致性,所有修改数据的命令仍然会被追加到旧的 AOF 文件。当新的 AOF 文件创建完毕,旧的 AOF 文件被替换后,这些命令会被再次写入到新的 AOF 文件。

3.4、AOF持久化命令

Redis 中与 AOF 持久化相关的命令主要有以下几个:

  1. BGREWRITEAOF:该命令用于在后台异步执行一个 AOF 重写操作。AOF 重写可以减小 AOF 文件的大小。
  2. CONFIG SET appendonly yes/no:该命令用于开启或关闭 AOF 持久化功能。需要注意的是,关闭 AOF 持久化后,Redis 将只能依赖 RDB 持久化来保存数据。
  3. CONFIG SET appendfsync always/everysec/no:该命令用于设置 AOF 持久化的同步策略。always 表示每次有写命令就立即同步到磁盘,everysec 表示每秒同步一次,no 表示完全由操作系统来决定何时同步。

以上就是 Redis 中和 AOF 持久化相关的主要命令。你可以根据你的实际需求,使用这些命令来控制 AOF 持久化的行为。

3.5、AOF参数设置

在 Redis 的配置文件中,有一些参数是和 AOF 持久化相关的,主要包括以下几个:

  1. appendonly:这个参数用于设置是否开启 AOF 持久化。如果它的值为 yes,那么 Redis 会开启 AOF 持久化。
  2. appendfilename:这个参数用于设置 AOF 文件的文件名。
  3. appendfsync:这个参数用于设置 AOF 持久化的同步策略。有三种可能的值:always 表示每次有写命令就立即同步到磁盘;everysec 表示每秒同步一次;no 表示完全由操作系统来决定何时同步。
  4. no-appendfsync-on-rewrite:这个参数用于设置在执行 AOF 重写时,是否暂停同步 AOF 文件。如果它的值为 yes,那么在执行 AOF 重写时,Redis 会暂停同步 AOF 文件。
  5. auto-aof-rewrite-percentage 和 auto-aof-rewrite-min-size:这两个参数用于设置自动触发 AOF 重写的条件。当 AOF 文件的大小是上次重写后的大小的 auto-aof-rewrite-percentage%,并且 AOF 文件的大小至少为 auto-aof-rewrite-min-size 时,Redis 会自动触发 AOF 重写。

以上就是 Redis 中和 AOF 持久化相关的主要参数。你可以根据你的实际需求,调整这些参数的值,以达到最佳的持久化效果。

3.6、AOF源码简述

Redis 的 AOF 持久化的源码主要分布在 aof.credis.c 两个文件中。以下是一些主要的函数和它们的作用:

  1. flushAppendOnlyFile:这个函数负责将 AOF 缓冲区的内容写入到磁盘。它会根据 appendfsync 配置选项的值来决定何时进行同步。
  2. feedAppendOnlyFile:这个函数负责将执行的命令追加到 AOF 缓冲区。它会将命令和它的参数转换为 Redis 协议格式,然后追加到 AOF 缓冲区。
  3. rewriteAppendOnlyFileBackground:这个函数负责在后台启动一个 AOF 重写操作。它会 fork 出一个子进程来进行 AOF 重写。
  4. rewriteAppendOnlyFile:这个函数负责执行 AOF 重写操作。它会遍历数据库中的所有键,然后生成相应的命令并写入到新的 AOF 文件。
  5. loadAppendOnlyFile:这个函数负责在 Redis 启动时加载 AOF 文件。它会读取 AOF 文件中的所有命令,然后重新执行这些命令,以此来恢复数据。

以上就是 Redis AOF 持久化的主要源码部分。需要注意的是,这只是一个简单的概述,实际的源码会更复杂,包括很多错误处理和优化。如果你想深入理解 Redis 的 AOF 持久化,建议你直接阅读源码。

3.7、AOF优缺点

AOF 持久化的优点:

  1. 数据安全性更高:AOF 持久化可以配置为每执行一次写命令就立即写入磁盘,这样即使发生故障,也只会丢失一次写命令的数据。
  2. 可读性和可写性更好:AOF 文件是一个只追加不修改的日志文件,可以被人类直接阅读。如果文件末尾损坏,可以直接修剪掉损坏部分,不会影响文件的读取

AOF 持久化的缺点:

  1. 文件体积更大:相比于 RDB 持久化,AOF 持久化的文件通常更大。
  2. 处理速度较慢:由于需要记录更多的信息,所以 AOF 持久化的处理速度通常会慢于 RDB 持久化。
  3. 可能存在冗余信息:在大量写入操作的情况下,AOF 文件中可能会存在大量的冗余信息。
  4. AOF 重写需要消耗更多的 CPU 和内存资源:AOF 重写过程中,需要 fork 出一个子进程,这会消耗大量的 CPU 和内存资源。
2.8、AOF注意事项

使用 AOF 持久化时,需要注意以下几点:

  1. 选择合适的 fsync 策略:appendfsync 参数决定了数据同步到磁盘的频率。always 可以提供最高的数据安全性,但会降低写性能;everysec 提供了较好的折中方案,既可以保证一定的数据安全性,又不会太大影响写性能;no 则完全依赖操作系统来决定何时同步,虽然写性能最高,但数据安全性最低。
  2. 定期进行 AOF 重写:随着时间的推移,AOF 文件可能会变得越来越大。定期进行 AOF 重写可以减小 AOF 文件的大小,提高数据恢复的速度。但需要注意的是,AOF 重写是一个消耗资源的操作,应在 Redis 负载较低的时候进行。
  3. 监控 AOF 文件的大小:如果 AOF 文件的大小超过了硬盘的可用空间,那么 Redis 将无法继续写入数据。因此,你应该定期监控 AOF 文件的大小,确保硬盘有足够的可用空间。
  4. 注意 AOF 文件的备份和恢复:你应该定期备份 AOF 文件,以防止数据丢失。在恢复数据时,只需要将备份的 AOF 文件替换到原来的位置,然后重启 Redis 即可。

AOF 和 RDB 是两种不同的持久化方式,各有优缺点。你应该根据你的实际需求来选择使用哪种持久化方式。如果你需要最高的数据安全性,那么应该选择 AOF 持久化。如果你更关心性能和效率,那么应该选择 RDB 持久化。当然,你也可以同时开启 AOF 和 RDB 持久化,以便兼顾数据安全性和效率。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-10-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、Redis持久化机制
    • 1.1、Redis持久化机制简介
      • 1.2、混合使用 RDB 和 AOF
      • 2、RDB(Redis DataBase)
        • 2.1、RDB持久化简介
          • 2.2、RDB持久化过程
            • 2.3、RDB持久化命令
              • 2.4、RDB参数设置
                • 2.5、RDB源码简述
                  • 2.6、RDB优缺点
                    • 2.7、RDB注意事项
                    • 3、AOF(Append Only File)
                      • 3.1、AOF简介
                        • 3.2、AOFB持久化过程
                          • 3.3、AOFB持久化重写
                            • 3.4、AOF持久化命令
                              • 3.5、AOF参数设置
                                • 3.6、AOF源码简述
                                  • 3.7、AOF优缺点
                                    • 2.8、AOF注意事项
                                    相关产品与服务
                                    云数据库 Redis
                                    腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
                                    领券
                                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档