原创

Redis 之 Redis 持久化存储

持久化存储分类

在 Redis 中,持久化存储分为两种。一种是 aof 日志追加的方式,另外一种是 rdb 数据快照的方式。

RDB持久化存储

RDB持久化存储即是将redis存在内存中的数据以快照的形式保存在本地磁盘中。

RDB持久化存储分为自动备份和手动备份.

手动备份通过 save 命令和 bgsave 命令。save是同步阻塞,而 bgsave 是非阻塞(阻塞实际发生在 fork 的子进程中)。

bgsave持久化存储实现原理

bgsave持久化存储实现原理.png
原理解析

  • 1.执行bgsave命令,Redis父进程判断当前是否存在正在执行的子进程,如果存在则直接返回.
  • 2.父进程fork一个子进程(fork的过程中会造成阻塞的情况),这个过程可以使用info stats命令查看latest_fork_usec选项,查看最近一次fork操作小号的时间,单位是微妙.
  • 3.父进程fork完之后,则会返回Background saving started信息提示,此时fork阻塞解除.
  • 4.fork出的子进程开始根据父进程内存数据生成临时的快照文件,然后替换原文件.使用lastsave命令可以查看最后一次生成rdb的时间,对应info的rdb_last_savetime选项.
  • 5.当备份完毕之后向父进程发送完成信息,具体可以见info Persistence下的rbd*选项.

指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。
RDB持久化.jpg

RDB持久化的优势与劣势

优势:

1.文件实现的数据快照,全量备份,便于数据的传输.比如我们需要把A服务器上的备份文件传输到B服务器上面,直接将rdb文件拷贝即可. 这种文件非常适合用于进行备份。

2.文件采用压缩的二进制文件,当重启服务时加载数据文件,比aof方式更快.

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

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

劣势

1.rbd采用加密的二进制格式存储文件,由于Redis各个版本之间的兼容性问题也导致rdb由版本兼容问题导致无法再其他的Redis版本中使用.

2.时效性差,容易造成数据的不完整性, 容易丢数据. 因为rdb并不是实时备份,当某个时间段Redis服务出现异常,内存数据丢失,这段时间的数据是无法恢复的,因此易导致数据的丢失.

AOF

AOF持久化存储便是以日志的形式将redis存储在aof_buf缓冲区中的数据写入到磁盘中。简而言之,就是记录redis的操作日志,将redis执行过的命令记录下载,当我们需要数据恢复时,redis去重新执行一次日志文件中的命令.

如何配置持久化存储

// 将no改为yes,控制aof开启与否
appendonly no
// 控制aof文件名称,存储的目录便是dir配置项
appendfilename "appendonly.aof"
// 三种备份策略(三者只需要开启以一个即可)
# appendfsync always // 命令写入立即写入磁盘
appendfsync everysec // 每秒实现文件的同步,写入磁盘
# appendfsync no // 随机进行文件的同步,同步操作则交给操作系统来负责,通常时间是最长30s

AOF持久化存储实现原理

aof日志追加方式实现持久化存储,每当执行服务器(定时)任务或者函数时flushAppendOnlyFile 函数都会被调用.
存储时需要经历如下四个过程.命令写入->文件同步->文件重写->文件重载
AOF持久化存储实现原理.png

  • 1.redis命令写入,此时会将redis命令写入aof_buf换从区.
  • 2.缓冲区中数据根据备份策略实现写入日志文件.
  • 3.当aof的文件越来越庞大,会根据我们的配置策略来实现aof的重写,实现文件的压缩,减少体积.
  • 4.当redis重新启动时,在去重写加载aof文件,达到数据恢复的目的.

aof采用的是 redis通讯协议(RESP )格式的命令文本存储(文本协议格式)。

以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录。
AOF(append only file)持久化.jpg

AOF的优缺点

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

  2. 数据实时保存,数据完整性强.即使丢失某些数据,制定好策略最多也是一秒内的数据丢失.

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

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

  5. 可读性强,由于使用的是文本协议格式来存储的数据,可有直接查看操作的命令,同时也可以手动改写命令.

举个例子, 如果你不小心执行了 FLUSHALL 命令, 但只要 AOF 文件未被重写, 那么只要停止服务器, 移除 AOF 文件末尾的 FLUSHALL 命令, 并重启 Redis , 就可以将数据集恢复到 FLUSHALL 执行之前的状态。

缺点

文件体积过大,加载速度比rbd慢.由于aof记录的是redis操作的日志,一些无效的,可简化的操作也会被记录下来,造成aof文件过大.但该方式可以通过文件重写策略进行优化.

RDB和AOF比较:

  • 1、aof文件比rdb更新频率高,优先使用aof还原数据。
  • 2、aof比rdb更安全也更大
  • 3、rdb性能比aof好
  • 4、rdb(即bgsave)做镜像全量持久化,aof做增量持久化。因为bgsave会耗费较长时间,不够实时,在停机的时候会导致大量丢失数据,所以需要aof来配合使用。在redis实例重启时,优先使用aof来恢复内存的状态,如果没有aof日志,就会使用rdb文件来恢复。

选择AOF还是RDB进行数据的持久化

  • 1.针对不同的情况来选择,建议使用两种方式相结合.
  • 2.针对数据安全性、完整性要求高的采用aof方式.
  • 3.针对不太重要的数据可以使用rdb方式.
  • 4.对于数据进行全量备份,便于数据备份的可以采用rdb方式.
  • 5.一般来说, 如果想达到足以媲美 PostgreSQL 的数据安全性, 你应该同时使用两种持久化功能。只使用 AOF 持久化, 并不推荐: 因为定时生成 RDB 快照(snapshot)非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快。

什么是 redis通讯协议(RESP )

RESP 是redis客户端和服务端之前使用的一种通讯协议;

RESP 的特点:实现简单、快速解析、可读性好
For Simple Strings the first byte of the reply is "+" 回复
For Errors the first byte of the reply is "-" 错误
For Integers the first byte of the reply is ":" 整数
For Bulk Strings the first byte of the reply is "$" 字符串
For Arrays the first byte of the reply is "*" 数组

FAQ

1、redis在服务期间,如果突然机器掉电会怎样?

该现象的结果,取决于aof日志sync属性的配置。如果不要求性能,在每条写指令时都sync一下磁盘,就不会丢失数据。但是在高性能的要求下每次都sync是不现实的,一般都使用定时sync,比如1s1次,这个时候最多就会丢失1s的数据。
~ end

正文到此结束
广告是为了更好的提供数据服务
本文目录