1. 持久化

所谓持久化是指将数据从内存中以某种形式同步到硬盘中,在 Redis 重启后能够根据硬盘中的记录恢复数据。Redis 持久化有两种方式,分别为 RDB(redis data base) 【快照】方式 和 AOF(append only file ) 【日志】方式。

Redis 的持久化机制有两种,分别为:

  • 快照 RDB,快照是一次全量备份,是内存数据的二进制序列化形式,在存储上非常紧凑;
  • 日志 AOF,日志是连续的增量备份,日志记录的是内存数据修改的指令记录文本;

AOF 日志在长期的运行过程中会变的无比庞大,数据库重启时需要加载 AOF 日志进行指令重放,这个时间就会无比漫长。所以需要定期进行 AOF 重写,给 AOF 日志进行瘦身。

两者区别:

  • RDB 持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是 fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。

  • AOF 持久化以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录。

2. RDB

2.1 RDB 【快照】方式

RDB 持久化是 Redis 的默认支持,无需进行配置。RDB 是指在指定的时间间隔内将内存中的数据集快照写入磁盘。当符合一定规则时,Redis 自动将内存中的所有数据生成一份副本并存储到硬盘上。分为以下四种情况:

  1. 根据配置规则自动进行快照

    SAVE  900 1
    SAVE  300 10
    SAVE  60  1000
    

    SAVE 900 1 表示 900s 内有一个或一个以上的键被更改则进行快照配置文件中。

  2. 用户执行 SAVEBGSAVE 命令

    (1) SAVE 命令

    Redis 会同步的进行快照操作,在快照执行过程中会阻塞所有来自客户端请求。

    (2) BGSAVE 命令

    Redis 会在后台异步地进行快照操作,在快照执行过程服务端可以继续响应来自客户端的请求。具体操作是 Redis 进程执行 fork 操作创建子进程,RDB 持久化过程由子进程负责,完成后自动结束。阻塞只发生在 fork 阶段,一般时间很短。建议使用。

  3. 执行 FLUSHALL 命令

    只要快照配置条件不为空,执行该命令时就会执行一次快照操作;而当没有定义快照条件时,即使执行该命令也不会执行快照操作。

  4. 执行复制 replication

    即使没有定义自动快照条件,且没有手动执行过快照操作,进行复制操作时也会进行自动快照。

2.2 RDB 【快照】原理

RedisRDB 持久化时会调用 glibc 的函数 fork 产生一个子进程,快照持久化完全交给子进程来处理,父进程继续处理客户端请求。子进程刚刚产生时,它和父进程共享内存里面的代码段和数据段。这是 Linux 操作系统的机制,为了节约内存资源,所以尽可能让它们共享起来。在进程分离的一瞬间,内存的增长几乎没有明显变化。

Python 语言描述进程分离的逻辑如下。fork 函数会在父子进程同时返回,在父进程里返回子进程的 pid,在子进程里返回零。如果操作系统内存资源不足,pid 就会是负数,表示 fork 失败。

pid = os.fork()
if pid > 0:handle_client_requests()  # 父进程继续处理客户端请求
if pid == 0:handle_snapshot_write()  # 子进程处理快照写磁盘
if pid < 0:# fork error

子进程做数据持久化,它不会修改现有的内存数据结构,它只是对数据结构进行遍历读取,并且保存过时的数据,然后序列化写到磁盘中。但是父进程不一样,它必须持续服务客户端请求,然后对内存数据结构进行不间断的修改。

这个时候就会使用操作系统的 COW(Copy On Write) 机制来进行数据段页面的分离。数据段是由很多操作系统的页面组合而成,当父进程对其中一个页面的数据进行修改时,会将被共享的页面复制一份分离出来,然后对这个复制的页面进行修改。这时子进程相应的页面是没有变化的,还是进程产生时那一瞬间的数据。

随着父进程修改操作的持续进行,越来越多的共享页面被分离出来,内存就会持续增长。但是也不会超过原有数据内存的 2 倍大小。另外一个 Redis 实例里冷数据占的比例往往是比较高的,所以很少会出现所有的页面都会被分离,被分离的往往只有其中一部分页面。每个页面的大小只有 4K,一个 Redis 实例里面一般都会有成千上万的页面。

子进程因为数据没有变化,它能看到的内存里的数据在进程产生的一瞬间就凝固了,再也不会改变,这也是为什么 Redis 的持久化叫「快照」的原因。接下来子进程就可以非常安心的遍历数据了进行序列化写磁盘了。

3. AOF

3.1 AOF 【日志】方式

该机制将以日志的形式记录服务器所处理的每一个写操作,在 Redis 服务器启动之初会读取该文件来重新构建数据库,以保证启动后数据库中的数据是完整的。

  1. 默认关闭,通过 appendonly yes 可开启
  2. 开启后,每执行一条更改数据库中的命令时,Redis 都会将该命令写入硬盘的 AOF 文件
  3. 达到一定条件时,Redis 会自动重写 AOF 文件
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
  1. 启动时 Redis 会逐个执行 AOF 文件中的命令将硬盘中的数据载入到内存中
  2. appendfsync everysec 通过配置文件中的该配置项,可使硬盘缓存中的数据每 1s 同步一次到真正的硬盘中

