> 文章列表 > 【Redis】Redis持久化之RDB详解(Redis专栏启动)

【Redis】Redis持久化之RDB详解(Redis专栏启动)

【Redis】Redis持久化之RDB详解(Redis专栏启动)

📫作者简介:小明java问道之路,2022年度博客之星全国TOP3,专注于后端、中间件、计算机底层、架构设计演进与稳定性建设优化。文章内容兼具广度深度、大厂技术方案,对待技术喜欢推理加验证,就职于知名金融公司后端高级工程师。

        

📫 热衷分享,喜欢原创~ 关注我会给你带来一些不一样的认知和成长。

        

🏆 2022博客之星TOP3 | CSDN博客专家 | 后端领域优质创作者 | CSDN内容合伙人

🏆 InfoQ(极客邦)签约作者、阿里云专家 | 签约博主、51CTO专家 | TOP红人、华为云享专家

        

🔥如果此文还不错的话,还请👍关注、点赞、收藏三连支持👍一下博主~ 


🍅 文末获取联系 🍅  👇🏻 精彩专栏推荐订阅收藏 👇🏻

专栏系列(点击解锁)

学习路线(点击解锁)

知识定位

🔥Redis从入门到精通与实战🔥

Redis从入门到精通与实战

围绕原理源码讲解Redis面试知识点与实战

🔥MySQL从入门到精通🔥

MySQL从入门到精通

全面讲解MySQL知识与企业级MySQL实战

🔥计算机底层原理🔥

深入理解计算机系统CSAPP

以深入理解计算机系统为基石,构件计算机体系和计算机思维

Linux内核源码解析

围绕Linux内核讲解计算机底层原理与并发

🔥数据结构与企业题库精讲🔥

数据结构与企业题库精讲

结合工作经验深入浅出,适合各层次,笔试面试算法题精讲

🔥互联网架构分析与实战🔥

企业系统架构分析实践与落地

行业最前沿视角,专注于技术架构升级路线、架构实践

互联网企业防资损实践

互联网金融公司的防资损方法论、代码与实践

🔥Java全栈白宝书🔥

精通Java8与函数式编程

本专栏以实战为基础,逐步深入Java8以及未来的编程模式

深入理解JVM

详细介绍内存区域、字节码、方法底层,类加载和GC等知识

深入理解高并发编程

深入Liunx内核、汇编、C++全方位理解并发编程

Spring源码分析

Spring核心七IOC/AOP等源码分析

MyBatis源码分析

MyBatis核心源码分析

Java核心技术

只讲Java核心技术

本文目录

本文目录

本文导读

一、什么是Redis RDB

二、RDB持久化的两种方法(RDB的两种策略方式)

1、save(同步阻塞)

2、bgsave命令(异步非阻塞)

3、save与bgsave比较

三、如何使用RDB策略备份数据

四、Redis RDB优缺点

五、bgsave原理

1、bgsave执行流程

2、fork实现原理(Copy On Write写时复制)

总结


本文导读

本文讲解Redis持久性机制RDB,RDB持久化的两种方法(RDB的两种策略方式、save和bgsave命令)并进行比较,如何使用RDB策略备份数据,分析Redis RDB优缺点,bgsave原理,bgsave执行流程,fork的实现原理(Copy On Write写时复制)。

一、什么是Redis RDB

Redis提供了两种持久性机制:一种是RDB也称为快照模式,一种是AOF日志也称为追加模式。

Redis RDB 是生成当前进程中数据的快照并将其保存到硬盘(因此也称为快照持久性),保存的文件后缀是.rdb,RDB是Redis的默认数据持久化方法,它将把数据库快照保存在dump.rdb二进制文件中,当Redis重新启动时可以读取快照(即以二进制文件的形式保存内存数据)并从文件中恢复数据。

二、RDB持久化的两种方法(RDB的两种策略方式)

1、save(同步阻塞)

当在Redis客户端上执行save命令时,将在Redis安装目录中生成RDB文件,save有一个致命问题,Redis服务在持久化期间被阻止(确切地说,它将阻止当前执行save命令的线程,但 Redis 是单线程的,因此整个服务将被阻止)Redis就不能继续提供外部请求,如果数据量很小,则影响很小,如果每次复制需要1小时,相当于一小时的停机时间。 

2、bgsave命令(异步非阻塞)

使用 Linux的fork()函数用于生成主进程的子进程,用于完成RDB的生成。生成完成后,将通知主进程我们的RDB文件已成功生成。时间复杂度也是O(n),但它不会阻塞主进程

