Redis--Redis的持久化

参考博客传送门:

http://doc.redisfans.com/topic/persistence.html
https://www.cnblogs.com/chenpingzhao/p/5158791.html

什么是Redis的持久化?

Redis的持久化就是把内存的数据写到磁盘中去,防止服务宕机了内存数据丢失。
当然了,你可以关闭持久化,让数据只在服务器运行时存在。

Redis持久化有几种,分别是什么,各自有什么优缺点

Redis 提供了两种持久化方式:快照(RDB文件 默认)和追加式文件(AOF文件)

RDB是Redis DataBase缩写,是指在指定的时间间隔能对你的数据进行快照存储。
它所生成的 RDB 文件是一个压缩的二进制文件,通过该文件可以还原生成 RDB 文件时的数据库状态
PS:数据库状态是指 Redis 服务器的非空数据库以及他们键值对的统称

RDB 文件的创建

有两个命令可以生成 RDB 文件,一个是 SAVE、另一个是 BGSAVE。

两者的区别在于:前者会阻塞 Redis 服务器进程,直到 RDB 文件创建完毕为止。

而在服务器进程阻塞期间,服务器是不能处理任何命令请求的。

后者则不会阻塞服务器进程,因为是通过 fork 一个子进程,并让其去创建 RDB 文件,而服务器进程(父进程)继续则继续处理命令请求。

当写完数据库状态后,新 RDB 文件就会原子地替换旧的 RDB 文件。

RDB 文件的载入

RDB 文件的载入是在服务器启动时自动执行的,所以没有用于载入的命令,期间阻塞主进程。

只要没有开启 AOF 持久化功能,在启动时检测到有 RDB 文件,就会自动载入。

当服务器有开启 AOF 持久化功能时,服务器将会优先使用 AOF 文件来还原数据库状态。原因是 AOF 文件的更新频率通常比 RDB 文件的更新频率高。

Redis载入RDB文件时,会对RDB文件进行校验,如果文件损坏,则日志中会打印错误,Redis启动失败。

RDB的优点有:

  1. RDB 保存了 Redis 在某个时间点上的数据集,非常适合用于进行备份:

  2. RDB 非常适用于灾难恢复:它只有一个文件,并且内容都非常紧凑,可以(在加密后)将它传送到其他地方。

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

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

RDB的缺点有:

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

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

AOF是Append-only file缩写,是指记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据。 AOF 文件中的命令全部以 Redis 协议的格式来保存,新命令会被追加到文件的末尾。

AOF 持久化实现

AOF 持久化功能的实现可以分为 3 个步骤:命令追加(到 AOF 缓冲区)、文件写入(缓冲区内容写到 AOF 文件)、文件同步(AOF 文件保存磁盘)
Redis 服务器进程就是一个事件循环,这个循环中的文件事件(socket 的可读可写事件)负责接收客户端的命令请求,以及向客户端发送命令结果。

因为服务器在处理文件事件时,可能会发生写操作,使得一些内容会被追加到 AOF 缓冲区末尾。所以,在服务器每次结束一个事件循环之前 ,都会调用 flushAppendOnlyFile 方法。

这个方法执行以下两个工作:

WRITE:根据条件,将缓冲区内容写入到 AOF 文件。

SAVE:根据条件,调用 fsync 或 fdatasync 函数,将 AOF 文件保存到磁盘中。

两个步骤都需要根据一定的条件来执行,而这些条件由 Redis 配置文件中的 appendfsync 选项来决定的,一共有三个选择:

appendfsync always:每次执行完一个命令之后, WRITE 和 SAVE 都会被执行

appendfsync everysec:SAVE 原则上每隔一秒钟就会执行一次。

appendfsync no:每次执行完一个命令之后, WRITE 会执行,SAVE 都会被忽略
(只会在以下任意一种情况中被执行:
Redis 被关闭
AOF 功能被关闭
系统的写缓存被刷新(可能是缓存已经被写满,或者定期保存操作被执行。完成依赖 OS 的写入,一般为 30 秒 左右一次))
在这里插入图片描述

AOF 重写

既然 AOF 持久化是通过保存写命令到文件的,那随着时间的推移,这个 AOF 文件记录的内容就越来越多,文件体积也就越来越大,对其进行数据还原的时间也就越来越久,这时候就需要用到AOF的重写功能了。

通过该功能来创建一个新的 AOF 文件来代替旧文件。并且两个文件所保存的数据库状态一样,但新文件不会包含任何冗余命令,所以新文件要比旧文件小得多。

这个重写功能是通过读取服务器当前的数据库状态来实现的。虽然叫做“重写”,但实际上并没有对旧文件进行任何读取修改。

AOF的特点有:

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

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

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

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

AOF的缺点有:

  1. 对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积。

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

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

持久化的配置

RDB配置:

时间策略(默认)
save 900 1      // 900 秒内,对数据库至少修改 1 次。下面同理    
save 300 10     
save 60 10000       

文件名称
dbfilename dump.rdb

文件保存路径
dir ./

如果持久化出错,主进程是否停止写入(默认情况下,如果Redis在后台生成快照的时候失败,那么就会停止接收数据,目的是让用户能知道数据没有持久化成功。但是如果你有其他的方式可以监控到Redis及其持久化的状态,那么可以把这个功能禁止掉。)
stop-writes-on-bgsave-error yes

是否压缩(默认Redis会采用LZF对数据进行压缩。如果你想节省点CPU的性能,你可以把压缩功能禁用掉,但是数据集就会比没压缩的时候要打。)
rdbcompression yes

导入时是否检查(从版本5的RDB的开始,一个CRC64的校验码会放在文件的末尾。这样更能保证文件的完整性,但是在保存或者加    载文件时会损失一定的性能(大概10%)。如果想追求更高的性能,可以把它禁用掉,这样文件在写入校验码时会用0替代,加载的时  候看到0就会直接跳过校验)
rdbchecksum yes

如果想禁用快照保存的功能,可以通过注释掉所有"save"配置达到,或者在最后一条"save"配置后添加如下的配置:
save ""

AOF配置:

启用AOF配置
appendonly yes

文件名称
appendfilename "appendonly.aof"

可靠性:
appendfsync always:每当有新命令追加到AOF的时候调用fsync。速度最慢,但是最安全。
appendfsync everysec:每当有新命令追加到AOF的时候调用fsync。速度最慢,但是最安全。
appendfsync no:从不fsync,交由系统去处理。这个方式速度最快,但是安全性没有保证
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章