Redis持久化篇

news2024/12/22 22:52:36

文章目录

  • 持久化篇
    • 1、AOF持久化是怎么实现的?
      • 1.1、AOF日志
      • 1.2、三种写回策略
      • 1.3、AOF重写机制
      • 1.4、AOF后台重写
    • 2、RDB快照是怎么实现的?
      • 2.1、快照怎么使用
      • 2.2、执行快照时,数据能被修改吗?
      • 2.3、RDB和AOF合体
    • 3、Redis大key对持久化有什么影响?
      • 3.1、大Key对AOF日志的影响
      • 3.2、大Key对AOF重写和RDB的影响

持久化篇

1、AOF持久化是怎么实现的?

1.1、AOF日志

在这里插入图片描述

​ 保存写操作到日志的持久化方式,就是Redis里的AOF持久化功能,注意只会记录写操作,读操作命令是不会被修改的,因为没有意义。=> 需要修改redis.comf里的参数:appendonly yes && appendfilename “appendonly.aof” 分别表示是否开启AOF持久化,AOF持久化文件的名称。

​ AOF文件格式 *3代表三部分 $3代表命令的字节数位3字节

而且Redis是先执行写操作,再记录命令到日志,这样有两个好处:

​ 1)避免额外的开销,如果写操作语法有问题,记录到AOF日志,恢复的时候可能会出问题。

​ 2)不会阻塞当前写操作命令的执行

风险:

​ 1)redis还没来得及将命令写入到硬盘,服务器宕机,数据就会有丢失的风险

​ 2)写操作命令执行成功后才记录AOF体制,所以不会阻塞当前命令的执行,但是可能给下一个命令带来阻塞风险,因为写入内存和写入磁盘的命令都是主进程完成的

1.2、三种写回策略

​ 用户态(执行写操作命令 -> 命令追加到server.aof_buf)—— I/O系统调用write —— 内核态(内核缓冲区page cache -> 由内核发起写操作 -> 硬盘)

具体实现步骤:

1、Redis执行完写操作后,会将命令追加到server.aof_buf缓冲区

2、通过write()系统调用,将aof_buf缓冲区的数据写入AOF文件,此时数据没有写入到磁盘,而是拷贝到内核缓冲区page cache,等待内核将数据写入硬盘;

3、具体内核缓冲区的数据什么时候写入到硬盘,由内核决定。

写回磁盘策略 => redis.conf配置文件中的appendsync三种参数可以填

1、Always:总是,每次执行完写命令操作后,同步将AOF日志数据写回磁盘

2、Everysec:每秒,每次执行完写操作后,现将命令写入到AOF文件到内核缓冲区,每隔一秒将缓冲区的内容写回磁盘

3、NO:交给操作系统,命令写入AOF内核缓冲区,由操作系统决定什么时候写回磁盘

在这里插入图片描述

​ 这三种写回策略其实就是什么时机执行fsync()函数,Always每次写入就执行;Everysec创建一个异步任务来执行;No就是永不执行。

1.3、AOF重写机制

​ AOF日志是一个文件,随着写操作命令越来越多,文件的大小会越来越大 => 为了避免AOF文件越写越大,提供了AOF重写机制,文件大小超过设定的阈值之后,Redis会启动AOF重写机制来压缩AOF文件。

​ 具体的做法是:读取当前数据库中的所有键值对,将每一个键值对用一条命令记录到新的AOF文件中,等到全部记录完之后,将新的文件替换到现在的AOF文件。相当于记录对某个键的最新值,删除掉旧值,减少了AOF日志的大小,所以重写需要重写到新的AOF文件中,失败的话,直接删除这个文件就好,不会对现有的AOF文件造成影响。

1.4、AOF后台重写

​ 重写的时候,这个过程是比较耗时的,所以重写的操作不能放在主进程里 => 重写AOF过程是由后台子进程bgwrriteaof来完成的,有两个好处:

​ 1)子进程重写AOF期间,主进程可以继续处理命令请求,从而避免阻塞主进程;

​ 2)子进程带有主进程的数据副本,注意不是线程,线程共享内存,会在修改共享内存数据的时候加锁,影响性能,而父子进程共享内存数据,以只读的方式,当父子进程任意一方修改了该共享内存,就会发生写时复制,于是父子进程就有了独立的数据副本,不需要加锁也可以保证数据安全。

