MySQL 缓存策略

MySQL 缓存方案用来干什么 ?

  • 缓存用户定义的热点数据,用户直接从缓存中获取热点数据,降低数据的写压力。
  • 场景分析
    • 内存访问速度是磁盘访问速度的 10 万倍。
    • 读的需求远远大于写的需求
    • MySQL 自身缓冲层跟业务无关
    • MySQL 作为项目主要数据库,便于统计分析。
    • 缓存数据库作为辅助数据库,存放热点数据

还有哪些方式提升 MySQL 访问性能

在这里插入图片描述

  • 读写分离
    • 是什么 ?
      • 设置多个从数据库,从数据库可能会在多个机器中。
      • 写操作依然在主数据库。
      • 主数据库提供数据的主要依据。
    • 解决了什么问题:从数据库主要解决读压力。
    • 原理:
      • 主从原理。
      • 异步复制:最终一致性;主从之间数据会有差异。
      • 如果读操作有一致性要求,读操作去读主数据库。
  • 连接池
    • 在服务端中创建多个与数据库的链接。
    • 解决了什么问题:并发提升数据库访问性能;复用连接资源,避免连接建立或断开、以及安全验证的开销。
    • 原理:MySQL 的网络模型:select;阻塞的 IO 模型。如果发送一个事务(多个 SQL 语句),这个事务必须在一个连接中执行。
  • 异步连接
    • 在服务端创建一个连接,针对这个连接采用非阻塞 IO。
    • 解决了什么问题:节省了网络传输时间。
    • 原理:使用了非阻塞 IO。

MySQL 缓存方案

  • Redis 缓存和 MySQL 一致性状态分析
    • MySQL 有,Redis 无。
    • MySQL 无,Redis 有。(错误状态)
    • 都有,数据不一致。(错误状态)
    • 都有,数据一致。
    • 都没有
  • 制定用户定义的热点数据读写策略
    • 读:先读 Redis 缓存,缓存存在直接返回;缓存不存在,去访问 MySQL 获取,再写 Redis。
    • 写:
      • 以安全为主
        • 先要删除 Redis 中的数据,然后再写 MySQL,最后将 MySQL 数据同步到 Redis。
        • 问题:缓存方案的主要目标是提升效率,而现在为了安全降低效率。
        • 只有一种情况使用:读远大于写。
      • 以效率为主
        • 先写 Redis 缓存并设置过期时间,再写 MySQL,等待 MySQL 同步到 Redis 中。
        • 过期时间选择:与 MySQL 网络传输时间 + MySQL 处理时间 + MySQL 同步到 Redis 的时间有关。
        • 安全问题:比如设置了过期时间为 200ms,在 200ms 窗口时间内,其它请求可能读到的是脏数据。

MySQL 主从复制

在这里插入图片描述

  • 工作原理:
    • 主库 DML 操作(增删改操作)通过 io-thread 写到 binlog。
    • 从库请求读取 binlog,通过 io-thread 写入从库本地 relay-log(中继日志)。
    • 从库通过 sql-thread 读取 relay-log,并把更新事件在从库重放(replay)一遍。
  • 复制流程:
    • Slave 中的 IO 线程连接上 Master,并请求从指定日志文件的指定位置之后的日志内容。
    • Master 接收到来自 Slave 的 IO 线程的请求后,负责复制的 IO 线程会根据请求信息读取日志指定位置之后的日志信息,返回给 Slave 的 IO 线程。返回信息中包含日志信息、Master 端 binlog 文件的名称、下次读取 Master 端 binlog 文件中的起始位置。
    • Slave 的 IO 线程接收到消息后,将接收到的日志内容依次添加到 Slave 端的 relay-log 文件末尾,并将读取到的 Master 端的 binlog 文件名和下次读取 binlog 文件中的起始位置记录到 master-info 文件中,以便在下一次读取的时候能够清楚地告诉 Master 从何处开始读取日志。
    • Slave 的 SQL 进程在检测到 relay-log 中新增加了内容后,会马上解析 relay-log 的内容为在 Master 端真实执行时的可执行内容,并在自身执行(重放)。

如何把 MySQL 的数据同步到 Redis ?

在这里插入图片描述

  • 额外增加一个中间件(go-mysql-transfer),该中间件伪装成 MySQL 的从数据库,不断地从 MySQL 中拉取数据(binlog)并进行解析,解析之后写到 Redis 中。(基于 MySQL 主从复制的原理,但是不会重放)
git clone https://gitee.com/mirrors/go-mysql-transfer

缓存方案的故障问题及解决

