Redis 数据库(四)—— Redis 持久化

一、持久化概述

1.1 持久化介绍

1.1.1 持久化介绍
利用永久性存储介质将数据进行保存,在特定的时间将保存的数据进行恢复的工作机制称为持款化。

Redis 的持久化可以防止数据的意外丢失,确保数据安全性

1.2 持久化方式

1.2.1 RDB 持久化
RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot)。

1.2.2 AOF 持久化
AOF 持久化记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。 AOF 文件中的命令全部以 Redis 协议的格式来保存,新命令会被追加到文件的末尾。 Redis 还可以在后台对 AOF 文件进行重写,使得 AOF 文件的体积不会超出保存数据集状态所需的实际大小。

Redis 还可以同时使用 AOF 持久化和 RDB 持久化。 在这种情况下, 当 Redis 重启时, 它会优先使用 AOF 文件来还原数据集, 因为 AOF 文件保存的数据集通常比 RDB 文件所保存的数据集更完整。

二、RDB 持久化

2.1 RDB 的优缺点

2.1.1 RDB 的优点
RDB 是一个非常紧凑(compact)的文件,它保存了 Redis 在某个时间点上的数据集。 这种文件非常适合用于进行备份: 比如说,你可以在最近的 24 小时内,每小时备份一次 RDB 文件,并且在每个月的每一天,也备份一个 RDB 文件。 这样的话,即使遇上问题,也可以随时将数据集还原到不同的版本。

RDB 非常适用于灾难恢复(disaster recovery):它只有一个文件,并且内容都非常紧凑,可以(在加密后)将它传送到别的数据中心,或者亚马逊 S3 中。

RDB 可以最大化 Redis 的性能:父进程在保存 RDB 文件时唯一要做的就是 fork 出一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无须执行任何磁盘 I/O 操作。

RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。

2.1.2 RDB 的缺点
如果你需要尽量避免在服务器故障时丢失数据,那么 RDB 不适合你。 虽然 Redis 允许你设置不同的保存点(save point)来控制保存 RDB 文件的频率, 但是, 因为RDB 文件需要保存整个数据集的状态, 所以它并不是一个轻松的操作。 因此你可能会至少 5 分钟才保存一次 RDB 文件。 在这种情况下, 一旦发生故障停机, 你就可能会丢失好几分钟的数据。

每次保存 RDB 的时候,Redis 都要 fork() 出一个子进程,并由子进程来进行实际的持久化工作。 在数据集比较庞大时, fork() 可能会非常耗时,造成服务器在某某毫秒内停止处理客户端; 如果数据集非常巨大,并且 CPU 时间非常紧张的话,那么这种停止时间甚至可能会长达整整一秒。 虽然 AOF 重写也需要进行 fork() ,但无论 AOF 重写的执行间隔有多长,数据的耐久性都不会有任何损失。

2.2 持久化指令

持久化指令为

save

2.3 save 指令相关配置文件

2.3.1 dbfilename dump.rdb

  • 设置本地数据库文件名,默认值为dump.rdb
  • 通常设置为dump-端口号.rdb

2.3.2 dir

  • 设置存储.rdb文件的路径
  • 通常设置成存储空间较大的目录中,目录名称data

2.3.3 rdbcompression yes

  • 设置存储至本地数据库时是否压缩数据,默认为yes,采用LZF压缩
  • 通常默认为开启状态,如果设置为no,可以节省CPU运行时间,但会使存储的文件变大(巨大)

2.3.4 rdbchecksum yes

  • 设置是否进行RDB文件格式校验,该校验过程在写文件和读文件过程均进行
  • 通常默认为开启状态,如果设置为no,可以节约读写性过程约10%时间消耗,但是存储一定的数据损坏风险

2.4 RDB 启动方式

2.4.1 bgsave 指令-手动启动
(1)示例
save指令可以完成持久化,但是是单线程操作,效率较低,这是可以使用bgsave指令,手动启动后台保存操作,但不是立即执行。
在这里插入图片描述

(2)bgsave 指令原理
当执行bgsave指令时,会发送指令给Redis,然后Redis会返回一个消息,但这个时候指令没有真正执行。在返回消息的时候,Redis会调用fork函数并生成一个子进程,这是一个单独的子进程,由这个子进程创建.rdb文件并完成指令,然后返回消息

bgsave命令是针对save阻塞问题做的优化,Redis内部所有涉及到RDB操作都采用bgsave的方式,save命令可以放弃使用。

(3)bgsave 指令配置

