网站平台建设,如何免费建造网站,光谷做网站推广多少钱,重点建设学科网站四、Redis 持久化 四、Redis 持久化4.1 持久化基本原理4.2 RDB持久化4.3 AOF持久化4.4 RDB与AOF对比4.5 持久化技术转型 五、Redis 主从集群六、Redis 分布式系统七、Redis 缓存八、Lua脚本详解九、分布式锁 数据库系列文章#xff1a; 关系型数据库: MySQL —— 基础语法大全… 四、Redis 持久化 四、Redis 持久化4.1 持久化基本原理4.2 RDB持久化4.3 AOF持久化4.4 RDB与AOF对比4.5 持久化技术转型 五、Redis 主从集群六、Redis 分布式系统七、Redis 缓存八、Lua脚本详解九、分布式锁 数据库系列文章 关系型数据库: MySQL —— 基础语法大全MySQL —— 进阶 非关系型数据库: Redis 的安装与配置Redis 基本命令上Redis 基本命令下 四、Redis 持久化 Redis是一个内存数据库所以其运行效率非常高。但也 存在一个问题内存中的数据是不持久的若 主机宕机 或 Redis 关机重启则内存中的数据全部丢失。当然这是不允许的。 Redis 具有持久化功能其会按照设置以 快照 或 操作日志 的形式将数据持久化到磁盘。 根据持久化使用技术的不同Redis 的持久化分为两种 RDBRedis DataBase 与 AOF Append Only File。
4.1 持久化基本原理 Redis 持久化 也称为 钝化 是指将内存中数据库的状态描述信息保存到磁盘中。只不过是不同的持久化技术对数据的状态描述信息是不同的 生成的持久化文件也是不同的 。但它们的作用都是相同的避免数据意外丢失。 通过手动方式或 自动定时方式或 自动条件触发方式将内存中数据库的状态描述信息写入到指定的持久化文件中。当系统重新启动时自动加载 持久化文件并根据文件中数据库状态描述信息将数据恢复到内存中 这个数据恢复过程也称为激活 。这个 钝化 与 激活 的过程就是 Redis 持久化的基本原理。 不过从以上分析可知 对于 Redis 单机状态下 无论是手动方式还是定时方式或条件触发方式都存在数据丢失问题 在尚未手动自动保存时发生了 Redis 宕机状况那么从上次保存到宕机期间产生的数据就会丢失。不同的持久化方式其数据的丢失率也是不同的。 需要注意的是 RDB 是 默认持久化方式但 Redis 允许 RDB 与 AOF 两种持久化技术同时开启此时系统会使用 AOF 方式做持久化即 AOF 持久化技术的 优先级要更高。同样的道理两种技术同时开启状态下 系统启动时若两种持久化文件同时存在则 优先加载 AOF持久化文件。
4.2 RDB持久化 RDBRedis DataBase 是指将内存中某一时刻的 数据快照 全量 写入到指定的 rdb 文件 的持久化技术。 RDB 持久化默认是开启的。 当 Redis 启动时会 自动读取 RDB 快照文件将数据从硬盘载入到内存 以恢复 Redis 关机前的数据库状态。
⭐️ 4.2.1、持久化的执行 RDB持久化的执行有三种方式手动 save 命令、手动 bgsave 命令与自动条件触发。
(1) 手动 save 命令 通过在 redis-cli 客户端中执行 save 命令可立即进行一次持久化保存。 save 命令在执行期间会 阻塞 redis-server 进程直至持久化过程完毕。而在 redis-server 进程阻塞期间 Redis 不能处理任何读写请求无法对外提供服务。
(2) 手动 bgsave 命令 通过在 redis-cli 客户端中执行 bgsave 命令可立即进行一次持久化保存。不同于 save 命令的是正如该命令的名称一样 background save 后台运行 save 。 bgsave 命令会使服务器进程 redis-server 生成一个 子进程由该子进程负责完成保存过程 。在子进程进行保存过程中不会阻塞 redis-server 进程对客户端读写请求的处理。
(3) 自动条件触发 自动条件触发的本质仍是 bgsave 命令的执行。只不过是用户通过在配置文件中做相应的设置后 Redis 会根据设置信息自动调用 bgsave 命令执行。具体配置方式后面会详解。
(4) 查看持久化时间 通过 lastsave 命令可以查看最近一次执行持久化的时间 其返回的是一个 Unix 时间戳 ms。
⭐️ 4.2.2、RDB优化配置重要 RDB 相关的配置在 redis.conf 文件的 SNAPSHOTTING 部分。 (1) save 该配置用于设置快照的自动保存触发条件即 save point 保存点。该触发条件是在指定时间段内发生了指定次数的写操作。 除非另有规定默认情况下持久化条件为 save 3600 1 300 100 60 10000 。 其等价于以下三条: save 3600 1 # 在 3600 秒 (1 小时) 内发生 1 次写操作save 300 100 # 在 300 秒 (5 分钟) 内发生 100 次写操作save 60 10000 # 在 60 秒 (1 分钟) 内发生 1 万次写操作 如果不启用RDB 持久化只需设置 save 的参数为空串即可 save 。 (2) stop-write-on-bgsave-error 默认情况下如果 RDB 快照已启用至少一个保存点且最近的 bgsave 命令失败 Redis将停止接受写入。这样设置是为了让用户意识到数据没有正确地保存到磁盘上否则很可能没有人会注意到并会发生一些灾难 。当然如果 bgsave 命令后来可以正常工作了 Redis将自动允许再次写入。 (3) rdbcompression 当进行持久化时启用 LZF 压缩字符串对象。虽然压缩 RDB 文件会消耗系统资源降低性能但可大幅降低文件的大小方便保存到磁盘加速主从集群中从节点的数据同步。 (4) rdbchecksum 从 RDB5 开始 RDB 文件的 CRC64 校验和就被放置在了文件末尾。这使格式更能 抵抗 RDB文件的损坏但在保存和加载 RDB 文件时性能会受到影响约 10%因此可以设置为 no 禁用校验和以获得最大性能。 在禁用校验和的情况下创建的 RDB 文件的校验和为零这将告诉加载代码跳过校验检查。默认为 yes 开启了校验功能。 (5) sanitize-dump-payload 该配置用于设置在加载 RDB 文件或进行持久化时是否开启对 zipList 、 listPack 等数据的全面安全检测。该检测可以降低命令处理时发生系统崩溃的可能。其可设置的值有三种选择 no 不检测yes 总是检测clients 只有当客户端连接时检测。排除了加载 RDB 文件与进行持久化时的检测。 默认值本应该是 clients 但其会影响 Redis 集群的工作所以默认值为 no 不检测。 (6) dbfilename 指定 RDB 文件的默认名称默认为 dump.rdb 。 (7) rdb-del-sync-files 主从复制时是否删除用于同步的从机上的 RDB 文件。默认是 no 不删除 。 不过需要注意 只有当 从机 的 RDB 和 AOF 持久化功能 都未开启 时才生效。 (8) dir 指定 RDB 与 AOF 文件的生成目录。默认为 Redis 安装根目录。 ⭐️ 4.2.3、RDB文件结构 RDB 持久化文件 dump.rdb 整体上有五部分构成
(1) SOF SOF (Start Of File) 是一个常量一个字符串 REDIS 仅包含这五个字符其长度为 5 。用于标识 RDB文件的开始以便在加载 RDB 文件时可以迅速判断出文件是否是 RDB 文件。
(2) rdb_version 这是一个整数长度为 4 字节表示 RDB 文件的版本号。
(3) EOF EOF (End Of File) 是一个常量占 1 个字节用于标识 RDB 数据的结束校验和的开始。
(4) check_um 校验和 check_sum 用于判断 RDB 文件中的内容是否出现 数据异常。 其采用的是 CRC64 校验算法。 CRC校验算法 在持久化时先将 SOF 、 rdb_version 及内存数据库中的 数据快照 这三者的二进制数据拼接起来形成一个二进制数假设称为数 a 然后再使用这个 a 除以校验和 check_sum 此时可获取到一个余数 b 然后再将这个 b 拼接到 a 的后面形成 databases 。在加载时需要先使用 check_sum 对 RDB 文件进行数据损坏验证。 验证过程只需将 RDB 文件中除 EOF 与 check_sum 外的数据除以 check_sum 。只要除得的余数不是 0 就说明文件发生损坏。当然如果余数是 0 也不能肯定文件没有损坏。这种验证算法是 数据损坏校验而不是数据没有损坏的校验。 (5) databases databases 部分是 RDB 文件中最重要的数据部分其可以包含任意多个非空数据库。而每个 database 又是由三部分构成
SODB 是一个常量占 1 个字节用于标识一个数据库的开始。db_number 数据库编号。key_value_pairs 当前数据库中的键值对数据。 每个 key_value_pairs 又由很多个用于描述 键值对 的数据构成。
VALUE_TYPE 是一个常量占 1 个字节用于标识该键值对中 value 的类型。EXPIRETIME_UNIT 是一个常量占 1 个字节用于标识 过期时间 的单位是 秒 还是 毫秒。TIME 当前 key-value 的过期时间。
⭐️ 4.2.4、RDB持久化过程 (面试的时候要说清楚过程) 对于Redis 默认的 RDB 持久化在进行 bgsave 持久化时 redis-server 进程会 fork 出一个 bgsave 子进程由该子进程以 异步方式 负责完成持久化。而在持久化过程中 redis-server 进程不会阻塞其会继续接收并处理用户的读写请求。 bgsave子进程的详细工作原理如下 由于子进程可以继承 父进程的所有资源且父进程不能拒绝子进程的继承权。所以bgsave 子 进程有权读取到 redis-server 进程写入到内存中的用户数据使得将内存数据持久化到 dump.rdb 成为可能。 bgsave 子进程 在持久化时首先会将内存中的全量数据 copy 到磁盘中的一个 RDB 临时文件 copy 结束后再将该文件 rename 为 dump.rdb 替换掉原来的同名文件。 不过在进行持久化过程中如果 redis-server 进程接收到了用户写请求则系统会将内存中发生数据修改的物理块 copy 出一个 副本。等内存中的全量数据 copy 结束后会再将副本中的数据 copy 到 RDB 临时文件。 这个副本的生成是由于 Linux 系统的 写时复制技术Copy-On-Write 实现的。 写时复制技术是Linux 系统的一种进程管理技术。 原本在 Unix 系统中当一个主进程通过 fork() 系统调用创建子进程后内核进程 会 复制 主进程的整个内存空间中的数据然后分配给子进程。这种方式存在的问题有以下几点 这个过程非常耗时这个过程降低了系统性能如果主进程修改了其内存数据子进程副本中的数据是没有修改的。即出现了数据冗余而冗余数据最大的问题是数据一致性无法保证。 现代 的 Linux 则采用了更为有效的方 式写时复制。子进程会 继承 父进程的所有资源其中就包括主进程的内存空间。即子进程与父进程 共享内存 。只要内存被共享 那么该内存就是只读的写保护的。 而 写时复制 则是在任何一方需要写入数据到共享内存时都会出现异常此时内核进程就会将需要写入的数据 copy 出一个副本写入到另外一块非共享内存区域。 4.3 AOF持久化 AOFAppend Only File 是指 Redis 将每一次的 写操作 都以 日志的形式 记录到一个 AOF 文件中的持久化技术。当需要恢复内存数据时将这些 写操作重新执行一次便会恢复到之前的内存数据状态。
⭐️ 4.3.1、AOF基础配置
(1) AOF 的开启 默认情况下 AOF 持久化是没有开启的通过修改配置文件中的 appendonly 属性为 yes 可以开启。
(2) 文件名配置 Redis 7 在这里发生了重大变化。原来只有一个 appendonly.aof 文件现在具有了三类多个文件
基本文件可以是 RDF 格式也可以是 AOF 格式。其存放的内容是由 RDB 转为 AOF 当时内存的快照数据。该文件可以有多个。增量文件以操作日志形式记录转为 AOF 后的写入操作。该文件可以有多个。清单文件用于维护 AOF 文件的创建顺序保障激活时的应用顺序。 该文件只有一个。
(3) 混合式持久化开启 对于基本文件可以是 RDF 格式也可以是 AOF 格式。通过 aof-use-rdb-preamble 属性可以选择。其默认值为 yes 即默认 AOF 持久化的基本文件为 rdb 格式文件也就是默认采用混合式持久化。
(4) AOF 文件目录配置 为了方便管理可以专门为 AOF 持久化文件指定存放目录。目录名由 appenddirname 属性指定存放在 redis.conf 配置文件的 dir 属性指定的目录默认为 Redis 安装目录。
⭐️ 4.3.2、AOF文件格式 AOF 文件包含三类文件基本文件、增量文件 与 清单文件。其中基本文件一般为 rdb 格式在前面已经研究过了。下面就来看一下 增量文件 与 清单文件 的内容格式。
(1) Redis 协议 增量文件 扩展名为 .aof 采用 AOF 格式。 AOF 格式其实就是 Redis 通讯协议格式 AOF持久化文件的 本质就是基于 Redis 通讯协议的文本 将命令以纯文本的方式写入到文件中。 Redis 协议规定 Redis 文本是 以行来划分 每行以 \r\n 行结束。每一行都有一个 消息头 以表示消息类型。 消息头 由六种不同的符号表示其意义如下:
() 表示一个正确的状态信息(-) 表示一个错误信息(*) 表示消息体总共有多少行不包括当前行($) 表示下一行 消息数据 的长度不包括换行符长度 \r\n(空) 表示一个消息数据(:) 表示返回一个数值
(2) 查看AOF文件 打开 appendonly.aof.1.incr.aof 文件可以看到如下格式内容。 以上内容中框起来的是三条命令。一条数据库切换命令 SELECT 0 两条 set 命令。它们的意义如下
(3) 清单文件 打开清单文件 appendonly.aof.manifest 查看其内容如下 该文件首先会按照 seq 序号列举出所有基本文件基本文件 type 类型为 b 然后再按照 seq 序号再列举出所有增量文件增量文件 type 类型为 i 。 对于 Redis 启动时的数据恢复也会按照该文件由上到下依次加载它们中的数据。
⭐️ 4.3.3、Rewrite机制 随着使用时间的推移AOF 文件会越来越大。为了防止 AOF 文件由于太大而占用大量的磁盘空间降低性能 Redis 引入了 Rewrite 机制来对 AOF 文件进行压缩。
(1) 何为 rewrite 所谓 Rewrite 其实就是对 AOF 文件 进行重写整理。当 Rewrite 开启后主进程 redis-server 创建出一个子进程 bgrewriteaof 由该子进程完成 rewrite 过程。其首先对现有 aof 文件进行 rewrite 计算将 计算结果 写入到一个临时文件写入完毕后再 rename 该临时文件为 原 aof文件名覆盖原有文件。
(2) rewrite 计算 rewrite 计算也称为 rewrite 策略。 rewrite 计算遵循以下策略
读操作命令 不写入文件无效命令 不写入文件过期数据 不写入文件多条命令 合并写入 文件
(3) 手动开启 rewrite Rewrite 过程的执行有两种方式。一种是通过 bgrewriteaof 命令手动开启一种是通过设置条件自动开启。 以下是手动开启方式 该命令会使主进程 redis-server 创建出一个子进程 bgrewriteaof 由该子进程完成 rewrite过程。而在 rewrite 期间 redis-server 仍是可以对外提供读写服务的。
(4) 自动开启 rewrite 手动方式需要人办干预所以一般采用自动方式。由于 Rewrite 过程是一个计算过程需要消耗大量系统资源会降低系统性能。所以 Rewrite 过程并不是随时随地任意开启的而是通过设置一些条件当满足条件后才会启动以降低对性能的影响。 下面是配置文件中对于 Rewrite 自动启动条件的设置。
auto-aof-rewrite-percentage 开启 rewrite 的增大比例默认 100% 。指定为 0 表示 禁用自动 rewrite 。auto-aof-rewrite-min-size 开启 rewrite 的 AOF 文件最小值默认 64M 。该值的设置主要是为了防止小 AOF 文件被 rewrite 从而导致性能下降。 自动重写 AOF 文件。当 AOF 日志文件大小增长到指定的百分比时 Redis 主进程 redis-server 会 fork 出一个子进程 bgrewriteaof 来完成 rewrite 过程。 其工作原理如下
Redis 会记住最新 rewrite 后的 AOF 文件大小作为基本大小如果从主机启动后就没有发生过重写则基本大小就使用启动时 AOF 的大小。如果当前AOF 文件 大于 基本大小的配置文件中指定的百分比阈值且当前 AOF 文件 大于 配置文件中指定的最小阈值则会触发 rewrite 。
⭐️ 4.3.4、AOF优化配置
(1) appendfsync 当客户端提交写操作命令后该命令就会写入到 aof_buf 中而 aof_buf 中的数据持久化到磁盘 AOF 文件的过程称为数据同步。 何时将 aof_buf 中的数据同步到 AOF 文件采用不同的数据同步策略同时的时机是不同的有三种策略
always 写操作命令写入 aof_buf 后会立即调用 fsync() 系统函数将其追加到 AOF 文件。该策略效率较低但相对比较安全不会丢失太多数据。最多就是刚刚执行过的写操作在尚未同步时出现宕机或重启将这一操作丢失。no 写操作命令写入 aof_buf 后什么也不做不会调用 fsync() 函数。而将 aof_buf 中的数据同步磁盘的操作由操作系统负责。 Linux 系统默认同步周期为 30 秒。效率较高。everysec 默认策略。写操作命令写入 aof_buf 后并不直接调用 fsync()而是 每秒调用一次 fsync() 系统函数来完成同步。该策略兼顾到了性能与安全是一种折中方案。
(2) no-appendfsync-on-rewrite 该属性用于指定 当 AOF fsync 策略设置为 always 或 everysec 当主进程创建了子进程 正在执行 bgsave 或 bgrewriteaof 时 主进程是否不调用 fsync() 来做数据同步。设置为 no双重否定即肯定主进程会调用 fsync() 做同步。而 yes 则不会调用 fsync() 做数据同步。 如果调用 fsync()在需要同步的数据量非常大时会阻塞主进程对外提供服务即会存在延迟问题。如果不调用 fsync()则 AOF fsync 策略相当于设置为了 no 可能会 存在 30 秒数据丢失的风险。
(3) aof-rewrite-incremental-fsync 当 bgrewriteaof 在执行过程也是先将 rewrite 计算的结果写入到了 aof_rewr ite_buf 缓存中然后当缓存中数据达到一定量后就会调用 fsync() 进行 刷盘操作即 数据同步 将数据写入到 临时文件。 该属性用于控制 fsync() 每次刷盘的数据量最大不超过 4MB 。这样可以避免由于单次刷盘量过大而引发长时间阻塞。
(4) aof-load-turncated 在进行 AOF 持久化过程中可能会出现 系统突然宕机的情况此时写入到 AOF 文件中的最后一条数据可能会不完整。当主机启动后 Redis 在 AOF 文件不完整的情况下是否可以启动取决于属性 aof-load-truncated 的设置。其值为
yes AOF 文件最后不完整的数据直接从 AOF 文件中截断删除不影响 Redis 的启动。no AOF 文件最后不完整的数据不可以被截断删除 Redis 无法启动。
(5) aof-timestamp-enabled 该属性设置为 yes 则会开启在 AOF 文件中增加时间戳的显示功能可方便按照时间对数据进行恢复。但该方式可能会与 AOF 解析器不兼容所以默认值为 no 不开启。
⭐️ 4.3.5、AOF持久化过程 AOF 详细的持久化过程如下:
Redis 接收到的 写操作命令 并不是直接追加到磁盘的 AOF 文件的而是将每一条写命令 按照 redis 通讯协议格式 暂时 添加到 AOF 缓冲区 aof_buf 。根据设置的数据同步策略当同步条件满足时再将缓冲区中的数据 一次性写入磁盘的 AOF 文件以减少磁盘 IO 次数提高性能。当磁盘的 AOF 文件大小达到了 rewrite 条件时 redis-server 主进程会 fork 出一个子进程 bgrewriteaof 由该子进程完成 rewrite 过程。子进程 bgrewriteaof 首先对该磁盘 AOF 文件进行 rewrite 计算将计算结果写入到一个临时文件全部写入完毕后再 rename 该临时文件为磁盘文件的原名称覆盖原文件。如果在 rewrite 过程中又有写操作命令追加那么这些数据会暂时写入 aof_rewrite_buf 缓冲区。等将全部 rewrite 计算结果写入临时文件后会先将 aof_rewrite_buf 缓冲区中的数据写入临时文件然后再 rename 为磁盘文件的原名称覆盖原文件。
4.4 RDB与AOF对比
⭐️ 4.4.1、RDB优势与不足
1RDB优势
RDB 文件较小数据恢复较快
2RDB不足
数据安全性较差写时复制会降低性能RDB 文件可读性较差
⭐️ 4.4.2、AOF优势与不足
1AOF优势
数据安全性高AOF 文件可读性强
2AOF不足
AOF 文件较大写操作会影响性能数据恢复较慢
4.5 持久化技术转型
官方推荐使用 RDB 与 AOF 混合式持久化。若对数据安全性要求不高则推荐使用 纯 RDB 持久化方式。不推荐使用纯 AOF 持久化方式。若 Redis 仅用于缓存则无需使用任何持久化技术。 Redis 持久化 快速食用---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 五、Redis 主从集群
六、Redis 分布式系统
七、Redis 缓存
八、Lua脚本详解
九、分布式锁