缓存穿透

  • 数据在 Redis 和 MySQL 中都没有,一直读取不存在的数据,造成 MySQL 访问性能急剧降低。
    • 假设黑客恶意请求服务器不存在的数据,此时 Redis 形同虚设,那么所有的请求压力都会堆积在 MySQL 中,相当于请求穿透了 Redis 直接到了 MySQL,造成 MySQL 访问性能急剧降低。
  • 解决
    • 在 Redis 中缓存不存在的热点数据为 <key, nil>,服务器每次读到 “nil” 字符串的时候,说明整个存储系统都没有这个数据,当客户端再次请求这个数据时,服务器可以直接返回。
      • 缺点: 如果黑客不断地随机出新的 key,那么 Redis 就会写很多不存在的 <key, nil>,可能会把 Redis 的内存撑爆(Redis 不怕请求多,而是怕内存不够)。
    • 部署布隆过滤器:布隆过滤器可以确定一个 key 是否存在。
      • 布隆过滤器要部署到 Redis 中,而不是部署到服务器中(如果有多个服务器,那么每次都需要把热点数据写到每个服务器的布隆过滤器中,这样的话,就需要维护多个布隆过滤器,很麻烦)。
      • 缺点:布隆过滤器只能增加数据,不能删除数据。

缓存击穿

  • 数据在 Redis 中没有,在 MySQL 中有,大量并发连接请求,造成 MySQL 访问性能急剧降低。
  • 解决
    • 分布式锁:请求数据的时候获取锁,若获取成功,则操作后释放锁;若获取锁失败,则休眠一段时间(200 ms)再去获取锁。
      • 服务器 A 先访问 Redis(要获取锁),发现数据不存在,然后访问 MySQL,发现数据存在,将数据同步给 Redis(要释放锁),后面的服务器 B、服务器 C 就可以直接从 Redis 中获取数据。
    • 将很热的 key 设置为不过期。

缓存雪崩

  • 大量缓存数据集中失效,但是数据在 MySQL 中存在,造成 MySQL 访问性能急剧降低。
  • 解决
    • 将很热的 key 设置为不过期。
    • 间隔设置过期时间。
    • 重启时,预先导入热数据到缓存(预热)。

缓存方案的弊端

  • 不能处理多语句的事务。
    begin;
    start transaction;
    sql1;
    sql2;
    commit;
    
  • Redis 不支持回滚。
  • 最终解决方案:分布式关系型数据库 TiDB

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

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

相关文章

Vue教学14:动态组件与异步组件,提升应用的灵活性与性能

大家好&#xff0c;欢迎回到我们的Vue教学系列博客&#xff01;在前十三篇博客中&#xff0c;我们学习了Vue.js的基础知识、安装Node.js与npm、使用Vue Devtools进行调试、Vue实例与生命周期钩子、数据绑定&#xff08;单向与双向&#xff09;、计算属性与侦听器、条件渲染和列…

Cookie 探秘:了解 Web 浏览器中的小甜饼

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

C++ 之LeetCode刷题记录(三十八)

&#x1f604;&#x1f60a;&#x1f606;&#x1f603;&#x1f604;&#x1f60a;&#x1f606;&#x1f603; 开始cpp刷题之旅。 目标&#xff1a;执行用时击败90%以上使用 C 的用户。 18. 四数之和 给你一个由 n 个整数组成的数组 nums &#xff0c;和一个目标值 target…

【嵌入式Linux】ELF格式文件分析工具汇总

本文目录 概述分析工具**readelf****objdump****ldd****nm****strings****gdb****dwarfdump****size****cfilt****elfinspect** 总结 概述 ELF是一种常见的二进制文件格式&#xff0c;Linux系统所有的可执行程序和共享库都是ELF格式。 分析工具 在Linux下&#xff0c;分析EL…

CRM是什么?SaaS是什么?CRM和SaaS有什么关系?

CRM是什么&#xff1f;SaaS是什么&#xff1f;CRM和SaaS有什么关系&#xff1f; 接下来&#xff0c;我们就来好好唠唠CRM和SaaS。 下文提到的一款典型SaaS CRM模版先放在这儿了&#xff0c;有需要的可以自取——https://www.jiandaoyun.com 先来波名词解释吧 CRM是什么&#…

嵌入式通信数据经常说的大端和小端模式(学习)

一.概念 大端模式&#xff08;Big-endian&#xff09;&#xff1a;高位字节排放在内存的低地址端&#xff0c;低位字节排放在内存的高地址端&#xff0c;即正序排列&#xff0c;高尾端&#xff1b; 小端模式&#xff08;Little-endian&#xff09;&#xff1a;低位字节排放在…

大数据开发(Hadoop面试真题-卷六)

大数据开发&#xff08;Hadoop面试真题&#xff09; 1、MapReduce为什么一定要有环型缓冲区&#xff1f;2、MapReduce为什么一定要有Shuffle过程&#xff1f;3、Reduce怎么知道去哪里拉Map结果集&#xff1f;4、MapReduce Shuffle的排序算法&#xff1f;5、MapReduce shuffle为…

基于springboot的场地预约小程序的设计与实现(程序+数据库+文档)

