RedisRedis持久化之RDB详解(Redis专栏启动)
Posted 小明java问道之路
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RedisRedis持久化之RDB详解(Redis专栏启动)相关的知识,希望对你有一定的参考价值。
📫作者简介:小明java问道之路,2022年度博客之星全国TOP3,专注于后端、中间件、计算机底层、架构设计演进与稳定性建工设优化。文章内容兼具广度深度、大厂技术方案,对待技术喜欢推理加验证,就职于知名金融公司后端高级工程师。
📫 热衷分享,喜欢原创~ 关注我会给你带来一些不一样的认知和成长。
🏆 2022博客之星TOP3 | CSDN博客专家 | 后端领域优质创作者 | CSDN内容合伙人
🏆 InfoQ(极客邦)签约作者、阿里云专家 | 签约博主、51CTO专家 | TOP红人、华为云享专家
🔥如果此文还不错的话,还请👍关注、点赞、收藏三连支持👍一下博主~
🍅 文末获取联系 🍅 👇🏻 精彩专栏推荐订阅收藏 👇🏻
专栏系列(点击解锁)
学习路线(点击解锁)
知识定位
全面讲解MySQL知识与企业级MySQL实战 🔥计算机底层原理🔥
本文目录
本文导读
本文讲解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写时复制)。
以上是关于RedisRedis持久化之RDB详解(Redis专栏启动)的主要内容,如果未能解决你的问题,请参考以下文章