面试官问:Redis如何持久化?
mhr18 2024-11-18 14:32 19 浏览 0 评论
今天这节我们将简单讲解redis的持久化机制,去除繁琐的背景描述,我们直接入主题!
redis为什么要持久化?
众所周知redis数据是存放在内存中,是一个内存数据库,如果没有不想办法定期将其状态持久化到磁盘中,当我们遭遇不可抗力因素的时候我们就无法恢复之前的状态,比如断电后导致进程退出,我们可以根据之前的持久化数据重建缓存。
redis持久化方式有哪些?
- RDB (Redis DataBase)持久化:这是默认的持久化方式,这个方式是以手动触发或者服务器配置选项来定期执行将redis数据库的状态(某时刻的数据快照)保存到一个RDB文件中。
- AOF (Append Only File)持久化:我们RDB会做全镜像备份,而这种方式在某些时候是不合适的,我们希望以一种增量式方式来备份,AOF就应运而生了,工作方式是redis会将收到的写命令以文本形式追加到文件中。
AOF文件重写原理
为啥要重写aof文件,这里会有一个问题? AOF保存是每次客户端请求的写命令,随时间的增长会变得越来越大,而且里面有大量的重复命令,比如命令:加了三次key为students的命令
sadd students "zhangsan"
sadd students "lisi"
sadd students "wangmazi"
AOF文件必须保存三条命令,这完全没有不要!其他写命令也是同样的道理,为了缩减aof文件,AOF重写程序开启子进程调用aof_rewirte函数来完成文件重写的工作,这样可以保证重写期间主进程继续提供读写服务,子进程带有父进程的数据副本,不使用线程是为了避免使用锁而造成数据安全问题,子进程首先从数据库找到该键值当前值,然后用一条命令代替之前三条命令,这就是AOF重写的原理,简单明了!
RDB持久化触发方式
- save命令:执行save命令,直接阻塞客户端进程直到保存完成,完成后会删除老的RDB。
- bgsave命令:服务器会创建(fork)一个子进程,由子进程负责保存RDB文件,父进程继续为客户端提供读写服务,这里需要注意的是派生出来的的是子进程而不是子线程!这很重要!如果是子线程来负责保存工作,线程之间必然存在竞争!
AOF持久化触发方式
- always:同步持久化,每次写请求会被立即从aof_buffer中同步到磁盘,性能较差但也是最安全的,如果发生故障停机只会丢失一个时间循环内的写操作。
- everysec:每秒同步异步操作,每秒从aof_buffer中同步到磁盘,发生停机只会丢失一秒命令数据。
- no:只负责写入aof_buffer缓冲区,至于什么时候同步到磁盘由系统决定,可能是缓冲区满了,也可能是时间限制到了,这是速度最快,但是宕机后会丢失当前缓冲区所有命令数据。
持久化过程如何保证数据一致性?
无论是RDB还是AOF都使用了子进程来处理持久化过程,而父进程可以继续处理客户端读写请求,这里你或许会有2个疑问?
问题1:RDB生成文件过程中怎么保证数据不被新的写命令覆盖,导致数据被污染?
问题1:AOF文件重写过程中怎么保证文件数据的状态和redis内存数据状态一致性?
如何解决这2个问题?
解决问题1:举个例子,子进程生成RDB文件过程中,还未被持久化的内存页数据可能被变更了,那等持久化完成后的数据文件就不能叫快照或镜像了!所谓快照或是镜像,说的是在同一时刻所有数据状态都要被定格保存下来,例如说好是持久化<=9:00的数据,完成后不能出现部分数据更新时间是9:00之前的,部分是九点以后的。
RDB持久化过程中,redis调用fork开启子进程将数据从内存写入一个临时文件,而父进程继续提供读写服务。此时利用linux系统的写时复制的机制(copy on write)使子进程和父进程是共享物理页面(page)的,一般情况是复制一个子进程会把父进程的数据全部copy出来,这样会浪费大量存储空间和copy时间 ,写时复制只有在父进程接收写请求时会单独为需要修改的page复制出副本来写入,当子进程写入临时文件完成后会替换老的RDB文件。
例如下图,如果子进程正在进行持久化,此时如果客户端A需要写入page1,父进程会将page1复制出来进行写入,子进程此时读到是原始数据,因为变更在副本上不在原始数据上,所以子进程的地址空间内数据仍然是fork时刻的快照。
解决问题2:AOF在重写过程中使用子进程来避免父进程阻塞,所以父进程可以继续处理读写请求,而新的写请求会改变数据库状态,使其和AOF文件命令所表示状态不一致,例如子进程开始重写之前,数据库只有一个键值对k1=v1,等重写完成后数据库有了k2、k3、k4,重写后的aof文件和redis实时数据库状态不一致。为了解决这个问题,redis引入一个aof重写缓冲区,这个重写缓冲区在子进程创建之后开始写入,此时redis每接受一个写命令是会同时往aof缓冲区和重写缓冲区写数据。
当子进程完成AOF文件重写后会生成新的AOF文件,这时子进程向父进程发起信号,父进程接收信号并做以下处理:
- AOF重写缓冲区内容追加到刚生成AOF的文件尾部。
- 最后用新的文件原子覆盖已有的AOF文件。
父进程处理以上两步的时候处于阻塞状态,完成以后才能继续接收请求,而在其他时候父进程都可以接收请求,这样尽量提高了可用性!
什么时候载入持久化的数据?
当服务器启动时会自动检测RDB文件,如果存在则载入以恢复状态。当然我们比较之后看到了,由于AOF文件保存的是每条写命令必然它的更新频率高于RDB全量备份文件,所以服务器启动时会优先选择AOF来恢复数据!
redis持久化流程
无论是哪种持久化方式系统都是先将数据或命令保存懂啊系统缓冲区中,再从缓冲区同步到磁盘。以减少磁盘IO,如果此时发生了故障,那数据能否持久化?
- Redis故障:如果数据已经到系统内核缓冲区,也就是系统调用write成功返回,后面数据就从redis交给了系统层面,系统会自动持久化到磁盘,否则将持久化失败。
- 系统故障:可想而知系统都挂了,持久化必须上面所有步骤必须完成才能持久化。
RDB和AOF方式的优劣
RDB优势:
- 非常适合灾难恢复和全量备份。
- 由于是二进制格式,数据紧凑。
RDB劣势:
- 由于镜像或快照备份所以备份过程中,如果有新的数据写入,将不会保存,可能造成数据丢失。
AOF优势:
- 增量备份,通过配置可实现数据实时或延时持久化,数据丢失可能性降低。
- 可以通过重放AOF文件恢复最近的时间的数据,具体时间取决于配置刷盘策略。
AOF劣势:
- 如果配置的刷盘频率过高,可能读写速度不如RDB模式。
- AOF文件过大需要通过子进程重写压缩命令来解决。
最后
假如面试官问你一个问题:我有一堆数据,大家都去读写它,现在想把它以快照或增量的形式备份出来?有哪些方式?可能遇到问题有哪些?我们最后再来解答这个问题!读者可以自行思考。
个人理解有所纰漏,还请老铁们多多指教!请关注我的头条号【技术工匠】!后续持续更新!
相关推荐
- 【推荐】一个开源免费、AI 驱动的智能数据管理系统,支持多数据库
-
如果您对源码&技术感兴趣,请点赞+收藏+转发+关注,大家的支持是我分享最大的动力!!!.前言在当今数据驱动的时代,高效、智能地管理数据已成为企业和个人不可或缺的能力。为了满足这一需求,我们推出了这款开...
- Pure Storage推出统一数据管理云平台及新闪存阵列
-
PureStorage公司今日推出企业数据云(EnterpriseDataCloud),称其为组织在混合环境中存储、管理和使用数据方式的全面架构升级。该公司表示,EDC使组织能够在本地、云端和混...
- 对Java学习的10条建议(对java课程的建议)
-
不少Java的初学者一开始都是信心满满准备迎接挑战,但是经过一段时间的学习之后,多少都会碰到各种挫败,以下北风网就总结一些对于初学者非常有用的建议,希望能够给他们解决现实中的问题。Java编程的准备:...
- SQLShift 重大更新:Oracle→PostgreSQL 存储过程转换功能上线!
-
官网:https://sqlshift.cn/6月,SQLShift迎来重大版本更新!作为国内首个支持Oracle->OceanBase存储过程智能转换的工具,SQLShift在过去一...
- JDK21有没有什么稳定、简单又强势的特性?
-
佳未阿里云开发者2025年03月05日08:30浙江阿里妹导读这篇文章主要介绍了Java虚拟线程的发展及其在AJDK中的实现和优化。阅前声明:本文介绍的内容基于AJDK21.0.5[1]以及以上...
- 「松勤软件测试」网站总出现404 bug?总结8个原因,不信解决不了
-
在进行网站测试的时候,有没有碰到过网站崩溃,打不开,出现404错误等各种现象,如果你碰到了,那么恭喜你,你的网站出问题了,是什么原因导致网站出问题呢,根据松勤软件测试的总结如下:01数据库中的表空间不...
- Java面试题及答案最全总结(2025版)
-
大家好,我是Java面试陪考员最近很多小伙伴在忙着找工作,给大家整理了一份非常全面的Java面试题及答案。涉及的内容非常全面,包含:Spring、MySQL、JVM、Redis、Linux、Sprin...
- 数据库日常运维工作内容(数据库日常运维 工作内容)
-
#数据库日常运维工作包括哪些内容?#数据库日常运维工作是一个涵盖多个层面的综合性任务,以下是详细的分类和内容说明:一、数据库运维核心工作监控与告警性能监控:实时监控CPU、内存、I/O、连接数、锁等待...
- 分布式之系统底层原理(上)(底层分布式技术)
-
作者:allanpan,腾讯IEG高级后台工程师导言分布式事务是分布式系统必不可少的组成部分,基本上只要实现一个分布式系统就逃不开对分布式事务的支持。本文从分布式事务这个概念切入,尝试对分布式事务...
- oracle 死锁了怎么办?kill 进程 直接上干货
-
1、查看死锁是否存在selectusername,lockwait,status,machine,programfromv$sessionwheresidin(selectsession...
- SpringBoot 各种分页查询方式详解(全网最全)
-
一、分页查询基础概念与原理1.1什么是分页查询分页查询是指将大量数据分割成多个小块(页)进行展示的技术,它是现代Web应用中必不可少的功能。想象一下你去图书馆找书,如果所有书都堆在一张桌子上,你很难...
- 《战场兄弟》全事件攻略 一般事件合同事件红装及隐藏职业攻略
-
《战场兄弟》全事件攻略,一般事件合同事件红装及隐藏职业攻略。《战场兄弟》事件奖励,事件条件。《战场兄弟》是OverhypeStudios制作发行的一款由xcom和桌游为灵感来源,以中世纪、低魔奇幻为...
- LoadRunner(loadrunner录制不到脚本)
-
一、核心组件与工作流程LoadRunner性能测试工具-并发测试-正版软件下载-使用教程-价格-官方代理商的架构围绕三大核心组件构建,形成完整测试闭环:VirtualUserGenerator(...
- Redis数据类型介绍(redis 数据类型)
-
介绍Redis支持五种数据类型:String(字符串),Hash(哈希),List(列表),Set(集合)及Zset(sortedset:有序集合)。1、字符串类型概述1.1、数据类型Redis支持...
- RMAN备份监控及优化总结(rman备份原理)
-
今天主要介绍一下如何对RMAN备份监控及优化,这里就不讲rman备份的一些原理了,仅供参考。一、监控RMAN备份1、确定备份源与备份设备的最大速度从磁盘读的速度和磁带写的带度、备份的速度不可能超出这两...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle位图索引 (63)
- oracle批量插入数据 (62)
- oracle事务隔离级别 (53)
- oracle 空为0 (50)
- oracle主从同步 (55)
- oracle 乐观锁 (51)
- redis 命令 (78)
- php redis (88)
- redis 存储 (66)
- redis 锁 (69)
- 启动 redis (66)
- redis 时间 (56)
- redis 删除 (67)
- redis内存 (57)
- redis并发 (52)
- redis 主从 (69)
- redis 订阅 (51)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)
- redis 限流 (51)