** &#x1f345;点赞收藏关注 → 私信领取本源代码、数据库&#x1f345; 本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#xff0c;希望你能有所收获&#xff0c;少走一些弯路。&#x1f345;关注我不迷路&#x1f345;** 目录 一、研…

《操作系统真相还原》读书笔记二:环境搭建 xshell连接virtualbox

修改 sshd_config 使用 vi /etc/ssh/sshd_config命令进入sshd服务配置&#xff0c;键盘输入i进行编辑&#xff0c;将监听端口、监听地址前的 # 号去除&#xff0c;开启允许远程登录&#xff0c;开启使用用户名密码来作为连接验证。修改完成&#xff0c;按一下Esc&#xff0c;输…

网络原理初识(1)

目录 一、网络发展史 1、独立模式 2、网络互联 3、局域网LAN 局域网组建的方式 1、基于网线直连 2、基于集线器组建 3、基于交换机组建 4、基于交换机和路由器组建 4、广域网WAN 二、网络通信基础 1、IP地址 2、端口号 3、认识协议 4、五元组 一、网络发展史 1、独立模式 …

Linux环境下多个python版本的使用方法

1、查看python 解释器的安装位置 which python3 which python22、使用pip命令查看安装包 在确认Pyhton解释器的安装位置之后&#xff0c;我们可以使用pip命令来查看安装的包。pip是Python的包管理工具&#xff0c;可以用于安装、升级、卸载Python包。 pip list pip3 list pi…

Jmeter事务控制器聚合报告

Jmeter 事务控制器。 在Jmeter中&#xff0c;默认一个取样器就是一个事务事务控制器控制其子集取样器&#xff0c;合并为一个事务 添加&#xff1a;逻辑控制器/Logic Controller -> 事务控制器/Transaction Controller TPS: 服务器每秒处理的事务数在事务控制器下添加多个…

牛客网 华为机试 进制转换

本题是要将十六进制的字符串转换成十进制。看到题目第一眼就想到用map进行十六进制和十进制的映射。 然后我们需要注意&#xff0c;字符串前面会有0X&#xff0c;这只是一个标识十六进制的标识符&#xff0c;没有具体数字意义&#xff0c;我们在转换的时候&#xff0c;需要把它…

【视频转码】基于RK3588的视频转码探索

传统的视频转码服务基本都是基于X86下CPU、GPU转码&#xff0c;对硬件性能、功耗、成本来说都比较高。从技术角度来说现有视频转码技术有&#xff1a; 视频编码转变&#xff1a; 1. H.264 > H.265 保持视频分辨率、清晰度不变情况下&#xff0c;更改视频压缩方式&#xff0…

2024Java面试题知识点总结,一名毕业三年的女程序媛面试头条经验

程序员&#xff1a;给多少工资&#xff0c;干多少事 我们不是经常会看到一个关于西游记的“悖论”吗&#xff1a; 为什么孙悟空初期大闹天宫的时候那么厉害&#xff1f;因为他自己当老板&#xff0c;打一群天庭的打工仔。 为什么取经路上又变得不行了&#xff1f;作为一个打工…

牛客网 华为机试 取近似值

本题是要实现四舍五入。我们采用float的数据类型&#xff0c;因为这样数据精度更高。然后我们可以把得到的数据0.5&#xff0c;然后再转换成int数据类型&#xff0c;因为转换成int数据类型的时候是向下取整的&#xff0c;比如4.9转换成int就是4&#xff0c;4.2转换成int也是4。…

【Redis】高级特性 - 有序集合

文章目录 1. 有序集合的基本概念2. 使用场景2.1 排行榜2.2 时间轴2.3 范围查找 3. 基本操作3.1 添加成员3.2 查找成员排名3.3 查找成员分数3.4 范围查找3.5 删除成员 4. 示例演练4.1 添加成员和分数4.2 查找成员排名和分数4.3 查找排行榜4.4 删除成员 5. 有序集合的应用之美 在…

微服务笔记

什么是微服务? 微服务是一种经过良好架构设计的分布式架构方案&#xff0c;微服务架构特征: 1.单一职责:微服务拆分粒度更小&#xff0c;每一个服务都对应唯一的业务能力&#xff0c;做到单一职责&#xff0c;避免重复业发。 2.面向服务:微服务对外暴露业务接口 3.自治:团…

代码随想录算法训练营第52天| 300.最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组

300.最长递增子序列 完成 思路&#xff1a; 本题dp[i]代表[0,i]数组的最长递增子序列&#xff0c;一开始的想法也是两层for循环&#xff0c;但总觉得这题不该这么烦。然后看了随想录的题解&#xff0c;也是两层for循环&#xff0c;所以有了想法就要去尝试。 本题初始化也是个…

react中tab选项卡切换

react中tab选项卡切换&#xff0c;直接上代码&#xff0c;简单易懂 jsx代码 /* eslint-disable react-hooks/exhaustive-deps */ import React, { useEffect, useState } from "react"; import DocumentTitle from react-document-title import styles from ./…