MySQL的缓存策略

目录

一、MySQL 缓存方案用来干什么

二、提升MySQL访问性能的方式

1、读写分离(MySQL的主从复制)

2、连接池

3、异步连接

三、缓存方案是怎么解决的

1、缓存与MySQL一致性状态分析

2、制定热点数据的读写策略

四、缓存方案问题的解决方法

1、缓存穿透

2、缓存击穿

3、缓存雪崩

五、缓存方案的弊端


一、MySQL 缓存方案用来干什么

用来缓存用户定义的热点数据,用户直接从缓存获取热点数据,降低数据库的读写压力

我们都知道内存的读取速度是磁盘访问速度的十万倍,那么这个缓存方案适用于什么场景呢?

1、既然读取速度这么高,那么肯定就是读的需求远大于写的需求。

2、MySQL自身的缓冲层跟业务无关。MySQL中的缓存层也是用来缓存热点数据,但是这些数据包括索引、记录等。mysql 缓冲层是从自身出发,跟具体的业务无关,而不是缓存我们用户自己定义的热点数据

3、因此我们采用Redis作为我们的缓冲数据库,存放用户定义的热点数据。而MySQL只是作为项目的主要数据库,便于统计分析。

二、提升MySQL访问性能的方式

1、读写分离(MySQL的主从复制)

        什么是读写分离?我们设置多个从数据库,从数据库分布在多个不同的机器中,我们写的操作依然是在主数据库,而读的操作分给了从数据库,从数据库的数据都是来自主数据库。这样将读写进行分离,会解决主数据库读的压力。

        我之前的文章讲过主从之间如何进行同步。我们得知主从之间可能会存在数据不一致的情况,但是最终的数据是一样的,也就是可能会有延迟。比如博主写了一篇文章并且刚刚发布,但是我的朋友说还没有看到,我说你等个几秒就好了。对于这种情况就很适合这种方案(读取从数据库)。

        但是对于读的时效性很强的时候(一致性),我们就不可以读取从数据库了,而是直接读取主数据库。

2、连接池

        在MySQL中存在连接池的组件,比如两个客户端连接上来,但是我们使用多个线程去服务这几个客户端,可以大大提高并发访问数据库的能力,并且,连接池的资源是可以复用的,我们可以避免连接建立或断开,以及安全验证的开销。

        他的网络模型采用的并不是Reactor,而是select+阻塞io模型。对于上面所说的多个线程服务客户端,这里要特别注意,如果我们开启一个事务的话,一个事务内不是包含很多SQL语句嘛,我们要保证这些事务语句全部在一个线程内执行。

3、异步连接

        我们上面的连接池中讲到了网络模型采用的是 select + 非阻塞IO 。如果是阻塞IO的话也就是同步方式,我们发送多个SQL语句的话,他需要一个一个进行执行并且一个一个进行返回。

        但是我们采用异步的方式(非阻塞IO),我们发送多个命令,那么这些命令会异步执行,谁执行完毕,谁就通过回调函数进行返回,大大节省网络传输的时间。

三、缓存方案是怎么解决的

1、缓存与MySQL一致性状态分析

可行方案不可行方案
MySQL有,Redis无MySQL无,Redis有
都有,数据一致都有,数据不一致
都没有

        我们根据上面所讲述的主从复制,可以得知,MySQL中必须保存全部的数据,而Redis从数据库只是保存热点数据。那么我们来讨论上面这个表格的情况。

        可行方案中:MySQL有,Redis无。MySQL没有热点数据需要进行存储,所以Redis中没有数据,也就是说,用户查找的这个数据并不是热点数据。

        第二种方案:都有,数据一致。MySQL中包含热点数据,而且Redis中也包含热点数据,并且是一致的数据。这样我们查找从数据库的时候,就不会出现与主数据库查询不同的情况了。

        第三种:都没有。也就是说用户查找的这个数据是不存在的,所以在MySQL中也不存在。

        不可行方案:MySQL无,Redis有。我们讲的主从复制,需要保证写数据是写在主数据库中的,所以主数据库包含全部的信息,而从数据库是从主数据库中进行同步的。所以这种情况是不允许的。

        不可行方案:都有,数据不一致。我们讲的主从复制中也说到了从数据库与主数据库进行同步可能会有延迟,但是最终数据是一致的。这样就会导致我们可能读取从数据库的时候(读取热点数据)可能会导致与主数据库的数据不一致。

