redis:RDB和AOF机制

个人主页 : 个人主页
个人专栏 : 《数据结构》 《C语言》《C++》《Linux》《网络》 《redis学习笔记》
文章目录
- 前言
- RDB
- AOF
- 总结
前言
redis是一个内存数据库,把数据存储在内存中的,而内存中的数据是不持久的,要想能够做到持久,就需要让redis把数据存储到硬盘上。但redis相比于mysql这样的关系型数据库,最明显的特点就是效率高,速度快。这样便导致redis为了保证速度快,数据要存储在内存中,又为了持久化,数据要存储到硬盘中;
当要插入一个新的数据时,需要把这个数据,“同时”写入到内存和硬盘;当要查询某个数据时,直接从内存读取;硬盘数据只是在redis重启的时候,用来恢复内存中的数据的。
redis支持RDB(Redis DataBase)和AOF(Append Only File)两种持久化机制
RDB
RDB定期的把redis内存中的所有数据,都给写入硬盘中,生成一个快照;之后redis一旦重启,就可以根据刚才的快照,把内存中的数据恢复回来。
定期具体而言,又两种方式:手动触发,自动触发
- 手动触发
save命令,阻塞当前redis服务器,直到RDB过程完成为止。会导致类似于 keys *的后果,一般不建议使用save
bgsave命令,redis进程执行 fork 操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束;阻塞只发生在fork阶段
redis内部所有涉及到RDB的操作都采用类似bgsave的方式
2.自动触发
在redis配置文件中(linux中,redis的默认配置文件路径是/etc/redis/redis.conf),设置下,使redis每隔多长时间和每产生多少次修改就触发
使用save配置,如"save m n"表示 m秒内数据集发送了 n 次修改,自动RDB持久化;
通过shutdown 命令,关闭redis服务器,也会触发 service redis-server restart ,正常关闭
redis 进行主从复制的时候,主节点也会自动生成RDB快照,然后把RDB快照文件内容传输给从节点
bgsave命令的运行流程

- 执行bgsave命令,redis父进程判断当前进程是否存在其它正在执行的子进程,如RDB/AOF子进程,如果存在bgsave命令直接返回
- 父进程fork完成后,bgsave命令会返回"Background saving started" 信息并不再阻塞父进程,父进程可以继续响应其它命令
- 子进程创建RDB文件,根据父进程内存生成临时快照文件,完成后对原有文件进行原子替换
- 子进程发送信号给父进程表示完成,父进程更新统计信息
redis生成的rdb文件,存放在redis的工作目录中的,可以在redis配置文件中,进行设置


dump.rdb就是rdb机制生成的镜像文件,redis服务器默认的就是开启rdb的;dump.rdb文件就是二进制文件,把内存中的数据,以压缩的形式(默认采用LZF算法),保存到这个二进制文件中。
后续redis服务器重新启动,就会尝试加载这个rdb文件,如果发现格式错误,可能会加载数据失败

redis-check-rdb是redis提供的rdb文件检查工具
- RDB是一个紧凑压缩的二进制文件,代表redis在某个时间点上的数据快照。非常适用于备份,全量复制等场景。比如每6个小时执行bgsave备份,并把RDB文件复制到远端机器或者文件系统中用于灾备
- redis加载RDB恢复数据远远快于AOF的方式;RDB使用二进制的方式组织数据,直接把数据读取到内存中,按照字节的格式取出来放到结构体/对象中即可,但AOF是使用文本的方式来组织数据,则需要进行一系列的字符串切分
- RDB方式数据每办法走到实时持久化/秒级持久化,bgsave每次运行都需要执行fork创建子进程,属于重量级操作,频繁执行成本过高
- RDB文件使用特定二进制格式保存,redis版本演进过程有多个RDB版本,兼容可能有风险;可以通过写一个程序,直接遍历旧的redis中的所有key,把数据取出来插入到新的redis服务器中
AOF
redis的AOF(Append Only File)机制是一种持久化机制,用于将redis服务器接收到的所有写操作命令以追加的方式写入到磁盘中的日志文件中,重启时再重新执行AOF文件中的命令达到恢复数据的目的。
AOF的主要作用是解决数据持久化的实时性
开启AOF功能需要设置配置:appendonly yes,AOF文件名通过appendfilename配置,所在目录和RDB一样(/var/lib/redis)