实现过程

1、主进程fork()系统调用生成bgrewriteaof子进程,页表复制给子进程(虚拟地址和物理地址的映射关系),共享物理内存,内存的权限为可读

在这里插入图片描述

2、当父进程或子进程向这个内存发起写操作时,CPU就会触发写保护中断,进行物理内存的复制,重新设置映射关系,父子进程的内存读写权限设置为可读写,最后才对内存进行写操作 => 写时复制

在这里插入图片描述

3、存在两个阶段导致父进程阻塞:1)创建子进程,复制页面,页面太大,阻塞时间长;2)子进程或父进程修改共享数据,发生写时复制,拷贝物理内存,阻塞时间长。

4、可能出现的问题:

​ 1)在写时复制阶段,修改的是一个bigkey(数据量比较大的key-value),这个时候复制的物理内存数据的过程会比较耗时,有阻塞主进程的风险。

​ 2)主进程修改key-value,但是在子进程内存数据跟主进程数据不一致 => 设置AOF重写缓冲区,这个缓冲区在创建bgrewriteaof子进程就开始使用

在这里插入图片描述

​ 2)当子进程完成AOF重写工作的时候,发送信号给主进程 => AOF重写缓冲区的所有内容追加到新的AOF内容中,使得新旧AOF文件的数据库状态保持一致;将新的AOF文件进行改名,覆盖现有的AOF文件。

2、RDB快照是怎么实现的?

​ AOF文件的内容是操作命令(不是实际数据)、RDB文件的内容是二进制数据(某一个时刻的数据库实际数据);RDB恢复数据的效率比AOF高些,因为RDB文件读入内存就行,而AOF需要额外的执行操作命令步骤才能恢复数据。

2.1、快照怎么使用

1)save 命令,在主线程生成RDB文件,由于和执行操作命令在同一线程,所以如果写入RDB文件的时间太长,会阻塞主进程。

2)bgsave 命令,会创建一个子进程来生成RDB文件,这样避免主线程阻塞。

=> 可以配置每隔一段时间自动执行一次bgsave命令

save 900 1  // 900秒内,对数据库至少进行一次修改
save 300 10 // 300秒内,对数据库至少进行10次修改
save 60 10000 // 60秒内,对数据库至少进行10000次修改

2.2、执行快照时,数据能被修改吗?

可以的! => 关键技术:写时复制

​ 1)当主线程(父进程)对这些共享的数据只进行读操作的时候,是互不干扰的

​ 2)当主线程执行写操作的时候,就会发生写时复制,该数据块的物理内存就会被复制一份,然后主线程在这个数据副本进行修改操作,bgsave会在原来的数据写入到RDB文件。

​ 所以这样意味着子进程写入到RDB文件的数据只能是原本的内存数据,修改的部分交由下一次bgsave快照。

​ 极端情况:刚fork时,途中主进程处理了写操作,修改了共享内存,修改的数据的内存会被复制一份 => 极端情况下,内存的占用时原来的两倍。

2.3、RDB和AOF合体

​ RDB尽管数据恢复速度快,但是频率不好把握。

​ 1)频率太低,两次快照间一旦服务器发生宕机,就可能丢失较多数据;

​ 2)频率太高,频繁的写入磁盘和创建子进程会带来额外的性能开销。

=> 混合使用AOF日志和内存快照,亦称混合持久化 aof-use-rdb-preamble yes,工作在AOF日志重写过程

具体的做法是:(前半部分是RDB格式的全量数据 + 后半部分AOF格式的增量数据)

​ 1)AOF重写日志的时候,fork出来的重写子进程会先将与主线程共享的内存数据以RDB方式写入到AOF文件;

​ 2)然后主线程处理的操作命令会被记录在重写缓冲区里,重写缓冲区里的增量命令会以AOF方式写到AOF文件;

​ 3)写入完成后,将含有RDB格式和AOF格式的文件 替换 旧的AOF文件

3、Redis大key对持久化有什么影响?

3.1、大Key对AOF日志的影响

1、三种写回策略,在持久化大Key的时候,会有什么影响?

  • Always策略的时候,如果写入的是一个大Key,主线程在执行fsync()函数的时候,阻塞的时间会比较久,因为当写入数据量很大的时候,数据同步到硬盘这个过程是很耗时的。
  • Everysec策略,由于是异步执行fsync()函数,所以大key持久化过程不会影响到主线程。
  • No策略,永不执行fsync(), 所以大key持久化过程不会影响到主线程。