2、制定热点数据的读写策略

        对于读的策略比较简单,由于是热点数据,我们直接读取缓存(Redis),如果在Redis中找到了数据,那就直接返回。如果未找到,那就读取MySQL,如果在MySQL中读到数据,并且返回后,那就写入Redis。这里写入Redis中的是热点数据,并不是说,一查没有,一查没有,就全部写入Redis中。

写的策略分两种,一种是安全为主,一种是效率为主。

        如果要以安全为主,我们就要避免主数据库和从数据库读取的数据不同的问题。当我们先写入MySQL后,必然会出现MySQL与Redis数据不同的问题,那么我们就不能先写入MySQL。而是要先删除Redis中的数据,然后再写入MySQL,最后将MySQL中的数据同步到Redis中去,这样就保证两方的数据一致了。但是我们的缓存方案就是为了提升效率,现在却为了安全而降低了效率,这是我们不愿看到的。

        如果要以效率为主,我们可以先写入缓存,并且设置过期时间(大约是200毫秒),然后再写入MySQL,当写入MySQL后,我们再将MySQL中的数据同步到Redis中去。当同步到Redis中去的时候,这个过期时间也就到期了。过期时间是与MySQL网络传输时间+MySQL处理时间+MySQL同步到Redis的时间。有个问题是如果当写入MySQL写入失败,这个时候Redis中含有数据,那么他就会提供脏数据。但是这个问题也就200毫秒的存活时间,因为从数据库会找主数据库进行同步。

四、缓存方案问题的解决方法

1、缓存穿透

        问题:如果黑客让客户端一直读取MySQL和Redis中都不存在的数据,那么所有的读取操作都落在了MySQL中,那么就会造成MySQL中访问的性能急剧降低。

        解决:如果在Redis和MySQL中读取的数据都不存在,那么就在Redis中设置一个<Key,nil>,代表查找的这个热点数据不存在。或者部署布隆过滤器(类似于哈希表),使这些数据只能增加,不能删除,具体可以搜一搜。

2、缓存击穿

        问题:如果Redis中没有,但是MySQL中有,也就是说本来一个热点数据,在Redis中存在,但是过期了,那么大量的并发请求读取操作就会落到MySQL中,这样就造成MySQL访问的性能急剧降低。

        解决:我们可以将过热的数据设置成不过期的状态。或者是添加分布式锁,将并发的请求操作,变成串行执行。

3、缓存雪崩

        问题:我们在写入Redis中的数据是需要加入过期时间的,但是当我们不小心将多个过热数据的过期时间设置成统一时间,就会面临大量热点数据集中失效的问题,虽然失效,但是在MySQL中还是存在这个数据,所以大量的请求读取操作就会落到MySQL中去,就会造成MySQL访问性能急剧降低。

        解决:我们可以将这个过期时间给错开,避免同时过期。当然我们可以在重启MySQL的时候,先将一些热数据先缓存到Redis中。

五、缓存方案的弊端

        我们上面讲到一个问题就是,不能支持多语句的事务,如果要支持的话,需要保证begin到commit之间的全部语句都在一条线程中执行。而且Redis不支持回滚,并且有时候会造成Redis与MySQL数据不一致。

感谢大家的观看!0voice · GitHub

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

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

相关文章

酸枣病虫害智能化防控系统的探索与实践,基于YOLOv5全系列【n/s/m/l/x】参数模型开发构建枣类作物种植场景下酸枣病虫害智能检测识别系统

智慧农业&#xff0c;作为现代农业的高级形态&#xff0c;通过集成物联网、大数据、人工智能等先进技术&#xff0c;实现了农业生产过程的精准化、智能化管理。在酸枣等经济作物的种植过程中&#xff0c;病虫害的及时监测与防控直接关系到作物的产量与质量&#xff0c;进而影响…

react hooks--React.memo

基本语法 React.memo 高阶组件的使用场景说明&#xff1a; React 组件更新机制&#xff1a;只要父组件状态更新&#xff0c;子组件就会无条件的一起更新。 子组件 props 变化时更新过程&#xff1a;组件代码执行 -> JSX Diff&#xff08;配合虚拟 DOM&#xff09;-> 渲…

Knife4j 一款基于Swagger的开源文档管理工具

一、简单介绍 1.1 简介 Knife4j 是一款基于Swagger的开源文档管理工具&#xff0c;主要用于生成和管理 API 文档 二、使用步骤&#xff1a; 2.1 添加依赖&#xff1a; <dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spr…

spark之不同序列化对比

一&#xff0c;spark的rdd的序列话不同介绍 下面是使用不同序列化后的占用资源和数据大小 2&#xff0c;sparksql中序列化的区别 sparksql中使用序列化和不使用差别不大&#xff0c;英文sparksql中默认使用了encode自己实现的序列化方法&#xff0c;加上与不加序列化差别不大…

编译成功!QT/6.7.2/Creator编译Windows64 MySQL驱动(MSVC版)

相邻你找了很多博文&#xff0c;都没有办法。现在终于找到了正宗。 参考 GitHub - thecodemonkey86/qt_mysql_driver: Typical symptom: QMYSQL driver not loaded. Solution: get pre-built Qt SQL driver plug-in required to establish a connection to MySQL / MariaDB u…

.whl文件下载及pip安装

以安装torch_sparse库为例 一、找到自己需要的版本&#xff0c;点击下载。 去GitHub的pyg-team主页中找到pytorch-geometric包。网址如下&#xff1a; pyg-team/pytorch_geometric​github.com/pyg-team/pytorch_geometric 然后点击如图中Additional Libraries位置的here&am…

Leetcode Hot 100刷题记录 -Day18(反转链表)

反转链表&#xff1a; 问题描述&#xff1a; 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1]示例 2&#xff1a; 输入&#xff1a;head [1,2] 输出&a…

基于阿里云免费部署Qwen1-8B-chat模型并进行lora参数微调从0到1上手操作

文章目录 一、申请资源二、创建实例三、克隆微调数据四、部署Qwen1-8B-chat模型1、环境配置2、模型下载3、本地模型部署 五、模型微调1、拉取Qwen仓库源码2、微调配置3、合并微调参数4、本地部署微调模型 一、申请资源 阿里云账号申请PAI资源详细教程我已于部署ChatGLM3时写过…

双立方(三次)卷积插值

前言 图像处理中有三种常用的插值算法&#xff1a; 最邻近插值 双线性插值 双立方&#xff08;三次卷积&#xff09;插值 其中效果最好的是双立方&#xff08;三次卷积&#xff09;插值&#xff0c;本文介绍它的原理以及使用 如果想先看效果和源码&#xff0c;可以拉到最底…

关于若尔当矩阵中过渡矩阵的求法

关于若尔当矩阵中过渡矩阵的求法 豆瓜爱数学 ​关注 桜井雪子 等 114 人赞同了该文章 本文主要介绍考研中常考的另一类问题&#xff0c;当我们确认一个Jordan标准形时&#xff0c;对于过渡矩阵如何确定&#xff1f;这个常常是我们复习过程中容易忽略的一部分内容&#xff0c;…

物联网——USART协议