3.2 AOF 【日志】原理

事实上由于操作系统缓存机制,数据并没有真正写入硬盘,而是进入系统硬盘缓存。AOF 日志是以文件的形式存在的,当程序对 AOF 日志文件进行写操作时,实际上是将内容写到了内核为文件描述符分配的一个内存缓存中,然后内核会异步将脏数据刷回到磁盘的。

这就意味着如果机器突然宕机,AOF 日志内容可能还没有来得及完全刷到磁盘中,这个时候就会出现日志丢失。那该怎么办?

Linuxglibc 提供了 fsync(int fd) 函数可以将指定文件的内容强制从内核缓存刷到磁盘。只要 Redis 进程实时调用 fsync 函数就可以保证 aof 日志不丢失。但是 fsync 是一个磁盘 IO 操作,它很慢!如果 Redis 执行一条指令就要 fsync 一次,那么 Redis 高性能的地位就不保了。

所以在生产环境的服务器中,Redis 通常是每隔 1s 左右执行一次 fsync 操作,周期 1s 是可以配置的。这是在数据安全性和性能之间做了一个折中,在保持高性能的同时,尽可能使得数据少丢失。

Redis 提供了 bgrewriteaof 指令用于对 AOF 日志进行瘦身。其原理就是开辟一个子进程对内存进行遍历转换成一系列 Redis 的操作指令,序列化到一个新的 AOF 日志文件中。序列化完毕后再将操作期间发生的增量 AOF 日志追加到这个新的 AOF 日志文件中,追加完毕后就立即替代旧的 AOF 日志文件了,瘦身工作就完成了。

4. 数据恢复

4.1 RDB 方式

RDB 方式的持久化的数据恢复不需太多操作,只要将备份文件放入 Redis 的安装目录,启动即可。Redis 会自动加载文件至内存。在加载过程中会一直处于阻塞状态。

优点:

  • 整个数据库只包含一个备份文件。容易恢复和存储。
  • 方便复制和转移。
  • 相比于 AOF,数据集很大的情况下,RDB 的启动效率更高。
  • 性能最大化。对于 Redis 的服务进程而言,在开始持久化时,它唯一需要做的只是 fork 出子进程,之后再由子进程完成这些持久化的工作,这样就可以极大的避免服务进程执行操作。

缺点:

  • 如果想最大限度避免数据丢失,RDB 不是一个好选择,如果系统在持久化期间出现宕机,没有写入磁盘的数据都会丢失。
  • RDB 通过 fork 子进程来协助完成持久化,如果数据集较大,会导致服务器停止一些时间。

4.2 AOF 方式

RDB 一样,重启 RedisRedis 会自动加载 AOF 文件,实现数据恢复。

优点:

  • AOF 的数据安全性和同步性比 RDB 形式高。默认为每秒同步一次,如果设置为每操作同步一次,则数据会实现完全同步。
  • AOF 文件是通过追加的形式生成的。如果最后一次写入出现异常也不会影响之前的文件数据。
  • AOF 文件具有清晰可读的文件格式,如果我们错误的写入了命令,可以立马关闭,在重写没进行时,先进入文件中,去掉写错的命令。

缺点:

  • AOF 占用的空间比 RDB 大。
  • AOF 的同步速度比 RDB 慢。

5 混合持久化

重启 Redis 时,我们很少使用 rdb 来恢复内存状态,因为会丢失数据,因为 rdb 不是实时存储数据的。我们通常使用 AOF 日志重放,但是重放 AOF 日志性能相对 rdb 来说要慢很多,这样在 Redis 实例很大的情况下,启动需要花费很长的时间。

Redis 4.0 为了解决这个问题,带来了一个新的持久化选项——混合持久化。将 rdb 文件的内容和增量的 AOF 日志文件存在一起。这里的 AOF 日志不再是全量的日志,而是自持久化开始到持久化结束的这段时间发生的增量 AOF 日志,通常这部分 AOF 日志很小。

于是在 Redis 重启的时候,可以先加载 rdb 的内容,然后再重放增量 AOF 日志就可以完全替代之前的 AOF 全量文件重放,重启效率因此大幅得到提升。

6. 如何选择

如果对数据的完整性要求不是极高,可以丢失一点数据,那选择 RDB 是最好的。RDB 无论是备份方便性和恢复速度都高于 AOF,同时可以避免 AOF 的一些 bug。

如果对数据的完整性要求极高,请选择 AOF 形式。


参考:
https://juejin.cn/book/6844733724618129422/section/6844733724714614797