3.2、大Key对AOF重写和RDB的影响

​ 当AOF日志写入很多大Key,AOF日志文件的大小会很大,很快就会触发AOF重写机制。

​ AOF重写机制和RDB快照都会分别通过fork()函数来创建一个子进程来处理任务。

​ => info命令可以获取到latest_fork_usec指标,表示Redis最近一次fork操作的耗时,如果fork耗时很大,如超过1s需要做出调整

​ 1)单个实例的内存占用在10GB以下,fork很快就能返回

​ 2)Redis单纯做缓存,不关心Redis数据安全性问题,直接关闭AOF重写

​ 3)在主从架构,适当的调大repl-backlog-size,避免主节点频繁的使用全量同步的方式。

1、什么时候发生物理内存的复制?

​ 1)创建子进程途中,要复制父进程页表等数据结构

​ 2)当父进程或子进程向共享内存发起写操作,CPU就会触发写保护中断,写时复制

2、linux开启了内存大页,会影响redis性能

3、删除大key

​ 使用unlink命令(异步不阻塞),而不是用delete(会阻塞主进程)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/493412.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

自动驾驶行业观察之2023上海车展-----智驾供应链(2)

传感器供应链发展 图达通:展示长距Lidar“Falcon”,和DeepWay签署定点协议 产品:主视激光雷达 Falcon 猎鹰(2023CES曾亮相) 核心亮点: • 核心性能:最远探测距离可达 500 米,为智…

《计算机网络—自顶向下方法》 第一章Wireshark实验:Wireshark软件的安装和入门

要深入理解网络协议,需要仔细观察协议实体之间交换的报文序列。为探究协议操作细节,可使协议实体执行某些动作,观察这些动作及其影响。这些任务可以在仿真环境下或在如因特网这样的真实网络环境中完成。观察在正在运行协议实体间交换报文的基…

万字长文详解linux内存管理,值得收藏

一、Linux内存管理概述 Linux内存管理是指对系统内存的分配、释放、映射、管理、交换、压缩等一系列操作的管理。在Linux中,内存被划分为多个区域,每个区域有不同的作用,包括内核空间、用户空间、缓存、交换分区等。Linux内存管理的目标是最…

经典常用的脚本讲解

目录 一:echo 语句 二:while read命令​编辑 三:猴子摘香蕉问题 四:斐波拉切数求前10个数的和 ​五:随机生成8位数的密码 六:二进制转换 (1)余数倒排法 (2)减法正…

Google - ISLR 比赛总结

引言 本篇主要想总结一下最近打的GISLR比赛,本来是没想写的,比赛前期感觉赛题很有意思,做了eda以及根据一些base改了改自己的方案,取得了还不错的结果,但因为中途被各种琐事缠身,发生了很多变故&#xff0…

【Linux】Libevent库

Libevent——高性能I/O框架库 底层封装了select,poll,epoll,便于使用 I/O框架库以库函数的形式,封装了较为底层的系统调用,给应用程序提供了一组更便于使用的接口。 特点:1.跨平台,2.统一事件源…

c++面向对象之封装、继承、和多态

一、封装 把客观事物封装成类,而且可以把自己的数据和方法设置为只能让可信的类或者对象操作,对不可信的信息进行隐藏(利用public,private,protected,friend)实现 二、继承 2.1类与类的关系 has-a :描述一个类由多个部件类构成…

SpringCloud全面学习笔记之初尝美妙篇

目录 前言初识微服务单体架构分布式架构微服务架构初见SpringCloud微服务治理分布式服务架构案例 微服务组件及使用Eureka注册中心提供者和消费者Eureka的结构和作用搭建Eureka服务注册服务服务发现Eureka注册服务总结 Ribbon负载均衡原理负载均衡原理负载均衡策略懒加载 Nacos…

Qt quick基础2(包含平移旋转放缩以及qml控件大写开头啊)

Qt quick基础2(包含平移旋转放缩以及qml控件大写开头啊) 目录 Qt quick基础2(包含平移旋转放缩以及qml控件大写开头啊)前言简单的平移、旋转和放缩其他元素的一些基本使用qml文件作为控件时,务必以大写字母开头命名小结…