接口 串口通信 硬件电路 电平标准 串口参数、时序 USART USART主要框图 TXE: 判断发送寄存器是否为空 RXNE: 判断接收寄存器是否非空 RTS为输出信号&#xff0c;用于表示MCU串口是否准备好接收数据&#xff0c;若输出信号为低电平&#xff0c;则说明MCU串口可以接收数据&#…

简单题69.x的平方根 (Java)20240919

问题描述&#xff1a; java代码&#xff1a; class Solution {public int mySqrt(int x) {if (x < 2) {return x; // 0 和 1 的平方根分别是它们自己}int left 2; // 从2开始&#xff0c;因为0和1已经处理了int right x / 2; // 最大可能的平方根不会超过 x / 2int mid;w…

列表、数组排序总结:Collections.sort()、list.sort()、list.stream().sorted()、Arrays.sort()

列表类型 一.Collections.sort() Collections.sort()用于List类型的排序&#xff0c;其提供了两个重载方法&#xff1a; 1.sort(List<T> list) &#xff08;1&#xff09;List指定泛型时只能指定引用数据类型&#xff0c;也就是说无法用于基本数据类型的排序。 &am…

Matlab R2024B软件安装教程

一、新版本特点 MATLAB R2024B版本带来了众多新特性和改进&#xff0c;旨在提升用户的内容创作体验和工程效率。以下是该版本的一些主要特点&#xff1a; 1. 性能提升和优化&#xff1a;R2024B版本在性能上进行了显著优化&#xff0c;无论是在提问、回答问题、发布新技巧还是…

el-table 的单元格 + 图表 + 排序

<el-table border :data"tableDataThree" height"370px" style"width: 100%"><el-table-column :key"activeName 8" width"50" type"index" label"序号" align"center"></el…

JS实现树形结构数据中特定节点及其子节点显示属性设置的技巧(可用于树形节点过滤筛选)

大家好&#xff0c;今天我要分享的是如何在树形结构的数据中&#xff0c;根据特定条件设置节点及其所有子节点的显示属性。在实际项目中&#xff0c;这种需求非常常见&#xff0c;特别是在需要动态展示和隐藏节点的情况下。下面我将通过一个具体的示例来讲解实现过程。 需求分析…

【网络安全 | 靶机搭建】解决虚拟机联网问题(NAT模式)

背景:在电脑上下载并使用VMware虚拟机后,重装VMware时可能会遇到虚拟机无法联网的问题(例如,ping www.baidu.com 无法通畅)。这种情况可能是网络适配器被删除导致的。 本文将通过添加网络、安装网络适配器以及切换网络连接方式等步骤解决虚拟机的联网问题,具体步骤如下:…

Android Retrofit源码分析(一):Retrofit是什么?和OkHttp的区别是什么?为什么需要他?

目录 一、Retrofit是什么? Retrofit是一个基于OKHttp的RESTful网络请求框架,由Square公司开源,专为Android和Java提供类型安全的HTTP客户端。它可以理解为OKHttp的加强版,底层封装了OKHttp,主要负责网络请求接口的封装,使得网络请求工作更加简洁高效。 简单来说,Retro…

ElementUI 布局——行与列的灵活运用

ElementUI 布局——行与列的灵活运用 一 . 使用 Layout 组件1.1 注册路由1.2 使用 Layout 组件 二 . 行属性2.1 栅格的间隔2.2 自定义元素标签 三 . 列属性3.1 列的偏移3.2 列的移动 在现代网页设计中&#xff0c;布局是构建用户界面的基石。Element UI 框架通过其强大的 <e…

0x08 MotionEye 视频监控组件 list 信息泄漏洞 CVE-2022-25568

参考&#xff1a; MotionEye 视频监控组件 list 信息泄漏洞 CVE-2022-25568 | PeiQi文库 (wgpsec.org) 一、漏洞描述&#xff1a; motionEye是用Python写的motion的Web前端&#xff0c;它可以监视视频信号并检测运动。它可以与多种类型的摄像机配合使用,也可以与电影文件一起…