拿个offer - 开源&项目实战 拿个offer - 开源&项目实战
首页
后端技术
🚀大话面试
  • 校&社招实战项目

    • 12306(铁路购票平台)
    • 短链接(Sass平台)
  • 社招进阶项目

    • 刚果商城(DDD领域驱动)
  • 基础架构项目

    • 幂等基础组件(支持接口及多种MQ)
    • 企业基础架构组件库
  • 校&社招实战项目

    • 12306(铁路购票平台) (opens new window)
    • 短链接(Sass平台) (opens new window)
  • 社招进阶项目

    • 刚果商城(DDD领域驱动) (opens new window)
加入群聊
🔋知识星球
代码仓库 (opens new window)
首页
后端技术
🚀大话面试
  • 校&社招实战项目

    • 12306(铁路购票平台)
    • 短链接(Sass平台)
  • 社招进阶项目

    • 刚果商城(DDD领域驱动)
  • 基础架构项目

    • 幂等基础组件(支持接口及多种MQ)
    • 企业基础架构组件库
  • 校&社招实战项目

    • 12306(铁路购票平台) (opens new window)
    • 短链接(Sass平台) (opens new window)
  • 社招进阶项目

    • 刚果商城(DDD领域驱动) (opens new window)
加入群聊
🔋知识星球
代码仓库 (opens new window)
  • 小册简介

    • 什么是大话面试
  • Redis

    • Redis为什么这么快?
    • Redis宕机数据会丢失么?
    • Redis的AOF是怎么实现的?
    • Redis的RDB是怎么实现的?
      • 回答话术
      • 问题详解
        • 1. 如何生成 RDB 文件
        • 2. 实现原理
        • 3. 与 AOF 的区别
    • Redis如何实现到期删除的?
    • Redis常用内存淘汰策略?
    • Redis字符串底层数据结构?
    • Redis的压缩列表是什么?
    • Redis的跳表是什么?
    • Redis的ZSet底层是怎么实现的?
    • 什么是布隆过滤器?
    • 布隆过滤器容量如何评估?
    • 布隆过滤器容量不够用如何解决?
    • Redis节点CPU核数越高越好?
    • 为什么Redis不适合海量请求?
    • Redis如何应对海量请求?
    • 如何提升Redis批量访问性能?
  • 缓存

    • 如何解决缓存击穿?
    • 如何解决缓存穿透?
    • 如何解决缓存雪崩?
    • 如何解决大Key问题?
    • 缓存如何预热?
    • 如何发现缓存中热Key?
    • 如何解决热Key问题?
    • 缓存与数据库一致性?
    • 先写DB再删除缓存解决一致性?
    • Binlog配合MQ如何解决一致性?
目录

Redis的RDB是怎么实现的?

# 回答话术

当通过 BGSAVE 指令生成 RDB 的时候,Redis 会 fork 出一个子进程,它会基于写时复制机制,在不阻塞主线程的情况下,将此刻的数据库全量数据保存为二进制快照。

具体的来说,在最开始的时候 fork 子进程的时候,操作系统会为其拷贝父进程的内存页,但是此时两者都指向同一块物理内存。当主进程发生写操作时,会真正的将父进程的数据拷贝到独立的物理内存中。此时父子进程的物理内存彼此独立,互不干涉,父进程继续处理增量数据,而子进程则根据拷贝出来的旧数据生成 RDB 快照。

相对 AOF,RDB 生成的二进制文件更小,数据恢复起来更快,并且整个流程中完全不会阻塞主进程,但是对应的,由于写时复制,在最坏的情况下可能会占用双倍内存,并且无法保存增量数据。

# 问题详解

# 1. 如何生成 RDB 文件

我们可以通过 SAVE 命令在主进程中阻塞的生成 RDB 文件,或者通过 BGSAVE 命令指定在子进程中生成 RDB 文件。

此外,也可以在数据库中通过 save 选项,指定当在一定的时间范围内执行了多少次修改时生成 RDB 文件。比如 save 120 10000 表示当在 120 秒内发生了 10000 次修改时,就通过 BGSAVE 在后台生成一分 RDB 文件。

关于数据是如何保存在 RDB 文件中的,请参考文章:RDB 文件结构 — Redis 设计与实现 (opens new window)

# 2. 实现原理

当 Redis 在 fork 出一个子进程去生成 RDB 文件时,主进程依然还在不同的接受指令并操作数据。与 AOF 不同,由于 RDB 是快照,因此实际上它不会同步增量数据,不过也不会影响父进程的操作。Redis 通过写时复制机制实现这样的效果。

简单的来说,当 fork 子进程后,虽然子进程会从父进程中拷贝内存页,但是实际上的内存页依然还是指向了原本的物理内存。而当父进程修改了内存后,才会真正在物理内存中复制一遍父进程的数据,并让子进程的内存页指向这块物理内存,这就是写时复制。

根据这个原理,当子进程在生成 RDB 文件时,若父进程发生写操作,由于写时复制,子进程会得到一份父进程的拷贝。此时子进程读取的是此时父进程内存数据的拷贝,而父进程继续操作他原本的那份内存,两者互不干涉。

在这个过程中,如果所有的数据都被修改过,那么内存中可能会同时存放两份数据。

# 3. 与 AOF 的区别

RDB 即 Redis Database,它本质上就是某个时刻的全量数据快照。它以二进制的方式保存了某个时刻 Redis 数据库中的全部数据,Redis 启动后只需要将其加载进内存即可恢复数据。

相比起 AOF,它的优点是:

  • 文件更小:由于 RDB 里面存放的是非常紧凑的二进制数据,因此相比起 AOF 文件,它占用的空间更小,因此也更适合用来频繁的进行全量备份。
  • 加载更快:Redis 只需要将 RDB 加载进内存即可恢复数据,相比起还需要重放指令的 AOF,它要快得多。
  • 不阻塞主进程:生成 RDB 的过程可以完全在子进程中完成,因而不需要在主线程进行任何 IO 操作。

对应的,它的缺点是:

  • RDB 需要 fork 出子进程去完成这个任务,当比较频繁的生成 RDB 文件时,会对 CPU 带来比较大的压力;
  • 无法保存增量数据;
上次更新: 2023/11/06, 23:14:13
Redis的AOF是怎么实现的?
Redis如何实现到期删除的?

← Redis的AOF是怎么实现的? Redis如何实现到期删除的?→

Theme by Vdoing | Copyright © 2022-2023 马丁玩编程 | Apache2 License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式