初认redis(2)----redis的持久化RDB和AOF

redis的持久化—RDB

RDB持久化能够在指定的时间间隔对你的数据进行快照存储

RDB配置

#指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合
save "" #停止RDB持久化
save 900 1   #900秒内有1个键被更改
save 300 10  #300秒内有10个键被更改
save 60 10000  #60秒内有10000个键被更改
	
rdbcompression yes  #存储至本地的数据库是否压缩数据,默认为yes,redis采用 LZF 压缩,如果为了节省CPU时间,可以关闭该选项,但是会导致数据库文件变大

dbfilename dump.rdb  #本地数据文件名,默认值为dump.rdb

dir ./  #本地数据文件存放目录

Redis 提供了两个命令来生成 RDB 文件,分别是 save 和 bgsave。

  • save:在主线程中执行,会导致阻塞
  • bgsave:创建一个子线程,专门用于写入RDB文件,避免了主线程的阻塞(默认配置)

RDB的优点

  • RDB是一个紧凑型的文件,它保存了某个时间点的数据集,非常适用于数据集的备份
  • RDB是一个紧凑的单一文件,很方便传送到远程数据中心,非常适用于灾难恢复
  • RDB在保存RDB文件时父进程只需要fork出一个子进程,然后由子进程来处理写操作,父进程不用做其他的IO操作,所以RDB持久化可以最大化redis的性能
  • 与AOF相比,在恢复大的数据集的时候,RDB会更快一些