底层原理是 fork()+copyonwrite,bgsave可以在持久化的同时提供外部读写服务,而不会相互影响,新写的数据不会对已经持久化的数据造成数据影响,持久化过程中的出现异常或时间过长不会对Redis的外部服务产生任何影响,持久化后,新的rdb文件将覆盖前一个文件。

3、save与bgsave比较

save bgsave
IO 同步 异步
阻塞 部分(fork时发生阻塞)
时间复杂度 O(n) O(n)
优点 不消耗额外内存 不阻塞客户端命令
缺点 阻塞客户端命令 需要fork消耗内存

三、如何使用RDB策略备份数据

RDB持久化的触发分为手动触发和自动触发两种,Redis可以通过客户端主动持久化,输入命令(手动在客户端输入save 或 bgsave命令)生成RDB文件,也可以通过配置来等满足条件时自动持久化(自动触发是在配置文件中通过save m n,指定当m秒内发生n次变化时,会触发bgsave,比如save m n配置,save 900 1,意味着900秒内至少有1个key被改变则做一次快照)生成RDB文件。

一般情况下不会手动触发,在主从复制期间,从库全量主库数据,主库将执行bgsave命令进行快照;当客户端执行数据库清空命令FLUSHALL时触发快照;当客户端执行shutdown关闭Redis时触发快照。

四、Redis RDB优缺点

优点:RDB文件简单快捷,它在某个时间点存储Redis数据,适合备份,可以设置一个时间点来归档RDB文件,以便在需要时可以轻松地将数据恢复到不同的版本,也就是说RDB适合灾难恢复(灾备),单个文件可以轻松地传输到远程服务器,RDB的性能非常好,当需要持久性时,主进程将派生出一个子进程,然后将持久性工作移交给子进程(bgsave)。

缺点:RDB存在丢失数据问题,假设快照(自动触发save m n配置)每5分钟保存一次,如果Redis由于某种原因无法正常工作,则从上次生成快照到Redis出现问题的数据将丢失。RDB使用fork() 为数据持久化生成子进程,如果数据很大,可能需要一些时间,导致Redis停止服务。

五、bgsave原理

1、bgsave执行流程

Redis父进程首先确定否有有正在执行的save、bgsave、bgrewriteaof的子进程,如果正在执行,bgsave命令将直接返回。

父进程执行fork操作以创建子进程,在此过程中,父进程被阻止,Redis无法从客户端执行任何命令。在父进程fork后,bgsave命令返回保存信息,不再阻止父进程,并可以响应其他命令,子进程创建RDB文件,基于父进程的内存快照生成临时快照文件,并在完成后执行原始文件的原子替换
子进程向父进程发送信号以指示完成,父进程更新统计信息。

2、fork实现原理(Copy On Write写时复制)

fork实现通过Copy-on-Write写时复制,,类似于Java中的CopyOnWriteArrayList。如果多个调用方同时需要相同的资源(如内存或磁盘中的数据存储),多个调用方将共同获得指向同一资源的相同指针,在调用方尝试修改资源的内容之前,系统实际上会向调用方复制一个特殊副本,其他调用方看到的初始资源保持不变。

这是 Linux 的机制,为了节省内存资源,尽可能多地共享资源,在进程分离的时刻,内存增长几乎没有显著变化。在Redis中,子进程执行数据持久化不会修改现有的内存数据结构,只会遍历和读取数据结构,然后将其序列化到磁盘。父进程不同需要继续服务客户端请求,然后不断修改内存数据结构。这个时候就会使用操作系统的 COW 机制来进行数据段页面的分离(请参考:【精通内核】计算机程序的本质、内存组成与ELF格式深度解析)

数据段由许多操作系统的页面组成,当父进程修改其中一个页面的数据时,它将复制并分离共享页面,然后修改复制的页面,此时,子流程的相应页面或生成流程时的数据不会更改。因为子进程的数据没有改变,所以它所能看到的内存中的数据在进程生成时被冻结,不会再改变,所有Redis持久性被称为快照,所有子进程可以安全的遍历数据并写入磁盘。

总结

本文讲解Redis持久性机制RDB,RDB持久化的两种方法(RDB的两种策略方式、save和bgsave命令)并进行比较,如何使用RDB策略备份数据,分析Redis RDB优缺点,bgsave原理,bgsave执行流程,fork的实现原理(Copy On Write写时复制)。