力扣题库刷题笔记682-棒球比赛

1、题目如下&#xff1a; 2、个人Python代码实现如下&#xff1a; 代码如下&#xff1a; class Solution: def calPoints(self, operations: List[str]) -> int: i 0 #用于遍历元素的下标 while i < len(operations): …

【Python入门篇】——Python基础语法(数据类型与数据类型转换)

作者简介&#xff1a; 辭七七&#xff0c;目前大一&#xff0c;正在学习C/C&#xff0c;Java&#xff0c;Python等 作者主页&#xff1a; 七七的个人主页 文章收录专栏&#xff1a; Python入门&#xff0c;本专栏主要内容为Python的基础语法&#xff0c;Python中的选择循环语句…

数据结构与算法导学

文章目录 数据结构和算法导学认识数据结构认识算法总结 数据结构和算法导学 程序 数据结构 算法 认识数据结构 什么是数据结构&#xff1f; 数据结构是一门研究计算机中数据存储和数据操作的学科。 为什么要学习数据结构&#xff1f; 学习数据结构能让我们写出更加优秀的代码…

关于在线帮助中心你需要思考以下几个问题

搭建帮助中心是大多数企业都在尝试做的事情&#xff0c;它的重要性对于企业来说不言而喻。现在对于企业来说&#xff0c;搭建帮助中心或许不是什么难事&#xff0c;但是关于帮助中心&#xff0c;有几个问题需要思考清楚&#xff0c;才能让其发挥最大的价值。 一、如何让用户养成…

CAS 原子操作类

CAS 原子类 java.util.concurrent.atomic 是什么 CAS compare and swap的缩写&#xff0c;中文翻译比较并交换&#xff0c;实现并发算法时常用的一种技术 它包含三个操作数–内存位置、预期原值及更新值 执行CAS操作时&#xff0c;将内存位置的值与预期原值比较 如果相匹…

网络协议与攻击模拟-05-ICMP协议

ICMP 协议 1、理解 ICMP 协议 2、理解 ICMP 重定向 3、会使用 wireshark 分析 ICMP 重定向流量实验 一、 ICMP 基本概念 1、 ICMP 协议 Internet 控制报文协议&#xff0c;用于在 IP 主机、路由器之间传递控制消息&#xff0c;控制消息指网络通不通、主机是否可达、路由是否…

荔枝派Zero(全志V3S)驱动开发之hello驱动程序

文章目录 前言一、设备驱动分类二、字符设备驱动简介三、字符设备驱动开发1、APP打开的文件在内核中如何表示2、编写驱动程序的步骤3、hello 驱动程序编写<1>、试验程序编写<2>、测试程序编写<3>、编写 Makefile<4>、编译 3、运行测试<1>、上传程…

PyTorch实战4:猴痘病识别

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f366; 参考文章&#xff1a;365天深度学习训练营-第P4周&#xff1a;猴痘病识别&#x1f356; 原作者&#xff1a;K同学啊|接辅导、项目定制 目录 一、搭建CNN网络结构1、原文网络结构1.1、网络…

4。计算机组成原理(2)存储系统

嵌入式软件开发&#xff0c;非科班专业必须掌握的基本计算机知识 核心知识点&#xff1a;数据表示和运算、存储系统、指令系统、总线系统、中央处理器、输入输出系统 这一部分主要讲解了CPU的组成和扩容、CPU与存储器&#xff08;主存、辅存、缓存&#xff09;的连接 一 存储…

C++笔记——第十六篇 异常

目录 1.C语言传统的处理错误的方式 2. C异常概念 3. 异常的使用 3.1 异常的抛出和捕获 在函数调用链中异常栈展开匹配原则 3.2异常安全 4.异常的优缺点 1.C语言传统的处理错误的方式 传统的错误处理机制&#xff1a; 1. 终止程序&#xff0c;如assert&#xff0c;缺陷&a…

飞腾ft2000-麒麟V10-SP1安装Docker、运行gitlab容器

目录 一、安装及配置docker 1、卸载docker相关包及删除相关配置文件 2、安装二进制docker 1.下载软件包 2.解压 3.修改镜像加速地址 4.修改profile文件 5.启动docker 6.docker常用命令 二、安装并启动gitlab镜像 1.安装gitlab镜像 1.查询满足使用需求的gitlab版本 2…