Redis持久化机制


Redis一共有 2 种持久化方式,RDB(Redis DataBase)和AOF(Append Only File)

在我们安装了redis之后,所有的配置都是在redis.conf文件中,里面保存了RDB和AOF两种持久化机制的各种配置

RDB持久化

RDB是在指定的时间间隔内将内存中的数据以快照的形式保存在磁盘上,是默认的持久化方式,文件名为dump.rdb

既然RDB机制是通过把某个时刻的所有数据生成一个快照来保存,那么就应该有一种触发机制来实现这个过程。

save

该命令会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,直到RDB过程完成为止。

bgsave

执行该命令时不会阻塞服务器进程,因为是通过fork一个子进程,并让其去创建 RDB 文件,而父进程则继续处理命令请求。当写完数据库状态(Redis服务器的非空数据库以及他们键值对的统称)后,新的RDB文件就会原子地替换旧的 RDB 文件。

默认如下配置:
save 900 1: 表示900 秒内如果至少有 1 个 key 的值变化,则保存。
save 300 10:表示300 秒内如果至少有 10 个 key 的值变化,则保存。
save 60 10000:表示60 秒内如果至少有 10000 个 key 的值变化,则保存.
如果不需要持久化,可注释掉所有的 save 行来停用保存功能。

  • stop-writes-on-bgsave-error :默认值为yes。当启用了RDB且最后一次后台保存数据失败,Redis是否停止接收数据。这会让用户意识到数据没有正确持久化到磁盘上,否则没有人会注意到灾难(disaster)发生了。如果Redis重启了,那么又可以重新开始接收数据了
  • rdbcompression ;默认值是yes。对于存储到磁盘中的快照,可以设置是否进行压缩存储。
  • rdbchecksum :默认值是yes。在存储快照后,我们还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。
  • dbfilename :设置快照的文件名,默认是 dump.rdb
  • dir:设置快照文件的存放路径,这个配置项一定是个目录,而不能是文件名。

RDB优点

  • RDB文件紧凑,全量备份,非常适合用于进行备份和灾难恢复。
  • 生成RDB文件的时候,redis主进程会fork一个子进程来处理所有保存工作,主进程不需要进行任何磁盘IO操作。
  • RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。

RDB缺点

  • RDB快照是一次全量备份,存储的是内存数据的二进制序列化形式,存储上非常紧凑。
  • 持久化,子进程会拥有父进程的内存数据,父进程修改内存子进程不会反应出来,所以在快照持久化期间修改的数据不会被保存,可能丢失数据。

AOF

全量备份总是耗时的,有时候我们提供一种更加高效的方式AOF,工作机制很简单,redis会将每一个收到的写命令都通过write函数追加到文件中。通俗的理解就是日志记录。

AOF持久化实现

分为 3 个步骤:命令追加、文件写入、文件同步

命令追加就是将写命令追加到AOF缓冲区的末尾,文件写入是缓冲区内容写到 AOF 文件,文件同步是将 AOF 文件保存到磁盘。

在《Redis设计与实现》中提到,Redis 服务器进程就是一个事件循环,这个循环中的文件事件(socket 的可读可写事件)负责接收客户端的命令请求,以及向客户端发送命令结果。

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

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

  • write:根据条件,将缓冲区内容写入到AOF文件。
  • save:根据条件,调用fsync或fdatasync函数,将AOF文件保存到磁盘中。

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

  • appendfsync always:每执行一个命令保存一次
  • appendfsync everysec(默认且推荐):每一秒钟保存一次
  • appendfsync no:不保存

下面是三个选择的区别:

  • appendfsync always:每次执行完一个命令之后,write和save都会被执行
  • appendfsync everysec:save原则上每隔一秒钟就会执行一次。
  • appendfsync no:每次执行完一个命令之后, write会执行,save都会被忽略,只会在Redis被关闭或AOF功能被关闭时执行

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

AOF重写

通过该功能来创建一个新的AOF文件来代替旧文件,并且两个文件所保存的数据库状态一样,但新文件不会包含任何冗余命令,所以新文件要比旧文件小得多。而为什么新文件不会包含任何冗余命令呢?因为这个重写功能是通过读取服务器当前的数据库状态来实现的。虽然叫做「重写」,但实际上并没有对旧文件进行任何读取修改。

比如旧文件保存了对某个key有5个set 命令,经过重写之后,新文件只会记录最后一次对该key的set命令,因此说新文件不会包含任何冗余命令

