Redis 持久化机制

前文

redis 下载安装

redis 的简单使用

SpringBoot 整合 Redis 的简单使用

Redis 数据结构详解

Redis 基本的事务操作与乐观锁实现


Redis 是内存数据库,如果不将内存中的数据库状态保存到磁盘,那么一旦服务器进程退出,服务器中的数据库状态也会消失,所以 Redis 提供了持久化功能

    很多时候我们需要持久化数据也就是将内存中的数据写入到硬盘里面,大部分原因是为了之后重用数据(比如重启机器,机器故障之后恢复数据),或者是为了防止系统故障而将数据备份到一个远程位置

    Redis 支持持久化,而且支持两种不同的持久化操作。Redis 的一种持久化方式叫做快照(Snapshotting,RDB),另一种方式是只追加文件(Append-Only-File,AOF)。这两种方式各有千秋

RDB(Redis DataBase)

什么是 RDB?

    在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的 Snapshot 快照,它恢复时是将快照文件直接读到内存里

    Redis 可以通过创建快照来获得存储在内存里面的数据在某个时间点上的副本。Redis 创建快照之后,可以对快照进行备份,可以将快照复制到其它服务器从而创建具有相同数据的服务器副本(Redis 主从结构,主要用来提高 Redis 性能),还可以将快照留在原地以便重启服务器的时候使用

    Redis 会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何的 IO 操作,这就确保了极高的性能,如果需要进行大规模数据的恢复,且对于数据恢复的完成性不是非常敏感,那么 RDB 方式比 AOF 方式更加高效。RDB 的缺点是最后一次持久化后的数据可能丢失
在这里插入图片描述

有时候在生产环境我们会将这个文件进行备份

RDB 保存的是 dump.rdb 文件 都是在我们的 redis.conf 配置文件中进行配置的

Fork

    Fork 的作用是复制一个与当前进程一样的进程。新进程的所有数据(变量、环境变量、程序计数器等)数值都和原进程一直,但是是一个全新的进程,并作为原进程的子进程

触发机制

1、save 的规则满足的情况下,会自动触发 RDB 规则
2、执行 flushall 命令,也会触发我们的 RDB 规则
3、退出 redis,也会产生 rdb 文件

备份就自动生成一个 dump.rdb 文件
在这里插入图片描述

如何恢复 RDB 文件?

1、只需要将 RDB 文件放在我们的 redis 启动目录下就可以了,redis 在启动的时候会自动检查 dump.rdb 文件,恢复其中的数据
2、查看需要存在的位置

127.0.0.1:6379> config get dir
1) "dir"
2) "/usr/local/bin"    // 如果在这个目录下存在 dump.rdb 文件,启动就会自动恢复其中的数据

优点

  • 适合大规模的数据恢复!dump.rdb
  • 对数据完整性要求不高

缺点

  • 需要一定的时间间隔进行操作,如果 redis 意外宕机了,这个最后一次修改数据就没有了
  • fork 进程的时候,会占用一定的内容空间

AOF(Append Only File)

什么是 AOF?

将我们的所有命令都记录下来,history,恢复的时候就把这个文件全部再执行一遍
在这里插入图片描述

    以日志的形式来记录每个写操作,将 Redis 执行过的所有指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis 启动之初会读取该文件重新构建数据,换言之,redis 重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作

AOF 保存的是 appendonly.aof 文件

APPEND ONLY MODE

在这里插入图片描述
    默认是不开启的,我们需要手动进行配置!我们只需要将 appendonly 改为 yes 即可开启 AOF,重启 redis 就可以生效了

如果这个 AOF 文件有错误,这时候 redis 是启动不起来的,我们需要修复这个文件

redis 给我们提供了一个工具 redis-check-aof --fix

appendonly no   # 默认是不开启 aof 模式的,默认是使用 rdb 方式持久化的,在大部分所有的情况下,rdb 完全够用了  
appendonlyfilename "appendonly.aof"   # 持久化的文件名

# appendonly always    # 每次修改都会 sync,消耗性能
appendfsync everysec   # 每秒执行一次 sync,可能会丢失这 1s 数据
# appendfsync no       # 不执行 sync,这个时候操作系统自己同步数据,速度最快

