Redis学习笔记(11)- Redis的持久化

1、简介

  Redis是一个内存数据库,所以数据全部存在内存中,如何保证Redis在突然宕机后,数据还可以进行恢复,这就需要Redis提供的持久化机制来实现。Redis持久化机制提供了两种方式:一种快照(RDB ),一种AOF日志。下面将分别学习两种持久化机制的相关内容。

2、快照(RDB)

  快照是一种全量的持久化机制,即把当前内存中的全部数据集的快照写入磁盘中,恢复时再将快照文件直接读到内存里。快照时内存数据的二进制序列化形式,在存储上非常紧凑,所以和AOF日志方式相比,这种方法的文件体积更小。
  Redis提供的快照(RDB)机制,提供自动触发(即通过Redis.conf配置)和手动配置(Redis命令)两种方式。下面首先学习自动触发的方式。

2.1、RDB自动触发
  1. save配置
    在这里插入图片描述
    save: 用来配置触发 Redis的 RDB 持久化条件,格式:“save m n”,表示m秒内数据集存在n次修改时,自动触发持久化,本质上和执行了bgsave命令类似。多个save时,满足一个条件即可触发该操作。如果不需要持久化,可以注释掉所有的 save 行或者save “”实现停用。
      如果在后台持久化的过程中,出现错误时,Redis的write操作会报错,用来提醒用户当前持久化出现问题,避免出现灾难性问题。如果后台持久化功能恢复,Redis的write操作就会自动恢复。(其实就是上面截图中的解释)
  2. stop-writes-on-bgsave-error
    在这里插入图片描述
    stop-writes-on-bgsave-error: 默认yes。yes表示启用了RDB且最后一次后台保存数据失败,Redis是否停止write操作。
  3. rdbcompression
    在这里插入图片描述
    rdbcompression: 默认yes。表示使用LZF压缩dump.rdb文件。如果考虑节省CPU资源,可以设置为no,这个时候dump.rdb文件会比较大。
  4. rdbchecksum
    在这里插入图片描述
    rdbchecksum: 默认值是yes。在存储快照后,我们还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。
  5. dbfilename、dir
    在这里插入图片描述
    dbfilename: 快照的文件名,默认是 dump.rdb。
    dir: 快照文件的存放路径,该配置项一定是个目录,而不能是文件名。默认是和当前配置文件保存在同一目录。
2.2、RDB手动触发

  Redis手动触发RDB的命令有两个:save和bgsave。

  1. save命令
      该命令会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,直到RDB过程完成为止。
      一般来说,在生产环境很少执行 SAVE 操作,因为它会阻塞所有客户端,保存数据库的任务通常由 BGSAVE 命令异步地执行。然而,如果负责保存数据的后台子进程不幸出现问题时, SAVE 可以作为保存数据的最后手段来使用。
  2. bgsave命令
      执行该命令时,Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。具体操作是Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。

参考: 《Redis命令参考- -持久化》

2.3、RDB实现原理

  Redis使用操作系统的多进程COW(Copy On Write)机制来实现快照的持久化。Redis在持久化时,会调用函数fork产生一个子进程,快照持久化完全交给子进程进行处理,父进程继续处理客户端请求。子进程刚创建时,子进程和父进程共享内存中的代码和数据。在后续过程中,子进程做数据持久化过程中,不会修改现有数据结构,它只是遍历数据,并序列化到磁盘中,而父进程在处理客户端请求时,会修改数据结构,这个时候就用到了操作系统的多进程COW。
  操作系统的多进程COW, 即写入时复制(Copy-on-write,简称COW),是一种计算机程序设计领域的优化策略。其核心思想是,如果有多个调用者(callers)同时要求相同资源(如内存或磁盘上的数据存储),他们会共同获取相同的指针指向相同的资源,直到某个调用者试图修改资源的内容时,系统才会真正复制一份专用副本(private copy)给该调用者,而其他调用者所见到的最初的资源仍然保持不变。这过程对其他的调用者都是透明的(transparently)。此作法主要的优点是如果调用者没有修改该资源,就不会有副本(private copy)被创建,因此多个调用者只是读取操作时可以共享同一份资源。

参考:《不会产奶的COW(Copy-On-Write)》

3、AOF日志

  AOF持久化机制是一种连续增量备份,AOF日志记录的是内存数据修改的指令记录文本,类似MySQL的binlog。AOF日志,在长时间运行的过程中会变得非常庞大,Redis重启时需要加载AOF日志进行指令重放。

3.1、开启AOF日志的方式

  默认情况下,AOF日志是没有开启的。可以通过修改redis.conf配置文件,进行启用AOF持久化功能。
  首先,修改appendonly参数,设置为yes。
