当前位置: 首页 > java >正文

4.2.4 MYSQL的缓存策略

文章目录

  • 4.2.4 MYSQL的缓存策略
      • 1. MYSQL缓存方案用来干什么
    • 2. 缓存相关知识
      • 1. mysql主从复制
      • 2. 为什么需要缓冲层
      • 3. 还有哪些类型数据库
    • 3. 那些方式会提升MYSQL读写性能
      • 1. mysql读写分离
      • 2. 连接池
      • 3. 异步连接
    • 4. 缓存方案是怎么解决的
      • 1. redis和MYSQL一致性状态分析
        • 1. 流程:先读缓存,有直接返回(不需要访问mysql),没有,访问mysql,有返回并同步到缓存,没有就是整个系统都木有
        • 2. 写策略:
      • 2. 同步方案
    • 5. 缓存方案问题以及解决
      • 1. 缓存穿透
      • 2. 缓存击穿
      • 3. 缓存雪崩
    • 6. 缓存方案的弊端
      • 1. 不能处理多语句任务
      • 2. redis不支持回滚
      • 3. redis和mysql不一致问题

4.2.4 MYSQL的缓存策略

1. MYSQL缓存方案用来干什么

主要用于提高查询性能、减少磁盘 I/O 和 CPU 消耗,使得频繁访问的数据可以从内存中快速获取,从而大幅提升数据库响应速度

2. 缓存相关知识

MySQL 的缓存方案是指其在数据库运行过程中,使用内存缓存机制来优化查询性能、减少磁盘 I/O 和提升吞吐能力的一整套技术组合

1. mysql主从复制

MySQL 主从复制是指一个 主库(Master) 将数据的更新操作同步到一个或多个 从库(Slave) 的机制。

工作流程(基于异步复制为例)

Client  → 写操作 → Master(主库)↓ 产生 binlog(二进制日志)↓ 从库通过 I/O 线程读取 binlogSlave(从库) → SQL 线程重放 binlog → 数据同步
阶段描述
1. 主库记录 binlog所有写操作都会写入 binary log 日志
2. 从库 I/O 线程读取 binlog从库连接主库,读取 binlog 并保存为 relay log(中继日志)
3. 从库 SQL 线程执行 relay log将 relay log 转为 SQL 在从库中执行,实现数据同步

2. 为什么需要缓冲层

缓冲层,本质上是指在系统和慢速设备(如磁盘)之间加一个高速中间存储区域(一般在内存),目的是提高系统整体性能和减少资源消耗

读多写少,单个主节点能支撑项目数据量;数据的主要依据是 mysql;但是磁盘 I/O 很慢

3. 还有哪些类型数据库

除了关系型数据库(Relational Database,简称 RDBMS,如 MySQL、PostgreSQL、Oracle 等)之外,还有以下几类非关系型数据库(NoSQL 数据库)和新兴数据库类型,它们各有特点、应用场景不同:
一、非关系型数据库(NoSQL)

  1. 键值型(Key-Value)数据库
    结构:键 => 值(value 可为任意类型,如字符串、JSON、二进制等)
    优点:超高性能、适合缓存、简单的数据模型
    应用:缓存、会话管理、分布式存储
    常见代表:
    Redis(内存数据库,支持持久化)
    Memcached(高性能但不支持持久化)

  2. 文档型数据库
    结构:存储类似 JSON 的文档结构,字段可以灵活变化
    优点:灵活、适合快速开发、支持嵌套数据结构
    应用:内容管理、社交平台、日志系统
    常见代表:
    MongoDB
    CouchDB

  3. 列族型(列式)数据库
    结构:按列存储数据而非按行,适合处理大规模分析类数据
    优点:高压缩率、高查询效率(适合 OLAP)
    应用:大数据仓库、日志分析
    常见代表:
    Apache HBase(基于 Hadoop HDFS)
    Cassandra
    ClickHouse

  4. 图数据库
    结构:节点(Node)+ 边(Edge)+ 属性(Properties)
    优点:擅长表达关系、关系计算快
    应用:社交网络、推荐系统、知识图谱
    常见代表:
    Neo4j
    JanusGraph

二、新型数据库类型

  1. 时序数据库(Time Series DB)
    专门用于处理时间序列数据(指标监控、IoT、金融数据)
    常见代表:InfluxDB、TimescaleDB

  2. 多模型数据库
    同时支持多种模型(文档 + 图 + 关系等)
    常见代表:ArangoDB、OrientDB

  3. NewSQL
    结合关系型数据库的事务与 NoSQL 的扩展性
    常见代表:TiDB、CockroachDB

3. 那些方式会提升MYSQL读写性能

1. mysql读写分离

读写分离是指:主库处理写操作、从库处理读操作,实现负载均衡和高并发能力。结合主从复制,从库有与主库一致的数据,应用程序通过中间件或代码逻辑将写请求路由到主库,读请求路由到从库
架构图示:

              +-----------+|   应用层  |+-----------+/       \写操作  /         \ 读操作+----+     +----+|主库| --> |从库|+----+     +----+

2. 连接池

数据库连接是“重量级资源”,频繁创建和关闭连接会耗费大量时间。连接池通过复用连接,大幅提升性能

优点:

  1. 减少连接建立/销毁的时间开销
  2. 控制最大连接数,防止数据库过载
  3. 支持连接健康检查、空闲回收等机制

3. 异步连接

传统数据库操作是同步阻塞的,异步连接可以使应用非阻塞执行 SQL 查询,提升响应效率:

  1. 应用线程发出 SQL 后不等待数据库返回,而是立即执行其他逻辑
  2. 数据库结果准备好后,通过回调或事件通知处理
  3. 适合高并发场景,如 Web 服务、异步任务处理

4. 缓存方案是怎么解决的

1. redis和MYSQL一致性状态分析

状态编号MySQL 状态Redis 状态问题
状态1缓存穿透,需从 DB 读取再写缓存
状态2读取到脏数据,严重一致性问题
状态3有(不一致)缓存未更新,读到旧数据,数据不一致
状态4有(一致)✅ 正确状态
状态5✅ 正确状态(比如刚初始化)

我们只希望有4,5两种状态,所以关键在于**:避免状态2、3,修复状态1**。

1. 流程:先读缓存,有直接返回(不需要访问mysql),没有,访问mysql,有返回并同步到缓存,没有就是整个系统都木有
2. 写策略:
  1. 安全为主(强一致)策略:先删缓存,再写数据库
1. 删除 Redis 缓存(del key)
2. 更新 MySQL 数据
优点:可以保证缓存是旧的,不会读到脏数据缺点:可能会在并发场景下造成缓存击穿(刚删缓存就被读了)
  1. 效率为主(最终一致)策略:先写 DB,再异步更新缓存
1. 更新 MySQL 数据
2. 异步更新 Redis(如消息队列触发、延迟任务)
优点:效率更高,适合读多写少的场景缺点:存在数据瞬时不一致风险

前提是业务可容忍短时间的不一致

2. 同步方案

同步方案描述适用场景
延迟双删更新数据库后删缓存两次(间隔一段时间)强一致要求较高
消息队列同步DB 更新后写入 MQ,异步刷新缓存写多、缓存更新频繁场景
订阅 binlog监听 MySQL binlog,变更时更新缓存大型系统,使用 Canal/Debezium
定时刷新定时任务刷新缓存数据缓存数据更新频率低场景

解释一下为什么要延迟双删:

线程A(查询请求)线程B(更新请求)
删除缓存(step 1)
读取缓存(发现没了)
从数据库读取旧数据
更新数据库为新数据(step 2)
将旧数据写入 Redis(step 3)

结果:Redis 又被写入了旧数据,造成数据不一致

5. 缓存方案问题以及解决

1. 缓存穿透

指查询一个数据库和缓存中都不存在的 key(比如恶意构造的 user_id=-1),每次请求都穿透缓存打到数据库,造成缓存形同虚设

解决方案:

  1. 布隆过滤器(推荐):拦截非法 key
  2. 空值缓存:将查询结果为 null 的 key 也存入 Redis,设置较短过期时间(如 1~5 min)

2. 缓存击穿

某个热点 key 过期瞬间,大量请求同时访问数据库,引发数据库压力骤增。此时可能造成数据库可能被击垮,出现服务雪崩。

解决方案:

  1. 互斥锁机制(分布式锁):只允许一个请求重建缓存,其他请求等待。
  2. 永不过期 + 异步更新:缓存不过期,后台定时刷新
  3. 逻辑过期:缓存结构中加时间戳,自主判断是否需要异步更新

3. 缓存雪崩

大量 key 在同一时间失效,导致请求同时访问数据库。造成数据库崩溃,系统短时间内无法恢复。

解决方案:

  1. 过期时间设置随机值(抖动):避免集中失效
  2. 热点数据预热:重启服务后预加载缓存
  3. 多级缓存:如本地缓存 + 分布式缓存

6. 缓存方案的弊端

1. 不能处理多语句任务

Redis 作为缓存系统,无法感知事务范围。例如涉及多表写入、回滚逻辑时,缓存不能自动同步状态

  • 重要业务仍以数据库为主,一致性关键数据优先从数据库读取

2. redis不支持回滚

Redis 的写入是立刻生效的,不像数据库那样支持事务回滚(ACID),一旦写入 Redis,后续数据库失败,可能出现缓存脏写

  • 采用「先删缓存,再更新数据库」的强一致策略
  • 通过 MQ 异步补偿缓存更新

3. redis和mysql不一致问题

网络延迟、并发覆盖、先写缓存再写 DB 等操作顺序问题

  • 延迟双删:先删缓存,再更新 DB,等待 DB 写入完成后再删缓存
  • MQ 或 Canal 同步 binlog
  • 增加缓存版本号机制(避免并发写入覆盖)
http://www.xdnf.cn/news/3074.html

相关文章:

  • C++中vector的扩容过程是怎样的?
  • ARP渗透学习1
  • 农村供水智能化远程监控解决方案
  • std::optional 类是个啥?
  • esp32将partitions.csv文件启用到工程项目中的配置
  • antd pro4 升级 antd5
  • 深入解析:实现一个详细的日志过滤器(LogFilter)
  • 2025年渗透测试面试题总结-拷打题库25(题目+回答)
  • 30天通过软考高项-第一天
  • 刀客doc:小红书商业技术负责人苍响离职
  • 信息系统项目管理师——第10章 项目进度管理 笔记
  • 解决Ollama run qwen3:32b: Error: unable to load model问题
  • 阵列麦克风降噪原理
  • 记录一个单独读取evt.bdf的方法
  • 头歌java课程实验(文件操作)
  • 【CF】Day46——Codeforces Round 967 (Div. 2) B
  • 2025年高级Java后端面试题:最新技术体系深度解析
  • java发送邮件
  • 运行不会存储上一次的命令;运行命令不保存历史记录
  • 算法备案类型解析:如何判断你的算法属于哪种类型?
  • conda添加新python版本环境,如何激活和销毁
  • 深入理解 Web Service:原理、组件与核心技术详解
  • c++ 内部类
  • linux使用亚马逊aws-sdk-cpp
  • 适合五一劳动节的SVG模版
  • C++/SDL 进阶游戏开发 —— 双人塔防(代号:村庄保卫战 15)
  • Windows多网卡设置路由冲突的解决
  • 程序员如何用AI工具实现“快速验证原型”
  • Rational Rose显示工具栏及添加工具栏中想要的工具(小人图标,用例图标)
  • 浏览器限制了cookie数量怎么办