重写规则说明

aof 默认就是文件的无限追加,文件会越来越大

# rewrite   # 重写

如果 aof 文件大于 64M,太大了,fork 一个新的进程来将我们的文件进行重写

优点

  • 每一次修改都同步,文件的完整性会更加好
  • 每秒会同步一次,可能会丢失一秒的数据
  • 从不同步,效率最高的

缺点

  • 相对于数据文件来说, aof 远远大于 rdb,修复的速度也比 rdb 慢
  • aof 运行效率也要比 rdb 慢,所以 redis 默认的配置就是 rdb 持久化

扩展

1、RDB 持久化方式能够在指定的时间间隔内对你的数据进行快照存储

2、AOF 持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF 命令以 Redis 协议追加保存每次写的操作文件末尾,Redis 还能对 AOF 文件进行后台重写,使得 AOF 文件的体积不至于过大

3、只做缓存,如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化

4、同时开启两种持久化方式

  • 在这种情况下,当 redis 重启的时候会优先载入 AOF 文件来恢复原始的数据,因为在通常情况下 AOF 文件保存的数据集要比 RDB 文件保存的数据集要完整
  • RDB 的数据不实时,同时使用两者时服务器重启也只会找 AOF 文件,那要不要只用 AOF 呢?建议不要这样做,因为 RDB 更适合用于备份数据库(AOF 在不断变化不好备份),快速重启,而且不会有 AOF 可能潜在的 bug,留着作为一个万一的手段

5、性能建议

  • 因为 RDB 文件只用作后备用途,建议只在 Slave 上持久化 RDB 文件,而且只要 15 分钟备份一次就够了,只保留 save 900 1 这条规则
  • 如果 Enable AOF,好处是在最恶劣的情况下也只会丢失不超过两秒的数据,启动脚本较简单只 load 自己的 AOF 文件就可以了,代价一是带来了持续的 IO,二是 AOF rewrite 的最后将 rewrite 过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。只要硬盘许可,应该尽量减少 AOF rewrite 的评论,AOF 重写的基础大小默认值是 64M 打消了,可以设置到 5G 以上,默认超过原大小 100% 大小重写可以改到适当的数值
  • 如果不 Enable AOF,仅靠 Master-Slave Repllcation 实现高可用性也可以,能省掉一大笔 IO,也减少了 rewrite 时带来的系统波动。代价是如果 Master / Slave 同时倒掉,会丢失十几分钟的数据,启动脚本也要比较两个 Master / Slave 中的 RDB 文件,载入较新的那个,微博就是这种架构

Redis 4.0 对于持久化机制的优化

    Redis 4.0 开始支持 RDB 和 AOF 的混合持久化(默认关闭,可以通过配置项 aof-use-rdb-preamble 开启)

    如果把混合持久化打开,AOF 重写的时候就直接把 RDB 的内容写到 AOF 文件开头。这样做的好处是可以结合 RDB 和 AOF 的优点,快速加载同时避免丢失过多的数据。当然缺点也是有的,AOF 里面的 RDB 部分是压缩格式不再是 AOF 格式,可读性较差

补充内容:AOF 重写

    AOF 重写可以产生一个新的 AOF 文件,这个新的 AOF 文件和原有的 AOF 文件所保存的数据库状态一样,但体积更小

    AOF 重写是一个有歧义的名字,该功能是通过读取数据库中的键值对来实现的,程序无须对现有的 AOF 文件进行任何读入、分析或者写入操作

    在执行 BGREWRITEAOF 命令时,Redis 服务器会维护一个 AOF 重写缓冲区,该缓冲区会在子进程创建新的 AOF 文件期间,记录服务器执行的所有写命令。当子进程完成创建新得 AOF 文件的工作之后,服务器会将重写缓冲区中的所有内容追加到新 AOF 文件的末尾,使得新旧的两个 AOF 文件所保存的数据库状态一致。最后,服务器用新的 AOF 文件替换旧的 AOF 文件,以此来完成 AOF 文件重写操作

©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页