在这里插入图片描述
  Redis默认提供的是RDB持久化方案。该方法可以满足大部分情况,但是可能造成最近写入且未保存到快照中的那些数据丢失。
  AOF持久化提供了另外一种形式的备份。AOF持久化可以根据appendfsync的配置选择进行增量备份命令的策略,Redis默认使用的是每秒记录一次(平衡备份次数和性能)。
  AOF和RDB持久化可以同时使用。如果AOF持久化被启用,Redis会在启动的时候重放AOF文件中记录的命令,因为这个过程相对比较慢,所有需要定期对AOF文件进行重写,用来保证AOF文件比较小。

  其次,修改appendfilename参数,用了设置AOF日志的文件名。
在这里插入图片描述
  最后,配置appendfsync,设置redis多久才将命令持久化到磁盘一次。
在这里插入图片描述

  • appendfsync always:每次有新命令追加到aof文件时就执行一个持久化,非常慢但是安全
  • appendfsync everysec:每秒执行一次持久化,足够快(和使用rdb持久化差不多)并且在故障时只会丢失1秒钟的数据
  • appendfsync no:从不持久化,将数据交给操作系统来处理。redis处理命令速度加快但是不安全。
3.2、AOF日志的重写

  AOF文件里可能有太多“琐碎”指令,所以AOF会定期根据内存的最新数据重新生成AOF文件。AOF触发重写的方式有两种:自动触发(redis.conf配置)和手动触发(命令行触发),下面分别介绍:

  1. 自动触发
    Redis自动触发重新AOF日志的配置,如下所示:
    在这里插入图片描述
    首先,no-appendfsync-on-rewrite参数用来启用自动重写功能。重写操作触发时机,由auto-aof-rewrite-percentage和auto-aof-rewrite-min-size两个参数控制。其中,auto-aof-rewrite-percentage用来设置AOF文件增长比例,指当前AOF文件比上次重写的增长比例达到多少时,触发重写操作;auto-aof-rewrite-min-size则表示AOF文件重写的最小的文件大小,即最开始AOF文件必须要达到这个文件时才触发,后面的每次重写就根据上一次重写完成之后的大小进行触发了,主要用于第一次重写时。

    扫描二维码关注公众号,回复: 9643249 查看本文章
  2. 手动触发
    通过BGREWRITEAOF命令,可以实现手动触发AOF重写操作。执行一个 AOF文件 重写操作。重写会创建一个当前 AOF 文件的体积优化版本。即使 BGREWRITEAOF 执行失败,也不会有任何数据丢失,因为旧的 AOF 文件在 BGREWRITEAOF 成功之前不会被修改。

  重写操作只会在没有其他持久化工作在后台执行时被触发,也就是说:

  • 如果 Redis 的子进程正在执行快照的保存工作,那么 AOF 重写的操作会被预定(scheduled),等到保存工作完成之后再执行 AOF 重写。在这种情况下, BGREWRITEAOF 的返回值仍然是 OK ,但还会加上一条额外的信息,说明 BGREWRITEAOF 要等到保存操作完成之后才能执行。在 Redis 2.6 或以上的版本,可以使用 INFO [section] 命令查看 BGREWRITEAOF 是否被预定。

  • 如果已经有别的 AOF 文件重写在执行,那么 BGREWRITEAOF 返回一个错误,并且这个新的 BGREWRITEAOF 请求也不会被预定到下次执行。

参考: 《Redis命令参考- -持久化》

3.3、AOF日志的恢复

  如果AOF日志功能开启了,每次启动Redis的时候,就会恢复AOF文件,这个时候会涉及到一个参数:aof-load-truncated。如下所示:
在这里插入图片描述
  指Redis在恢复时,会忽略最后一条可能存在问题的指令。默认值yes。即在AOF写入时,可能存在指令写错的问题(突然断电,写了一半),这种情况下,yes会继续,而no会直接恢复失败。

4、RDB和AOF持久化方案的对比

在这里插入图片描述

5、Redis混合持久化

  混合持久化是Redis 4.X之后的一个新特性,其实本质上就是一种RDB&AOF的结合,持久化文件变成了RDB + AOF。首先由RDB定期完成内存快照的备份,然后再由AOF完成两次RDB之间的数据备份。这样就充分了利用了RDB 加载快,备份文件小等特点,也利用了AOF能尽可能不丢数据这个特性(进一步保证了数据一致性),当然了基本上丢失了AOF的可读性。加载过程就是按部分进行加载的,先按照RDB进行加载,然后把AOF命令追加写入就好了。在大多数场景下RDB + AOF的混合持久化模式其实还是很合适的。
在这里插入图片描述

发布了71 篇原创文章 · 获赞 3 · 访问量 5265

猜你喜欢

转载自blog.csdn.net/hou_ge/article/details/104617409
今日推荐