您的位置:首页 > 数据库 > Redis

十九 Redis AOF持久化

2018-12-27 09:27 357 查看
RDB 持久化的缺点

RDB 持久化,这种持久化可以将数据库里面的数据以二进制文件的形式储存到硬盘里面。
RDB 持久化有一个缺点,那就是,因为创建 RDB 文件需要将服务器所有数据库的数据都保存起来, 这是一个非常耗费资源和时间的操作,所以服务器需要隔一段时间才创建一个新的 RDB 文件,也即 是说,创建 RDB 文件的操作不能执行得过于频繁,否则就会严重地影响服务器的性能。
比如说,在 save 配置选项的默认设置下,即使有超过 10000 次修改操作发生,服务器也至少会间隔 一分钟才创建下一个 RDB 文件:
save 900 1
save 300 10
save 60 10000
如果在等待创建下一个 RDB 文件的过程中,服务器遭遇了意外停机,那么用户将丢失最后一次创建 RDB 文件之后,数据库发生的所有修改
数据丢失例子

解决方法
为了解决 RDB 持久化在遭遇意外停机时丢失大量数据的问题,Redis提供了 AOF 持久化功能。
比起 RDB 持久化, AOF 持久化有一个巨大的优势,那就是,用户可以根据自己的需要对 AOF 持 久化进行调整,让 Redis 在遭遇意外停机时不丢失任何数据,或者只丢失一秒钟数据,这比 RDB
久化遭遇意外停机 时,丢失的数据要少得多

AOF 持久化的运作原理
数据保存和数据还原

保存数据
AOF 持久化保存数据库数据的方法是:每当有修改数据库的命令被执行时,服务器就会将被执行的命 令写入到 AOF 文件的末尾。

数据还原
因为 AOF 文件里面储存了服务器执行过的所有数据库修改命令,所以给定一个 AOF 文件,服务器
只要重新执行一遍 AOF 文件里面包含的所有命令,就可以达到 还原数据库数据的目的。
举个例子,对于包含以下内容的 AOF 文件来说
select 0
set msg "hello"
incr counter
sadd alphabets "a" "b" "c"
incr counter

服务器只要重新 执行这些命令
就可以还原出右图所示的数据库

安全性问题 通过配置选项来调整
AOF 持久化的安全性


AOF 持久化的安全性问题
虽然服务器每执行一个修改数据库的命令,就会将被执行的命令写入到 AOF 文件,但这并不意味着
AOF 持久化不会丢失任何数据。
在目前常见的操作系统中,执行系统调用 write 函数,将一些内容写入到某个文件里面 时,为了提高 效率,系统通常不会直接将内容写入到硬 盘里面,而是先将内容放入到一个内存 缓冲区(buffer)里面, 等到缓冲区被填满,或者用户执行 fsync 调用和 fdatasync 调用时,才将储存在缓冲区里面的内容真 正地写入到硬 盘里面。
对于 AOF 持久化来说,当一条命令真正地被写入到硬 盘里面时,这条命令才不会因为停机而意外丢 失。
因此,AOF 持久化在遭遇停机时丢失命令的数量,取决于命令被写入到硬盘的时间: • 越早将命令写入到硬 盘,发生意外停机 时丢失的数据就越少;
• 而越迟将命令写入到硬盘,发生意外停机时丢失的数据就越多。



安全性控制
为了控制 Redis 服务器在遇到意外停机时丢失的数据量,Redis 为 AOF 持久化提供了 appendfsync 选项,这个选项的值可以是 always 、 everysec 或者 no ,这些值的意思分别为:
always :服务器每写入一个命令,就调用一次 fdatasync ,将缓冲区里面的命令写入到硬盘里面。在 这种模式下,服务器即使遭遇意外停机,也不会 丢失任何已经成功执行的命令数据

everysec :服务器每秒钟调用一次 fdatasync ,将缓冲区里面的命令写入到硬 盘里面。在这种模式下, 服务器遭遇意外停机 时,最多只丢失一秒钟内执行的命令数据。
no :服务器不主动调用 fdatasync ,由操作系统决定何时将缓冲区里面的命令写入到硬 盘里面。在这种 模式下,服 务器遭遇意外停机 时,丢失命令的数量是不确定的。
运行速度: always 的速度慢, everysec 和 no 都很快
默认值: everysec

停机示例

AOF重写
创建一个没有冗余内容的新AOF文件

AOF 文件中的冗余命令
随着服务器的不断运行, 为了记录数据库发生的变化,服务器会将越来越多的命令写入到 AOF 文件
里面,使得 AOF 文件的体积不断地增大。
为了让 AOF 文件的大小控制在合理的范围,避免它胡乱地增长,Redis提供了AOF 重写功能,通过
这个功能,服务器可以产生一个新的 AOF 文件:
• 新 AOF 文件记录的数据库数据和原有 AOF 文件记录的数据库数据完全一样;
• 新的 AOF 文件会使用尽可能少的命令来 记录数据库数据,因此新 AOF 文件的体积通常会比原
有 AOF 文件的体积要小得多。
• AOF 重写期间,服务器不会被阻塞,可以正常处理客户端发送的命令请求。
来看一个 AOF 重写的示例。


AOF 重写示例

AOF 重写的触发
有两种方法可以触发 AOF 重写:
1. 客户端向服务器发送 BGREWRITEAOF 命令。
2. 通过设置配置选项来让服务器自动执行 BGREWRITEAOF 命令,它们分别是:
• auto-aof-rewrite-min-size <size> ,触发 AOF 重写所需的最小体积:只有在 AOF 文件的体积 大于等于 size 时,服务器才会考虑是否需要进行 AOF 重写。这个选项用于避免对体积过小的 AOF 文件进行重写。
• auto-aof-rewrite-percentage <percent> ,指定触发重写所需的 AOF 文件体积百分比:当 AOF 文件的体积大于 auto-aof-rewrite-min-size 指定的体积,并且超过上一次重写之后的 AOF 文件 体积的 percent% 时,就会触发 AOF 重写。(如果服务器刚刚启动不久,还没有进行过 AOF 重 写,那么使用服务器启动时载入的 AOF 文件的体积来作为基准值。)将这个值设置为 0 表示关 闭自动 AOF 重写。

例子:
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

总结
创建 RDB 文件需要将服务器包含的所有数据全部写入到硬 盘里面,这是一个非常耗费资源和时间的 操作,因此服务器通常需要每隔一段时间才创建一个新的 RDB 文件,这使得服务器在遭遇意外停机 时,可能会 丢失大量数据。
AOF 持久化会将每个修改了数据库的命令都写入到 AOF 文件末尾,在启动服务器的时候,只要重新 执行 AOF 文件包含的命令,就可以还原服务器原有的数据库数据。
因为写入缓冲区的存在,AOF 持久化的安全性取决于缓冲区里面的命令何时会被真正地写入到硬盘 里面,通过设置 appendfsync 配置选项,用户可以让 AOF 持久化不丢失任何已经成功执行的命令数 据,或者只丢失一秒钟内被执行的命令数据,又或者不主动执行 fdatasync 调用,将写入硬盘的时机 交给操作系统来管理。
随着服务器的运行,AOF 文件会产生越来越多冗余命令,使得文件的体 积不断增大,而通过执行 AOF 重写操作,服务器可以创建一个保存相同数据库数据,但不包含任何冗余命令的新 AOF 文件,并使用 这个新 AOF 文件来代替原有的 AOF 文件。

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: