Redis内存快照

Redis内存快照

1. AOF数据恢复存在的问题

  • AOF方法每次执行记录的是操作命令,需要持久化的数据量不大
  • 但是也因为记录的是操作命令,而不是实际数据,所以用AOF方法进行故障恢复的时候,需要逐一把操作日志都执行一遍
    • 如果操作日志很多,Redis的恢复就会很缓慢,可能影响到正常

2. 内存快照Overview

  • 内存快照可以解决上述的问题

    • 内存快照指的是记录下内存中的数据在某一时刻的状态
    • 将某一时刻的状态以文件的形式写到磁盘上 这样即使宕机,快照文件也不会丢失,数据的可靠性也就有了保证
    • 快照文件成为RDB文件,RDB — Redis DataBase
  • RDB特征

    • 记录的是某一个时刻的数据,并不是操作
    • 因此在数据恢复的时候,我们可以将RDB文件直接读入内存,很快完成恢复

2.1 给哪些数据做快照?

  • Redis的数据都在内存当中,为了提供所有数据的可靠性保证,其执行的是全量快照
    • 即将内存中的所有数据都记录到磁盘当中
    • 与之一起来的问题就是,当需要对内存的全量数据做快照的时候,将其全部写入磁盘会花费很多时间
    • 而且全量数据越多,RDB文件就越大,往磁盘上写数据的时间开销就越大
    • 而Redis的单线程模型决定了我们要尽量避免阻塞主线程的操作
  • Redis生成RDB文件的命令
    • save
      • 在主线程中执行,会导致阻塞
    • bgsave
      • 创建一个子进程,专门用于写入RDB文件,可以避免对于主线程的阻塞

2.2 做快照的时候数据是否能够被增删改?

  • 我们需要使系统在进行快照的时候仍然能够接受修改请求,要不然会严重影响系统的执行效率

  • Redis会借助操作系统提供的写时复制技术 — copy on write,在执行快照的同时,正常处理写操作

    • copy on write

      • copy operation is deferred until the first write,

      • could significantly reduce the resource consumption of unmodified copies, while adding a small overhead to resource-modifying operations

        Copy-on-write

        Copy on Write实现

2.3 多久做一次快照?

  • 尽管bgsave执行时不阻塞主线程,但是频繁的执行全量快照,会带来两方面的开销
    • 磁盘带宽压力
      • 频繁将全量数据写入磁盘,会给磁盘带来很大的压力
      • 多个快照竞争有限的磁盘贷款,前一个快照还没有做完,后一个又开始做了,容易造成恶性循环
    • fork操作的阻塞
      • bgsave子进程需要通过fork操作从主线程创建出来
      • fork创建过程本身会阻塞主线程,而且主线程的内存越大,阻塞时间就越长

3. AOF和RDB混用模式

  • 为什么要混用
    • AOF执行速度会比较慢
    • RDB的全量复制频率难以把控,太低,会容易丢失数据;太高,系统开销会很大
  • 如何实现的
    • RDB以一定的频率来执行
    • 在两次快照之间,使用AOF日志记录这期间所有的命令操作

AOF & RDB Mix

  • 如上图所示,到了第二次做全量快照的时候,就可以清空AOF日志,因为所有的操作都已经保存到了第二次的全量快照当中了

4. 实际场景探究

我们使用一个 2 核 CPU、4GB 内存、500GB 磁盘的云主机运行 Redis,Redis 数据库的数据量大小差不多是 2GB,我们使用了 RDB 做持久化保证。当时 Redis 的运行负载以修改操作为主,写读比例差不多在 8:2 左右,也就是说,如果有 100 个请求,80 个请求执行的是修改操作。你觉得,在这个场景下,用 RDB 做持久化有什么风险吗?

  • 内存资源风险

    • Redis fork子进程做RDB持久化,由于写的比例为80%,那么在持久化过程中,“写实复制”会重新分配整个实例80%的内存副本,大约需要重新分配1.6GB内存空间,这样整个系统的内存使用接近饱和,

    • 如果此时父进程又有大量新key写入,很快机器内存就会被吃光,如果机器开启了Swap机制,那么Redis会有一部分数据被换到磁盘上,当Redis访问这部分在磁盘上的数据时,性能会急剧下降,已经达不到高性能的标准(可以理解为武功被废)。如果机器没有开启Swap,会直接触发OOM,父子进程会面临被系统kill掉的风险。

      • swap 机制

        • 将一块磁盘或者一个本地文件当做内存来使用

          • 换入

            • 当进程再次访问内存的时候,从磁盘读取数据到内存当中
          • 换出

  • CPU资源风险

    • 虽然子进程在做RDB持久化,但生成RDB快照过程会消耗大量的CPU资源,
    • 虽然Redis处理处理请求是单线程的,但Redis Server还有其他线程在后台工作,例如AOF每秒刷盘、异步关闭文件描述符这些操作。
    • 由于机器只有2核CPU,这也就意味着父进程占用了超过一半的CPU资源,此时子进程做RDB持久化,可能会产生CPU竞争,导致的结果就是父进程处理请求延迟增大,子进程生成RDB快照的时间也会变长,整个Redis Server性能下降。

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 stone2paul@gmail.com

文章标题:Redis内存快照

文章字数:1.5k

本文作者:Leilei Chen

发布时间:2021-01-02, 13:27:09

最后更新:2021-01-02, 13:29:47

原始链接:https://www.llchen60.com/Redis%E5%86%85%E5%AD%98%E5%BF%AB%E7%85%A7/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录
×

喜欢就点赞,疼爱就打赏