【专栏】基础篇05| Redis 该怎么保证数据不丢失(下)

前言

    上一小节我们讲了AOF是什么以及它是如何保证Redis的Crash Safe的,这一节我们再来看一看Redis的RDB和AOF有何不同,两者是怎么样的关系

RDB的工作模式

    RDB全称Redis Database,我们也常叫做Redis的内存快,它与AOF最大的不同在于AOF记录的是Redis具体执行的命令,而RDB存储的是数据本身,这样在数据恢复时只需要将备份的rdb文件覆盖原文件就行了,避免了AOF重放命令的繁琐与开销。

    内存快照我们在Mysql中也有体现,Innodb为了保证事务实现了多版本并发控制,也就是MVCC,而事务的不同隔离级别影响着select可以“看到”的数据范围,因此undo log利用innodb中最新的事务id和最老的事务id形成了一个高低水位,组成一行数据的“快照”。但是innodb的快照只是服务与事务,因此不需要真正的把每一行数据本身放进快照中,但是RDB不一样,这是实打实的快照,从内存到磁盘文件的一个快照,因此我们首先想到的问题是会不会太重了?

    Redis进行RDB有两种方式:save和bgsave,save会在主进程中执行,而bgsave则会由主进程创建子进程进行快照。在前面AOF重写的时候我们说过,主进程fork会产生的额外的开销,其中就是页表所在的进程数据结构需要复制到子进程内存空间最为耗时,因此bgsave的好处在于不会在快照时阻塞主进程,但是fork时会额外开销;save则会全程影响主进程,因此bgsave是Redis的默认配置,它在Redis配置文件中如下:

在m时间内有n条数据改变了就进行快照,结合了时间与空间的一个配置。所以回过头来看,RDB确实是一个很重的操作,那么这个快照执行过程中的新数据怎么处理呢?

    和AOF重写一样,Linux下fork出子进程进行RDB也会有Copy On Write优化写入性能(参考:【专栏】基础篇04| Redis 该怎么保证数据不丢失(上)),RDB快照时也会有AOF重写一样的问题,也就是新数据如何处理?而两者的解决方案也是相同的,通过COW形成副本机制,新的数据会以副本的形式存在,而子进程会把原数据备份而不是备份最新的副本,这也是快照的“不变性”。

对比AOF与RDB

    AOF在两者之间更符合”日志“的角色,优点在于它是增量的,并且是顺序写入有更高的IO性能;另外AOF的配置更加灵活,可以保证强一致性,也可以牺牲一致性保证性能。缺点在于由于记录的是过程而不是数据结果,所以用于数据恢复或者数据迁移的过程比较长;另外每秒同步的开销也是很大的,加上重写的开销,AOF并不会低于RDB。

    而RDB的缺点在于它是一个全量备份的过程,因此每一次都是一次不小的开销,这个开销除了在主线程的fork,还有一个就是副本的内存占用,这个点其实是容易忽略的,如果在写入非常频繁的场景下,两次RDB之间由于COW产生的副本是实实在在的内存开销,在这个过程中会存在两份数据导致内存上涨,如果有Swap机制那么内存不够时就会被置换到磁盘中,如果没有则会直接OOM;另外对于数据一致性要求很高的场景,RDB并不适合,因为在两次RDB之间宕机会造成数据的丢失,出于性能的考虑,往往RDB的执行的频率不会像AOF一样每秒执行。而RDB的优点也很明显,由于它高度紧凑的数据存储方式,以及它存储的是面向数据本身的,所以它适合快速恢复数实例数据,适应容灾场景。

AOF与RDB的结合

    在Redis4中提出了AOF与RDB结合的方式,由于AOF本身是增量的,而RDB又是全量的,因此增量+全量可以结合两者的优点。结合以后AOF只需要记录两次RDB之间的记录即可,下一次RDB就会把快照重新记录下来。这样一来,数据恢复时可以先替换rdb文件然后重放aof文件可以达到秒级别数据一致性,也避免了大量AOF的重放操作。

    Redis5后默认开启了混合模式,具体的工作模式还是围绕我们上一节的AOF重写来实现,当触发重写时Redis会将内存数据以rdb的形式写入aof文件的开头,由于AOF重写时新来的操作是会在重写缓冲区的因此缓冲区的命令就是两次RDB之间的增量数据,混合模式的开关在配置文件中如下:

不知道大家还记不记得上一节我们手动执行bgrewriteaof触发重写后的AOF日志,我们再贴一下:

开头就有preamble,可见默认就开启了混合模式。

小结

    这一小节我们大致讲解了一下Redis中数据持久化的另一种方式:RDB,对比了AOF和RDB我们更加清楚了两者的不同,也明白了混合模式的工作方式,是如何将两者结合实现效益最大化的。

    Redis的数据可靠性保证我们就告一段落,这样看Redis在单机下既有了花样的数据结构保证了存储的多样性,也有了AOF和RDB保证了作为一个数据库的Crash Safe,而我们知道Redis属于键值数据库,键值数据库与传统关系型数据库最大的不同就是去关系,这也是NoSql数据库的最大特征,这也为分布式数据库做了铺垫,Redis作为分布式键值数据库,集群模式才是工业王牌,所以我们需要了解Redis是如何提供分布式服务的以及如何处理分布式系统的问题的,下期见~

Redis专栏合集

【专栏】01| Redis夜的第一章

【专栏】基础篇02| Redis 旁路缓存的价值

【专栏】基础篇03| Redis 花样的数据结构

【专栏】基础篇04| Redis 该怎么保证数据不丢失(上)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值