因为重写涉及到大量 IO 操作,所以Redis是用子进程来实现这个功能的,否则将会阻塞主进程。该子进程拥有父进程的数据副本,可以避免在使用锁的情况下,保证数据的安全性。

那么这里又会存在一个问题,子进程在重写过程中,服务器还在继续处理命令请求,新命令可能会对数据库进行修改,这会导致当前数据库状态和重写后的 AOF 文件,所保存的数据库状态不一致。

为了解决这个问题,Redis 设置了一个 AOF重写缓冲区。在子进程执行 AOF 重写期间,主进程需要执行以下三个步骤:

  • 执行客户端的请求命令
  • 将执行后的写命令追加到 AOF 缓冲区
  • 将执行后的写命令追加到 AOF 重写缓冲区

当子进程结束重写后,会向主进程发送一个信号,主进程接收到之后会调用信号处理函数执行以下步骤:

  • 将 AOF 重写缓冲区内容写入新的 AOF 文件中,此时新文件所保存的数据库状态就和当前数据库状态一致了
  • 对新文件进行改名,原子地覆盖现有 AOF 文件,完成新旧文件的替换。

当函数执行完成后,主进程就继续处理客户端命令,因此在整个 AOF 重写过程中,只有在执行信号处理函数时才会阻塞主进程,其他时候都不会阻塞。

AOF优点

  • AOF可以更好的保护数据不丢失,一般AOF会每隔1秒,通过一个后台线程执行一次fsync操作,最多丢失1秒钟的数据
  • AOF日志文件没有任何磁盘寻址的开销,写入性能非常高,文件不容易破损。
  • AOF日志文件即使过大的时候,出现后台重写操作,也不会影响客户端的读写。
  • AOF日志文件的命令通过非常可读的方式进行记录,这个特性非常适合做灾难性的误删除的紧急恢复。比如某人不小心用flushall命令清空了所有数据,只要这个时候后台rewrite还没有发生,那么就可以立即拷贝AOF文件,将最后一条flushall命令给删了,然后再将该AOF文件放回去,就可以通过恢复机制,自动恢复所有数据

AOF缺点

  • 对于同一份数据来说,AOF日志文件通常比RDB数据快照文件更大。
  • AOF开启后,写的QPS会比RDB写QPS低,因为AOF一般会配置成每秒fsync一次日志文件,当然,每秒一次fsync,性能也还是很高的。

官方建议

通常,如果想提供很高的数据保障性,那么建议同时使用两种持久化方式。如果可以接受灾难带来的几分钟的数据丢失,那么可以仅使用 RDB。

很多用户仅使用了 AOF,但是建议,既然 RDB 可以时不时的给数据做个完整的快照,并且提供更快的重启,所以最好还是也使用 RDB。

在数据恢复方面:RDB 的启动时间会更短,原因有两个:

  • RDB 文件中每一条数据只有一条记录,不会像 AOF 日志那样可能有一条数据的多次操作记录。所以每条数据只需要写一次就行了。
  • RDB 文件的存储格式和 Redis 数据在内存中的编码格式是一致的,不需要再进行数据编码工作,所以在 CPU 消耗上要远小于 AOF 日志的加载。

注意:上面说了 RDB 快照的持久化,在进行快照的时候save,fork 出来进行 dump 操作的子进程会占用与父进程一样的内存,真正的 copy-on-write对性能的影响和内存的耗用都是比较大的。

比如机器 8G 内存,Redis 已经使用了 6G 内存,这时 save 的话会再生成 6G,变成 12G,大于系统的 8G。这时候会发生交换;要是虚拟内存不够则会崩溃,导致数据丢失。所以在用 redis 的时候一定对系统内存做好容量规划。

目前,通常的设计思路是利用复制(Replication)机制来弥补 aof、snapshot 性能上的不足,达到了数据可持久化。即 Master 上 Snapshot 和 AOF 都不做,来保证 Master 的写性能,而 Slave 上则同时开启 Snapshot 和 AOF 来进行持久化,保证数据的安全性。

参考
https://mp.weixin.qq.com/s?__biz=MzUxNTAzMTM4OA==&mid=2247483841&idx=1&sn=f1635e04fb271c4047fe7a8560208fde&chksm=f9bda9f2ceca20e4c898e48b1dba2c580bae269e142950061e53e773c83d1637e794549dfb4a&scene=21#wechat_redirect

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值