stop-writes-on-bgsave- error yes

后台存储过程中如果出现错误现象,是否停止保存操作,通常默认为开启状态。

2.4.2 save配置-自动启动
(1)save配置介绍
RDB 自动启动方式采用save配置方式完成

save second changes

在conf文件中进行配置,满足限定时间范围内key的变化数量达到指定数量即进行持久化。

  • second:监控时间范围
  • changes:监控key的变化量

(2)save配置启动原理
配置save启动方式后,当客户端执行了对应变化量的操作指令时,指令会发送给Redis,每个指令都会返回一个操作结果,这个结果会真正对数据产生影响,就会自动执行save配置持久化。

(3)配置save启动注意事项
save配置要根据实际业务情况进行设置,频度过高或过低都会出现性能问题,结果可能是灾难性的。

save配置中对于second与changes设置通常具有互补对应关系,尽量不要设置成包含性关系。

save配置启动后执行的是bgsave操作。

2.4.3 RDB 特殊启动方式
(1)全量复制启动方式

(2)在服务器运行过程中重启

debug reload

(3)关闭服务器时指定保存数据

shutdown save

2.4.4 RDB 启动方式比较

方式 save指令 bgsave指令
读写 同步 异步
阻塞客户端指令
额外内存消耗
启动新进程

三、AOF 持久化

3.1 AOF 持久化概述

3.1.1 AOF 持久化介绍
AOF(append only file)持久化:以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中命令达到恢复数据的目的。与RDB相比可以简单描述为改记录数据为记录数据产生的过程

AOF的主要作用是解决了数据持久化的实时性,目前已经是Redis持久化的主流方式。

3.1.2 AOF 持久化优缺点
(1)AOF 的优点
使用 AOF 持久化会让 Redis 变得非常耐久(much more durable):你可以设置不同的 fsync 策略,比如无 fsync ,每秒钟一次 fsync ,或者每次执行写入命令时 fsync 。 AOF 的默认策略为每秒钟 fsync 一次,在这种配置下,Redis 仍然可以保持良好的性能,并且就算发生故障停机,也最多只会丢失一秒钟的数据( fsync 会在后台线程执行,所以主线程可以继续努力地处理命令请求)。

AOF 文件是一个只进行追加操作的日志文件(append only log), 因此对 AOF 文件的写入不需要进行 seek , 即使日志因为某些原因而包含了未写入完整的命令(比如写入时磁盘已满,写入中途停机,等等), redis-check-aof 工具也可以轻易地修复这种问题。

Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写: 重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合。 整个重写操作是绝对安全的,因为 Redis 在创建新 AOF 文件的过程中,会继续将命令追加到现有的 AOF 文件里面,即使重写过程中发生停机,现有的 AOF 文件也不会丢失。 而一旦新 AOF 文件创建完毕,Redis 就会从旧 AOF 文件切换到新 AOF 文件,并开始对新 AOF 文件进行追加操作。

AOF 文件有序地保存了对数据库执行的所有写入操作, 这些写入操作以 Redis 协议的格式保存, 因此 AOF 文件的内容非常容易被人读懂, 对文件进行分析(parse)也很轻松。 导出(export) AOF 文件也非常简单: 举个例子, 如果你不小心执行了 FLUSHALL 命令, 但只要 AOF 文件未被重写, 那么只要停止服务器, 移除 AOF 文件末尾的 FLUSHALL 命令, 并重启 Redis , 就可以将数据集恢复到 FLUSHALL 执行之前的状态。

(2)AOF 的缺点
对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积。

根据所使用的 fsync 策略,AOF 的速度可能会慢于 RDB 。 在一般情况下, 每秒 fsync 的性能依然非常高, 而关闭 fsync 可以让 AOF 的速度和 RDB 一样快, 即使在高负荷之下也是如此。 不过在处理巨大的写入载入时,RDB 可以提供更有保证的最大延迟时间(latency)。

AOF 在过去曾经发生过这样的 bug : 因为个别命令的原因,导致 AOF 文件在重新载入时,无法将数据集恢复成保存时的原样。 (举个例子,阻塞命令 BRPOPLPUSH source destination timeout 就曾经引起过这样的 bug 。) 测试套件里为这种情况添加了测试: 它们会自动生成随机的、复杂的数据集, 并通过重新载入这些数据来确保一切正常。 虽然这种 bug 在 AOF 文件中并不常见, 但是对比来说, RDB 几乎是不可能出现这种 bug 的。

3.2 AOF 持久化策略

