RDB 快照机制
在默认情况下,Redis 会将内存数据库的快照存储在名为 “dump.rdb” 的二进制文件中。同时,你可以通过相关设置,让 Redis 在满足特定条件时自动保存数据集。例如,设定 “save 60 1000”,意味着当在 60 秒内数据集至少有 1000 个键被改动时,Redis 就会自动保存一次数据集。若想关闭 RDB 功能,只需将所有的 save 保存策略注释掉即可。
除了自动保存,还能手动生成 RDB 快照。进入 Redis 客户端后,执行 “save” 或 “bgsave” 命令都可以生成 “dump.rdb” 文件。需要注意的是,每次执行这些命令时,都会依据当前 Redis 的内存状态生成一个全新的 rdb 文件,并覆盖原有的 rdb 快照文件。
bgsave 的写时复制(COW)机制
Redis 借助操作系统提供的写时复制(Copy-On-Write,COW)技术,实现了在生成快照的同时,依然能够正常处理写命令。具体而言,“bgsave” 子进程是由主线程通过 “fork” 操作生成的,它能够共享主线程的所有内存数据。在 “bgsave” 子进程运行后,会开始读取主线程的内存数据,并将其写入 RDB 文件。
在此过程中,如果主线程只是对数据执行读操作,那么主线程和 “bgsave” 子进程之间互不干扰。然而,要是主线程要修改某块数据,这块数据就会被复制一份副本出来,“bgsave” 子进程会把这个副本数据写入 RDB 文件,而主线程依旧可以直接对原来的数据进行修改操作。
另外,配置自动生成 rdb 文件时,后台采用的就是 “bgsave” 方式。
AOF(append-only file)机制
虽然快照功能能对数据进行一定程度的持久化,但它并非十分耐久。倘若 Redis 因某些原因出现故障停机,服务器将会丢失那些最近写入却还没来得及保存到快照中的数据。
从 Redis 1.1 版本起,新增了一种具有更高耐久性的持久化方式 ——AOF 持久化。它会将每一条修改数据集的指令记录到 “appendonly.aof” 文件中(先写入操作系统缓存,每隔一段时间再通过 “fsync” 操作同步到磁盘)。
例如,执行 “set zhuge 666” 命令后,在 aof 文件里会按照 resp 协议格式记录相应数据,其中星号后面的数字表示命令包含的参数个数,“$” 号后面的数字代表对应参数的字符个数。要是执行带过期时间的 set 命令,比如 “set tuling 888 ex 1000”,aof 文件里记录的并非原始执行命令,而是记录 key 过期的时间戳。
可以通过修改配置文件开启 AOF 功能,只需设置 “appendonly yes” 即可。此后,每当 Redis 执行一个会改变数据集的命令(如 SET 命令)时,该命令就会被追加到 AOF 文件的末尾。如此一来,当 Redis 重新启动时,就能通过重新执行 AOF 文件中的命令来重建数据集。
关于 AOF 文件数据同步到磁盘的频率,有以下三种配置选项:
- appendfsync always:每次有新命令追加到 AOF 文件时,就执行一次 “fsync” 操作。这种方式虽然安全性很高,但速度很慢。
- appendfsync everysec:每秒执行一次 “fsync” 操作,它兼顾了速度和安全性,在出现故障时,最多只会丢失 1 秒钟的数据,也是推荐且默认的设置方式。
- appendfsync no:从不执行 “fsync” 操作,而是将数据交由操作系统自行处理。这种方式速度更快,但相对来说不太安全。
AOF 重写机制
随着 Redis 的使用,AOF 文件中可能会积累大量无用的指令。为此,AOF 会定期依据内存中的最新数据来重新生成 aof 文件。
例如,执行了一系列命令后,经过重写,AOF 文件中的内容会根据内存最新状态进行优化调整。
有两个配置项可用于控制 AOF 自动重写的频率:
- # auto‐aof‐rewrite‐min‐size 64mb:表示 aof 文件至少要达到 64M 的大小才会自动触发重写。因为文件太小的话,恢复速度本身就比较快,重写的意义不大。
- # auto‐aof‐rewrite‐percentage 100:意味着 aof 文件自上一次重写后,若文件大小增长了 100%,则会再次触发重写操作。
当然,AOF 也支持手动重写,进入 Redis 客户端执行 “bgrewriteaof” 命令即可进行重写。值得注意的是,AOF 重写时,Redis 同样会 “fork” 出一个子进程去执行相关操作,这与 “bgsave” 命令类似,不会对 Redis 正常处理命令造成过多影响。
RDB 和 AOF 的选择及混合持久化
在实际生产环境中,既可以启用 RDB,也可以启用 AOF。当 Redis 启动时,如果同时存在 rdb 文件和 aof 文件,会优先选择 aof 文件来恢复数据,毕竟通常情况下,aof 文件中的数据相对更全面一些。
Redis 4.0 版本引入了混合持久化这一选项(需先开启 AOF),通过配置 “# aof‐use‐rdb‐preamble yes” 即可开启该功能。开启混合持久化后,AOF 在重写时,不再仅仅是把内存数据转换为 RESP 命令写入 AOF 文件,而是会先对重写这一刻之前的内存做 RDB 快照处理,然后将 RDB 快照内容与增量的 AOF 修改内存数据的命令整合在一起,一同写入新的 AOF 文件。新生成的文件一开始并不叫 “appendonly.aof”,待重写完成后才会进行改名,并覆盖原有的 AOF 文件,完成新旧文件的替换。
借助混合持久化功能,在 Redis 重启时,可以先加载 RDB 的内容,再重放增量 AOF 日志,这样就无需像以往那样全量重放 AOF 文件,从而大幅提升了重启效率。混合持久化后的 AOF 文件有着特定的结构,以此来保障数据恢复的准确性和高效性。
Redis 数据备份策略
以下是一些常见的 Redis 数据备份策略示例:
- 编写 crontab 定时调度脚本,每小时将 rdb 文件或 aof 文件备份一份到指定目录中,并且仅保留最近 48 小时内的备份文件,及时清理过期的备份,避免占用过多磁盘空间。
- 每天保留一份当日的数据备份到特定目录,这样可以保留最近 1 个月的备份数据,方便在需要时进行历史数据回溯或数据恢复操作。
- 在每次进行备份复制操作时,对那些太过陈旧的备份文件进行删除处理,确保磁盘空间的合理利用以及备份数据的有效性。
- 每天晚上将当前机器上的备份文件复制一份到其他机器上,以此来防范因当前机器损坏等意外情况导致的数据丢失问题,增强数据的安全性和冗余性。
Redis 主从架构
配置从节点及主从工作原理
搭建 Redis 主从架构时,配置从节点需要进行相应的操作步骤。
当为 master 配置了一个 slave 后,无论这个 slave 是首次连接 Master,还是后续重新连接,它都会向 master 发送一个 PSYNC 命令来请求复制数据。
Master 收到 PSYNC 命令后,会在后台通过 “bgsave” 方式生成最新的 rdb 快照文件。在持久化过程中,Master 并不会停止接收客户端的请求,而是会把那些可能修改数据集的请求缓存在内存中。
待持久化操作完成后,Master 会将生成的 rdb 文件数据集发送给 slave,slave 接收到数据后,会先进行持久化生成 rdb 文件,再将其加载到内存中。之后,Master 还会把之前缓存在内存中的命令发送给 slave,确保 slave 能完整地复制 master 的数据状态。
并且,当 master 与 slave 之间的连接由于某些原因断开后,slave 具备自动重连 Master 的能力。如果 master 同时收到多个 slave 的并发连接请求,它只会进行一次持久化操作,然后把这份持久化的数据发送给所有并发连接的 slave,避免了重复的资源消耗。
数据部分复制(断点续传)
从 Redis 2.8 版本开始,在 master 和 slave 断开重连的情况下,不再总是进行全量数据复制,而是可以支持部分数据复制(类似断点续传功能),这得益于 PSYNC 命令的使用。
Master 会在其内存中创建一个用于复制数据的缓存队列,用来缓存最近一段时间的数据。Master 和它所有的 slave 都各自维护了复制的数据下标 “offset” 以及 Master 的进程 ID。
当网络连接断开后,slave 会向 master 请求继续进行未完成的复制操作,从所记录的数据下标开始进行。不过,如果 Master 的进程 ID 发生了变化,或者从节点数据下标 “offset” 太过陈旧,已经超出了 Master 的缓存队列范围,那么就会进行一次全量数据的复制。
缓解主从复制风暴
若存在很多从节点,可能会出现主从复制风暴的情况,即多个从节点同时向主节点请求复制数据,导致主节点压力过大。针对这种情况,可以通过合理的架构设计来进行优化,例如让部分从节点与已经和主节点同步过的从节点进行数据同步,以此分担主节点的压力,优化整个主从复制的流程和性能。
希望以上优化后的内容能让你对 Redis 的这些核心机制和架构有更清晰、顺畅的理解,如果你还有其他疑问或者需要进一步详细介绍某些部分,可以随时告诉我哦。