RDB的缺点

  • RDB保存的数据集不完整,如果redis意外宕机,可能会丢失几分钟的数据
  • RDB需要经常fork子进程来保存数据集到硬盘上,当数据集比较大的时候,fork的过程非常耗时,可能会影响redis在一些毫秒级内不能相应客户端的请求。如果数据集巨大并且CPU性能不大的情况下,这种情况会持续1秒,AOF也需要fork,但是可以调节重写日志文件的频率来提高数据集的耐久度(会占用一部分的空间资源

RDB的工作原理
当 Redis 需要保存 dump.rdb 文件时, 服务器执行以下操作:

  • Redis 调用forks. 同时拥有父进程和子进程。
  • 子进程将数据集写入到一个临时 RDB 文件中。
  • 当子进程完成对新 RDB 文件的写入时,Redis 用新 RDB 文件替换原来的 RDB 文件,并删除旧的 RDB 文件。
    在这里插入图片描述
    频繁执行全量复制带来的开销:
  • 磁盘压力过大:频繁将全量数据写入磁盘,会对磁盘带来很大的压力,多个快照竞争有限的磁盘带宽,前一个快照还没有做完,后一个又开始做了,容易造成恶性循环。
  • 主线程阻塞:bgsave 子进程需要通过 fork 操作从主线程创建出来。虽然,子进程在创建后不会再阻塞主线程,但是,fork 这个创建过程本身会阻塞主线程,而且主线程的内存越大,阻塞时间越长。如果频繁 fork 出 bgsave 子进程,这就会频繁阻塞主线程了。

增量复制:做了一次全量快照后,后续的快照只对修改的数据进行快照记录,这样可以避免每次全量快照的开销。(在使用元数据信息记住修改的数据时,会额外增加redis的空间开销)
在这里插入图片描述

redis的持久化—AOF

AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操作到文件末尾.Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大

AOF日志的的实现:
AOF日志是"写后"日志,就是说redis先执行命令,把数据写入内存,然后记录日志。AOF里记录的是redis收到的每一条命令,并以文本的形式保存。

日志(AOF)redis使用写后日志的好处:

  • 避免记录错误的命令
  • 不会阻塞当前的写操作
    在这里插入图片描述

AOF配置

appendonly yes  #是否在每次更新操作后进行日志记录,redis在默认情况下是异步的把数据写入磁盘,如果不开启,可能会在断电是导致一段时间内的数据丢失。因为redis本身同步数据文件是按save条件来同步的,所以有的数据会在一段时间内只存在内存中。默认为no

appendfilename appendonly.aof  #更新日志文件名,默认为 appendonly.aof

#写回策略:
#1.no:操作系统控制的写回:每个写命令执行完,只是先把日志写到 AOF 文件的内存缓冲区,由操作系统决定何时将缓冲区内容写回磁盘。(快)  
#2.always:同步写回:每个写命令执行完,立马同步地将日志写回磁盘;(慢,安全)  
#3.everysec:每秒写回:每个写命令执行完,只是先把日志写到 AOF 文件的内存缓冲区,每隔一秒把缓冲区中的内容写入磁盘;(折中,默认值)
appendfsync everysec

no-appendfsync-on-rewrite no

写回策略的特点:
在这里插入图片描述

AOF的优点

  • 使用AOF 会让你的Redis更加耐久: 你可以使用不同的fsync策略:无fsync,每秒fsync,每次写的时候fsync.使用默认的每秒fsync策略,Redis的性能依然很好(fsync是由后台线程进行处理的,主线程会尽力处理客户端请求),一旦出现故障,你最多丢失1秒的数据.
  • AOF文件是一个只进行追加的日志文件,所以不需要写入seek,即使由于某些原因(磁盘空间已满,写的过程中宕机等等)未执行完整的写入命令,你也可以使用redis-check-aof工具修复这些问题.
  • Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写: 重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合。 整个重写操作是绝对安全的,因为 Redis 在创建新 AOF 文件的过程中,会继续将命令追加到现有的 AOF 文件里面,即使重写过程中发生停机,现有的 AOF 文件也不会丢失。 而一旦新 AOF 文件创建完毕,Redis 就会从旧 AOF 文件切换到新 AOF 文件,并开始对新 AOF 文件进行追加操作。
  • AOF 文件有序地保存了对数据库执行的所有写入操作, 这些写入操作以 Redis 协议的格式保存, 因此 AOF 文件的内容非常容易被人读懂, 对文件进行分析(parse)也很轻松。 导出 AOF 文件也非常简单: 举个例子, 如果你不小心执行了 FLUSHALL 命令, 但只要 AOF 文件未被重写, 那么只要停止服务器, 移除 AOF 文件末尾的 FLUSHALL 命令, 并重启 Redis , 就可以将数据集恢复到 FLUSHALL 执行之前的状态。

AOF的缺点

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

AOF的工作原理
AOF 重写和 RDB 创建快照一样

  • Redis 执行 fork() ,现在同时拥有父进程和子进程。
  • 子进程开始将新 AOF 文件的内容写入到临时文件。
  • 对于所有新执行的写入命令,父进程一边将它们累积到一个内存缓存中,一边将这些改动追加到现有 AOF 文件的末尾,这样样即使在重写的中途发生停机,现有的 AOF 文件也还是安全的。
  • 当子进程完成重写工作时,它给父进程发送一个信号,父进程在接收到信号之后,将内存缓存中的所有数据追加到新 AOF 文件的末尾。
    在这里插入图片描述
    AOF文件损坏怎么办?
        程序正在对 AOF 文件进行写入时停机, 造成了 AOF 文件出错, 那么 Redis 在重启时会拒绝载入这个 AOF 文件, 从而确保数据的一致性不会被破坏。当发生这种情况时, 可以用以下方法来修复出错的 AOF 文件:
  • 为现有的AOF文件进行备份操作
  • 直用redis附带的redis-check-aof,对原来的AOF文件进行修复
  • 使用diff -u 对修复后的AOF和原始的AOF备份文,进行比对
  • 重启redis服务器,等待服务器载入修复后的文件,并进行数据备份

AOF文件重写
    因为AOF的运作方式是不断将命令追加到文件末尾,所以随着写入命令的不断增加,文件的体积也会变得越来越大。为了避免这种情况发生,增加了重写机制:
    它可以在不打算服务器客户端的情况下,对AOF文件进行重建,执行 BGREWRITAOF命令,redis将生成一个新的aof文件,这个文件重建当前数据集所需的最少的命令。

#触发机制:Redis会记录上次重写时的AOF文件大小,默认配置时当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发
auto-aof-rewrite-percentage 100  #(一倍)
auto-aof-rewrite-min-size 64mb

为什么AOF重写可以减少日志的大小?
    当我们对一个列表先后做了 6 次修改操作后,列表的最后状态是[“D”, “C”, “N”],此时,只用 LPUSH u:list “N”, “C”, "D"这一条命令就能实现该数据的恢复,这就节省了五条命令的空间。对于被修改过成百上千次的键值对来说,重写能节省的空间当然就更大了。

在这里插入图片描述
AOF非阻塞的重写过程

在这里插入图片描述

AOF 重写也有一个重写日志,为什么它不共享使用 AOF 本身的日志?
(答案来自网友):AOF重写不复用AOF本身的日志,一个原因是父子进程写同一个文件必然会产生竞争问题,控制竞争就意味着会影响父进程的性能。二是如果AOF重写过程中失败了,那么原本的AOF文件相当于被污染了,无法做恢复使用。所以Redis AOF重写一个新文件,重写失败的话,直接删除这个文件就好了,不会对原先的AOF文件产生影响。等重写完成之后,直接替换旧文件即可。

如何选择使用哪种持久化方式?
  • 如果可以接受几分钟以内的数据丢失,可以使用RDB持久化
  • 如果对数据的安全性要求较高,可以同时开启两种持久化功能
  • 如果只用 AOF,优先使用 everysec 的配置选项,因为它在可靠性和性能之间取了一个平衡。

混合使用 AOF 日志和内存快照
配置redis.conf

 aof-use-rdb-preamble yes

好处:

  • 快照不用很频繁地执行,避免了频繁 fork 对主线程的影响
  • AOF 日志也只用记录两次快照间的操作,就不会出现文件过大的情况了,也可以避免重写开销。

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值