3.2.1 AOF 持久化策略介绍
(1)always(每次)
每次写入操作均同步到AOF文件中,数据零误差,性能较低。

(2)everysec (每秒)
每秒将缓冲区中的指令同步到AOF文件中,数据准确性较高,性能较高,在系统突然宕机的情况下只会丢失1秒内的数据。

(3)no (系统控制)
由操作系统控制每次同步到AOF文件的周期,整体过程不可控。

**3.2.2AOF 持久化策略配置 **
首先要在配置文件中开启AOP持久化策略功能,默认为不开启状态

appendonly yes|no

然后再配置文件中配置具体的AOP持久化策略

appendfsyno always|everysec|no 

其他配置

appendfilename filename

AOF持久化文件名,默认文件名未appendonly.aof,建议配置为appendonly-端口号.aof

dir

AOF持久化文件保存路径,与RDB持久化文件保持一致即可

3.3 AOP 重写

3.3.1 AOP 重写介绍
随着命令不断写入AOF,文件会越来越大,为了解决这个问题,Redis引入 了AOF重写机制压缩文件体积。AOF文件重
写是将Redis进程内的数据转化为写命令同步到新AOF文件的过程。简单说就是将对同一个数据的若干个条命令执行结
果转化成最终结果数据对应的指令进行记录。

3.3.2 AOP 重写作用

  • 降低磁盘占用量,提高磁盘利用率
  • 提高持久化效率,降低持久化写时间,提高IO性能
  • 降低数据恢复用时,提高数据恢复效率

3.3.3 AOP 重写规则

  • 进程内已超时的数据不再写入文件
  • 忽略无效指令,重写时使用进程内数据直接生成,这样新的AOF文件只保留最终数据的写入命令,如del key1hdel key2sremkey3set key4 111. set key4 222等。
  • 对同一数据的多条写命令合并为一条命令
    lpush list1 aIpush list1 bIlpush list1 c可以转化为:Ipush list1 a b c。为防止数据量过大造成客户端缓冲区溢出,对list. set. hash. zset等类型,每条指令最多写入64个元素。

3.3.4 AOP 重写相关指令
手动重写

bgrewriteaof

自动重写

auto-aof-rewrite-min-size size
auto-aof-rewrite-percentage percentage

自动重写触发比对参数 (运行指令info Persistence获取具体信息)

aof_current_size
aof_base_size

自动重写触发条件

aof_current_size > auto-aof-rewrite-min-size
aof_current_size - aof_base_size / aof_base_size >= auto-aof-rewrite-percentage 

3.4 RDB 和 AOP 比较

3.4.1 RDB 和 AOF 比较

持久化方式 RDB AOF
占用存储空间 小(数据级:压缩) 大(指令级:重写
存储速度
恢复速度
数据安全性 会丢失数据 依据策略决定
资源消耗 高/重量级 低/轻量级
启动优先级

3.4.2 RDB 和 AOF 选择

  • 一般来说, 如果想达到足以媲美 PostgreSQL 的数据安全性, 可以同时使用两种持久化功能。
  • 如果你非常重视数据, 但仍然可以承受数分钟以内的数据丢失, 那么你可以只使用 RDB 持久化。
  • 对数据非常敏感,建议使用默认的AOF持久化方案
    • AOF持久化策略使用everysecond,每秒钟fsync一次。该策略redis5仍可以保持很好的处理性能,当出
      现问题时,最多丢失0-1秒内的数据。
    • 注意:由于AOF文件存储体积较大,且恢复速度较慢
  • 数据呈现阶段有效性,建议使用RDB持久化方案
    • 数据可以良好的做到阶段内无丢失(该阶段是开发者或运维人员手工维护的),且恢复速度较快,阶段
      点数据恢复通常采用RDB方案
    • 注意:利用RDB实现紧凑的数据持久化会使Redis降的很低
  • 综合比对
  • RDB与AOF的选择实际上是在做一种权衡,每种都有利有弊
  • 如不能承受数分钟以内的数据丢失,对业务数据非常敏感,选用AOF
  • 如能承受数分钟以内的数据失,且追求大数据集的恢复速度,选用RDB
  • 灾难恢复选用RDB
  • 双保险策略,同时开启RDB和AOF,重启后,Redis优先使用AOF来恢复数据,降低丢失数据的量

有很多用户都只使用 AOF 持久化, 但我们并不推荐这种方式: 因为定时生成 RDB 快照(snapshot)非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快, 除此之外, 使用 RDB 还可以避免之前提到的 AOF 程序的 bug 。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章