Redis 笔记(14)— 持久化及数据恢复(数据持久方式 RDB 和 AOF、数据恢复、混合持久化)相关推荐

  1. linux 关闭redis 命令_面试必问的 Redis:RDB、AOF、混合持久化

    前言 本来说 Redis 分3篇,但是上周写持久化时发现持久化的内容还越多的,于是持久化就单拆一篇了. 我估计后面的主从复制.哨兵.集群内容也是不少,所以说实话,我也不知道之前说的3篇会拆成几篇了 持 ...

  2. redis的持久化方式RDB和AOF的区别

    https://blog.csdn.net/m0_38110132/article/details/76906422 博客 学院 下载 图文课 论坛 APP 问答 商城 VIP会员 活动 招聘 ITe ...

  3. quartz持久化是指_面试必问:Redis 持久化是如何做的?RDB 和 AOF 对比分析

    从这篇文章开始,我们来介绍Redis高可用相关的机制.Redis要想实现高可用,主要有以下方面来保证: 数据持久化 主从复制 自动故障恢复 集群化 这篇文章我们先介绍Redis的高可用保障的基础:数据 ...

  4. Redis持久化策略——RDB、AOF、混合

    一.RDB(redis database) Redis默认启用该模式进行持久化,自动RDB使用的是异步方式(开启子进程)生成全量快照,配置文件为 redis.conf ①配置项:dbfilename ...

  5. Redis主从复制的搭建与.哨兵.数据持久

    目录 一.redis主从复制 1.主从复制的概述 2.一主一从结构的配置 二.哨兵服务 1. 哨兵服务的简单介绍 2.配置哨兵服务 三.数据持久化 1.RedisDataBase(RDB) 2.App ...

  6. Redis学习总结(21)——Redis持久化是如何做的?RDB和AOF对比分析

    前言 Redis要想实现高可用,主要有以下方面来保证: 数据持久化 主从复制 自动故障恢复 集群化 Redis的高可用保障的基础:数据持久化.因为Redis的主从复制和自动故障恢复,都需要依赖Redi ...

  7. radis的两种持久化方式RDB、AOF

    redis的两种持久化方式 持久化:把内存中的数据库保存到磁盘上.防止数据的丢失. redis支持的持久化方式两种: RDB:通过快照完成的,当符合一定条件时redis会自动将内存中的数据进行快照,并 ...

  8. SQL 必知必会·笔记14更新和删除数据

    1. 更新数据 基本的UPDATE语句,由三部分组成: 要更新的表 列名和它们的新值 确定要更新那些行的过滤条件 更新单列示例: 1 UPDATE Customers 2 SET cust_email ...

  9. Redis架构第二天:CenterOS集群、RDB和AOF、主从复制架构实践

    1.课程 小型电商:页面静态化 页面太多的时候,上亿,重新渲染,需要几天,不太靠谱 大型电商:异步+多级缓存+nginx本地化动态渲染 高并发.高可用,qps 总之一句话redis很重要.龙国学院很屌 ...

最新文章

  1. Java9新功能之HTTP2和REPL
  2. JavaScript基础事件(6)
  3. Ch5702-Count The Repetitions【字符串,倍增,dp】
  4. java uuid 线程安全_java – 在多线程应用程序中生成相同的UUID
  5. iReport与JasperReport简介
  6. [独库骑行之奇山异石]丹霞地貌和雅丹地貌
  7. 太火了,这些牛逼的Java代码技巧,肯定能让你目瞪口呆!
  8. sql server数据库中 smallint, int ,bigint ,tinyint的区别与长度
  9. 蓝桥杯_算法训练_未名湖畔的烦恼
  10. iphonex 序列号_X的序列号什么开头有什么意思吗?
  11. Recover a secret string from random triplets
  12. VM虚拟机安装CentOS7添加硬盘扩展存储空间的方法
  13. 嵌入式RTSP转RTMP设备说明
  14. python中画折线图不同颜色的两段_matplotlib绘制精美的折线图——另附颜色、形状查找表...
  15. Spring Boot整合Redis缓存(Lettuce)
  16. div高度、宽度100%|div width、height 100% - div100%
  17. 中国铜行业市场消费量调研及投资潜力预测分析报告2022-2027年
  18. 【刷题日记】网易——瞌睡
  19. Logstash~filter.kv插件使用教程(附带示例)
  20. 超详细解读OSPF Router-ID

热门文章

  1. 伦理困境:人工智能浪潮与“AI威胁论”之争
  2. 2022-2028年中国PET薄膜行业市场深度分析及未来趋势预测报告
  3. Redis 笔记(08)— 事务(一次执行多条命令、命令 watch/multi/exec/discard、错误处理)
  4. tensor和模型 保存与加载 PyTorch
  5. Java并发编程之CountDownLatch、CyclicBarrier和Semaphore
  6. 堆叠式传感器架构带来先进的视觉功能
  7. 如何构建虚拟护士应用程序?
  8. Android的数据存储方式
  9. 客快物流大数据项目(二十五):初始化业务数据
  10. 客快物流大数据项目(四):大数据项目为什么使用Docker