所有的写入命令会追加到aof_buf(缓冲区)中,AOF缓冲区根据对应的策略向硬盘做同步操作,随着AOF文件越来越大,需要定期对AOF文件进行重写,达到压缩目的,当redis服务器启动时,可以加载AOF文件进行数据恢复
redis执行命令速度快的重要原因,是直接操作内存;现在引入AOF后,又要写内存,又要写硬盘还可以想之前一样快吗?实际上,并没有影响到redis处理请求的速度,有以下两个原因:
- AOF机制并非是直接让工作线程把数据写入硬盘,而是先写入一个内存中的缓冲区,先积累一部分,再统一写入硬盘;这样大大降低了写硬盘的次数
- 硬盘上读写数据,顺序读写的速度是比较快的(比内存还是慢很多),AOF是每次把新的操作写入到原有文件的末尾,属于顺序写入
但缓冲区的数据还是在内存中,如果redis服务器突然挂了,缓冲区的数据就丢了。
redis给出一些选项,让我们选择缓冲区的刷新策略

刷新频率越高,性能影响就越大,数据可靠性就越高
刷新评率越低,性能影响就越小,数据可靠性就越低
系统调用write 和 fsync说明:
- write操作会触发延迟写(delayed write)机制,linux在内核提供页缓冲区用来提高硬盘IO性能,write操作在写入系统缓冲区后立即返回,同步硬盘操作依赖于系统调度机制;如:缓冲区页空间写满或到达特定时间周期。同步文件之前,如果此时系统故障宕机,缓冲区内数据丢失
- fsync针对单个文件操作,做强制硬盘同步,fsync将阻塞直到数据写入到硬盘
- 配置为always时,每次写入都要同步AOF文件,性能很差,在一般的SATA硬盘上,只能支持大约几百TPS写入。
- 配置为no时,由于操作系统同步策略不可控,虽然提供了性能,但数据丢失风险大大提高
- 配置everysec,是默认配置,兼顾数据安全和性能。理论上最多丢失1秒的数据

AOF文件持续增长,体积越来越大,会影响到redis下次启动的启动时间;redis启动的时候要读取aof文件内容(记录中间过程),而这个AOF文件有一些内容是多余的。

类似上述操作,实际上AOF只需要记录 set key 5即可。
因此redis就存在一个机制,能够针对AOF文件进行整理操作;也就是能够删除多余的内容,使AOF文件大小变小
AOF重写过程可以分为手动触发和自动触发
手动触发:调用bgrewriteaof命令
自动触发:根据 auto-aof-rewrite-min-size 和 auto-aof-rewrite-percentage 参数确定自动触发时间
- auto-aof-rewrite-min-size:触发重写时AOF的最小文件大小
- auto-aof-rewrite-percentage:当前AOF占用大小相比上次重传写时增加的比例


执行AOF重新请求,如果当前进程正在执行AOF重写,请求不执行;如果当前进程正在执行bgsave操作,重新命令延迟到bgsave完成之后再执行
父进程执行fork创建子进程;
父进程继续响应其它命令,所有写入命令仍然写入AOF缓冲区并根据appendfsync策略同步到硬盘,保证旧AOF文件机制正确(重写过程中,如果redis服务器挂了,可以根据旧AOF文件恢复数据);子进程根据内存快照,将命令合并到新的AOF文件中;
子进程完成重写,新AOF文件写入后,子进程发送信号给父进程,父进程把AOF重写缓冲区内临时保存的命令追加到新的AOF文件中,用新AOF文件替换旧AOF文件
注意:
重写的时候,不关心AOF文件中原来都有什么,只关心内存中最终的数据状态,子进程只需要把内存中当前的数据,获取出来,以AOF格式写入到一个新的AOF文件中;内存中的数据状态,就已经相当于把旧AOF文件结果整理后的样子;
RDB对于fork之后的新数据,就直接置之不理;AOF则对于fork之后的新数据,采用aof_rewrite_buf缓冲区的方式来处理;这是因为RDB本身的设计理念就是用来“定期备份”的,AOF的设计理念是“实时备份”
AOF本来是按照文本的方式写入文件的,但文本的方式写入文件,后续加载成本比较高;redis就引入了“混合持久化”的方式,结合了RDB和AOF的特点
按照AOF的方式,把每一个请求/操作,都记录文件,在触发AOF重写之后,把当前内存的状态按照RDB的二进制格式写入到新的AOF文件中,后续再进行的操作,仍然按照AOF文本的方式追加到文件后面

