Redis详解持久化机制

小熙前段时间时间写了Redis的存储机制,接着再说下持久化机制吧,参考了其他大佬的精华和自己的理解。

一. 为什么要持久化

  1. redis是非关系型的内存数据库,数据将被存储在内存中,所以Redis服务器进程退出或者运行Redis服务器的计算机停机,Redis服务器中的数据就会丢失。

  2. 为了避免造成数据丢失,所以数据将被持久化到磁盘上(持久化机制),从而避免了数据的丢失,并且能很快的恢复之前的数据。

    Redis提供了两种持久化机制:

     1. AOF持久化
     2. RDB持久化 
    

二. AOF持久化机制

默认情况下AOF机制是关闭的,需要在redis.conf 配置文件中将 appendonly no 调整为 appendonly yes

  1. 流程如图:

    AOF流程图

  2. 大家可能注意到了,小熙画的AOFl持久化流程图后两步为什么不是一步呢,而是分为了:

     第一步:将操作命令追加到 AOF_BUF 缓存区
     第二步:将AOF_buf 缓存区数据同步到 AOF 文件
    

    (1)为什么拆分为两步:

    因为 Redis 是单线程响应,如果每次写入 AOF 命令都直接追加到磁盘上的 AOF 文件中,频繁的追加所造成的 IO 开销,那么Redis 的性能就只能取决于你的机器硬件了,为了解决这一问题,提升 Redis 的响应效率所以就添加了一层 aof_buf 缓存层, 所利用的是操作系统的 cache 技术,这样就能提升Redis 的性能了。但是还有一个引申出来的问题,那就是aof_buf 缓存区数据如何同步到 AOF 文件呢?由谁同步呢?

    (2)aof_buf 缓存区数据怎么样同步到 aof 文件中:

    aof_buf 缓存区数据写入到 aof 文件是由 linux 系统去完成的,由于 Linux 系统调度机制周期比较长,如果系统故障宕机了,意味着一个周期内的数据将全部丢失,这不是我们想要的,所以 Linux 提供了一个 fsync 命令,fsync 是针对单个文件操作(比如这里的 AOF 文件),做强制硬盘同步,fsync 将阻塞直到写入硬盘完成后返回,保证了数据持久化,正是由于有这个命令,所以 redis 提供了配置项让我们自行决定何时进行磁盘同步。

     redis 在 redis.conf 配置文件中提供了appendfsync 的三个配置项:
     # appendfsync always
     # appendfsync everysec
     # appendfsync no
    
     always
     从安全性来说,always是最安全的(丢失数据最少),因为即使出现故障停机,数据库也只会丢失一个事件循环中所产生的命令数据。
     从效率来说,always的效率最慢,因为服务器在每个事件循环都要将AOF缓冲区中的所有内容写入到AOF文件,并且同步AOF文件。
     
     everysec(默认配置)
     从安全性来说,everysec模式下,即使出现故障停机,数据库只会丢失一秒钟的命令数据。
     从效率来说,everysec模式足够快,因为服务器在每个事件循环都要将AOF缓冲区中的所有内容写入到AOF文件,并且每隔一秒就要在子线程中对AOF文件进行同步。
     
     no
     从安全性来说,no模式下,如果出现故障停机,数据库会丢失上次同步AOF文件之后的所有写命令数据,具有不确定性,因为服务器在每个事件循环都要将AOF缓冲区中的所有内容写入到AOF文件,至于何时对AOF文件进行同步,则由操作系统控制。
     从效率来说,no模式和everysec模式的效率差不多。
    

从以讲述中,会发现一个问题那就是AOF都是追加的,那么肯定会有文件体积过大,运行效率下降,所以Redis引入了重写机制来解决AOF文件过大问题。

  1. AOF的重写:

    AOF文件的重写并不需要对现有的AOF文件进行任何读取、分析或者写入操作,而是通过读取服务器当前的数据库数据来实现的。从数据库中读取键现在的值,然后用一条命令去记录键值对,代替之前记录这个键值对的多条命令。(小熙这里不过多赘述了,有兴趣可以查看下原理)

三. RDB持久化机制

默认情况下,RDB是开启的,快照方式存储,并且Redis提供了两种持久化方式:手动触发自动触发

  1. 手动触发:

    (1)SAVE命令:会阻塞Redis服务器进程,直到RDB文件创建完毕为止,在服务器进程阻塞期间,服务器不能处理任何命令请求,所以线上环境不建议使用

    (2)BGSAVE命令:Redis 主进程会派生出一个子进程,RDB 快照是由子进程来生成的,完成之后,子进程自动结束,服务器进程(父进程)只会在派生子进程的时候短暂的阻塞,这个过程是非常短的,之后服务器进程(父进程)继续处理命令请求,所以推荐使用该命令来手动触发

  2. 自动触发:

    (1)在配置中配置了 save 相关配置信息,比如在配置文件中配置 save 60 15000 ,也可以把它归类为“save m n”格式的配置,表示 m 秒内数据集存在 n 次修改时,会自动触发 bgsave。

    (2)在主从情况下,如果从节点执行全量复制操作,主节点自动执行 bgsave 生成 RDB 文件并发送给从节点

    (3)执行 debug reload 命令重新加载 Redis 时,也会自动触发 save 操作

    (4)默认情况下执行 shutdown 命令时,如果没有开启 AOF 持久化功能则自动执行 bgsave

  3. 优点:

    (1)RDB 快照是某一时刻 Redis 节点内存数据,非常适合做备份,上传到远程服务器或者文件系统中,用于容灾备份

    (2)数据恢复时 RDB 要远远快于 AOF

  4. 缺点:

    (1)RDB 持久化方式数据没办法做到实时持久化/秒级持久化。我们已经知道了 bgsave 命令每次运行都要执行 fork (派生)操作创建子进程,属于重量级操作,频繁执行成本过高。

    (2)RDB 文件使用特定二进制格式保存,Redis 版本演进过程中有多个格式 的 RDB 版本,存在老版本 Redis 服务无法兼容新版 RDB 格式的问题

四. AOF和RDB的区别:

  1. 持久化的方式:

    (1)RDB持久化是通过将某个时间点,Redis服务器存储的数据快照方式,保存到RDB文件中来实现持久化的。

    (2)AOF持久化是通过将Redis服务器执行的所有写命令保存到AOF文件中来实现持久化的。

  2. 安全性:

    (1)AOF持久化的安全性要比RDB持久化的安全性高,即如果发生机器故障,AOF持久化要比RDB持久化丢失的数据要少。

    (2)因为RDB持久化会丢失上次RDB持久化后写入的数据,而AOF持久化最多丢失1s之内写入的数据(使用默认everysec配置的话)。

  3. 文件大小:

    上面已经讲述RDB持久化记录的是结果的快照,而AOF持久化记录的是过程,所以AOF持久化生成的AOF文件会有体积越来越大的问题,所以Redis提供了AOF重写功能来减小AOF文件体积从而提高效率。

  4. 优先级:

    在安全性中的比较可以看AOF是别RDB高的,所以如果Redis服务器开启了AOF持久化功能,Redis服务器在启动时会使用AOF文件来还原数据,如果Redis服务器没有开启AOF持久化功能,Redis服务器在启动时会使用RDB文件来还原数据,所以AOF文件的优先级比RDB文件的优先级高。

    如果AOF和RDB(都存在或者存在其一)都加载失败,那么Redis服务启动会失败,即持久化数据恢复失败。

以上就是小熙的浅谈了,如果感兴趣可以自行搜索相关内容。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值