该选项为 yes 表示开启混合持久化
当redis上同时存在AOF文件和RDB快照时,启动redis以谁为主?以AOF为主,RDB直接被忽略了,AOF中包含的数据比RDB更全。

总结
以上就是我的redis学习笔记

相关文章:
redis:RDB和AOF机制
个人主页 : 个人主页 个人专栏 : 《数据结构》 《C语言》《C》《Linux》《网络》 《redis学习笔记》 文章目录 前言RDBAOF总结 前言 redis是一个内存数据库,把数据存储在内存中的,而内存中的数据是不持久的,要想能够做…...
券商隔夜单自动下单交易接口
之前研究打板排板,研究怎么才能买得进去。 最近遇到几只利空跌停板,缩量跌停,明天大概率继续一字封板跌停。 如果卖不掉,意味着还要继续吃几个跌停,甚至ST票十几个跌停都有可能。 一次跌停亏几万,还是挺…...
生成任意3D和4D场景!GenXD:通用3D-4D联合生成框架 | 新加坡国立微软
文章链接: https://arxiv.org/pdf/2411.02319 项目链接:https://gen-x-d.github.io/ 有视频 亮点直击 设计了一个数据整理流程,从视频中获取包含可移动物体的高质量4D数据,并为30,000个视频标注了相机姿态。这个大规模数据集称为CamVid-30K&…...
通过命令学习k8s
1、kubectl 命令可以列出所有命令 2、kubectl version 命令可以查看版本号 3、kubectl cluster-info命令可以查看集群信息(192.168.218.136:6443 即为kube-apiserver的IP和端口。) [rootk8s-master ~]# kubectl cluster-info Kubernetes master is run…...
【redis】—— 初识redis(redis基本特征、应用场景、以及重大版本说明)
序言 本文将引导读者探索Redis的世界,深入了解其发展历程、丰富特性、常见应用场景、使用技巧等,最后会对Redis演进过程中具有里程碑意义的版本进行详细解读。 (一)初始redis Redis是一种基于键值对(key-value&#x…...
服务器显卡和桌面pc显卡有什么不同
服务器显卡和桌面 PC 显卡在设计目标、性能优化、功能支持和硬件规格上都有显著不同。以下是主要区别: 1. 设计用途 服务器显卡:主要用于计算、深度学习、数据分析、科学计算、虚拟化和图形渲染等任务。其设计目标是持续高负载计算,保证高稳…...
Chrome使用IE内核
Chrome使用IE内核 1.下载扩展程序IE Tab 2.将下载好的IE Tab扩展程序拖拽到扩展程序界面,之后重启chrome浏览器即可...
类和对象(C++)——默认成员函数,构造函数,析构函数
1. 类的默认成员函数 默认成员函数就是用户没有显式实现,编译器会⾃动⽣成的成员函数称为默认成员函数。⼀个类,不写的情况下编译器会默认生成以下6个默认成员函数,需要注意的是这6个中最重要的是前4个,最后两个取地址重载&#…...
深入理解 Vue v-model 原理与应用
一、引言 在 Vue.js 开发中,v-model是一个非常重要且强大的指令。它为开发者在处理表单输入和数据双向绑定等场景中提供了极大的便利。无论是新手还是有经验的开发者,深入理解v-model对于高效地构建 Vue 应用至关重要。本文将对v-model进行深入剖析,从其基本原理、使用方式…...
内网域环境、工作组、局域网等探针方案
1. 信息收集 1.1 网络收集 了解当前服务器的计算机基本信息,为后续判断服务器角色,网络环境做准备 systeminfo 详细信息 net start 启动服务 tasklist 进程列表 schtasks 计划任务(受权限影响) 了解当前服务器的网络接口信息…...
uniapp—android原生插件开发(3Android真机调试)
本篇文章从实战角度出发,将UniApp集成新大陆PDA设备RFID的全过程分为四部曲,涵盖环境搭建、插件开发、AAR打包、项目引入和功能调试。通过这份教程,轻松应对安卓原生插件开发与打包需求! 一、打包uniapp资源包: 打包…...
goframe开发一个企业网站 统一返回响应码 18
响应码的logic package returncodeimport ("context""gf_new_web/internal/service""github.com/gogf/gf/v2/errors/gcode""github.com/gogf/gf/v2/frame/g" )type sReturncode struct { }var (insReturncode sReturncode{}…...
基于STM32的智能门禁系统设计
引言 本项目基于STM32微控制器设计了一个智能门禁系统,通过集成多个传感器模块和控制设备,实现对门禁系统的自动化管理与控制。该系统能够通过RFID卡、密码输入、以及指纹传感器等多种方式对进出人员进行验证,并结合LCD显示屏提供实时信息反…...
Python学习从0到1 day28 Python 高阶技巧 ⑧ 递归
那就祝我们爬不同的山,还能回到同一条路上,不是时时见面,但是时时惦记之人 —— 24.11.13 递归 1.什么是递归 递归在编程中是一种非常重要的算法 递归:即方法(函数)自己调用自己的一种特殊编程写法 函数调用自己,即…...
知识见闻 - 苹果手机拨号键长按
苹果手机(iPhone)在拨号界面长按按键时有一些特定的功能。以下是iPhone拨号键盘上长按按键的主要功能: 数字键 0 - 长按可输入""号,用于国际电话拨号 - 这是最常用的长按功能之一,方便用户拨打国际电话 星号…...
在 KubeVirt 中使用 GPU Operator
在 KubeVirt 中使用 GPU Operator 基于最新的GPU Operator版本24.9.0。 原文链接:GPU Operator with KubeVirt — NVIDIA GPU Operator 24.9.0 documentation 1. 简介 KubeVirt 是 Kubernetes 的一个虚拟机管理插件,允许您在 Kubernetes 集群中运行和…...
安慰剂检验Stata代码(全套代码、示例数据及参考文献)
数据简介:随着因果推断方法在实证研究中的使用比例不断提升,越来越多的文章进行安慰剂检验。其检验基本原理与医学中的安慰剂类似,即使用假的政策发生时间或实验组进行分析,以检验能否得到政策效应。如果依然得到了政策效应&#…...
DAY6 线程
作业1: 多线程实现文件拷贝,线程1拷贝一半,线程2拷贝另一半,主线程回收子线程资源。 代码: #include <myhead.h> sem_t sem1; void *copy1()//子线程1函数 拷贝前一半内容 {int fd1open("./1.txt",O…...
基于STM32的智能门锁系统设计思路:蓝牙、RFID等技术
一、项目概述 在现代家居安全领域,传统门锁因其安全性不足、开锁方式单一等问题,已逐渐无法满足用户的需求。传统机械锁容易被撬开、复制钥匙,同时开锁方式仅限于物理钥匙,给用户带来不便。因此,本文旨在设计并开发一…...
AndroidStudio-广播
一、广播的本质 广播是一种数据传输方式 二、Android 中的广播 发送一条广播,可以被不同的广播接收者所接收,广播接收者收到广播之后,再进行逻辑处理。 三、收发标准广播 广播的收发过程分为三个步骤: 1.发送标准广播 2.定义…...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)
前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块,…...
Rust 开发环境搭建
环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu 2、Hello World fn main() { println…...
从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...
二维FDTD算法仿真
二维FDTD算法仿真,并带完全匹配层,输入波形为高斯波、平面波 FDTD_二维/FDTD.zip , 6075 FDTD_二维/FDTD_31.m , 1029 FDTD_二维/FDTD_32.m , 2806 FDTD_二维/FDTD_33.m , 3782 FDTD_二维/FDTD_34.m , 4182 FDTD_二维/FDTD_35.m , 4793...
JS红宝书笔记 - 3.3 变量
要定义变量,可以使用var操作符,后跟变量名 ES实现变量初始化,因此可以同时定义变量并设置它的值 使用var操作符定义的变量会成为包含它的函数的局部变量。 在函数内定义变量时省略var操作符,可以创建一个全局变量 如果需要定义…...
Netty自定义协议解析
目录 自定义协议设计 实现消息解码器 实现消息编码器 自定义消息对象 配置ChannelPipeline Netty提供了强大的编解码器抽象基类,这些基类能够帮助开发者快速实现自定义协议的解析。 自定义协议设计 在实现自定义协议解析之前,需要明确协议的具体格式。例如,一个简单的…...
【芯片仿真中的X值:隐藏的陷阱与应对之道】
在芯片设计的世界里,X值(不定态)就像一个潜伏的幽灵。它可能让仿真测试顺利通过,却在芯片流片后引发灾难性后果。本文将揭开X值的本质,探讨其危害,并分享高效调试与预防的实战经验。 一、X值的本质与致…...

