mysql8.0移除查询缓存和替代方案介绍 一移除缓存的理由MySQL 8.0移除查询缓存的核心原因是‌其性能收益在现代硬件和高并发场景下已远低于维护成本‌具体原因如下‌锁竞争严重拖慢并发‌查询缓存的读写操作全程受全局互斥锁保护高并发场景下大量查询请求会被该锁阻塞反而成为性能瓶颈完全抵消了缓存命中带来的收益。‌缓存失效过于频繁‌只要表发生任何数据修改增删改该表对应的所有查询缓存就会被全部清空。在写入频繁的业务场景中缓存命中率极低几乎无法发挥作用。‌现代技术已替代其价值‌MySQL 8.0优化了InnoDB的缓冲池能高效缓存热数据页同时优化器的查询性能大幅提升再加上应用层的Redis等缓存方案查询缓存的存在意义已经完全被替代。‌维护成本过高‌查询缓存的代码逻辑复杂维护和优化难度大移除它可以大幅简化内核架构让研发资源集中投入到更有价值的性能优化方向上。总结6句话1对于经常更新的表缓存容易过期不容易控制2sql要完全一样才能命中缓存3为了节省空间4mysql缓存在分库分表的情况下是不起作用的5执行sql时候有触发器自定义函数缓存也是不起作用的6在表结构发生改变的时候缓存会失效二主流替代方案1. InnoDB缓冲池优化这是最核心的原生替代方案通过配置innodb_buffer_pool_size建议设为物理内存的50%~70%直接缓存热数据页和索引页大幅降低磁盘IO性能远优于旧版查询缓存。2. 应用层缓存使用Redis、Memcached等组件在业务代码中对高频查询结果做自定义缓存可灵活控制缓存失效规则完全规避表更新全清缓存的缺陷。3. 数据库代理层缓存通过MyCat、ProxySQL等中间件配置SQL结果缓存在代理层统一拦截重复查询无需修改业务代码即可实现类查询缓存效果。4. 优化器与索引优化通过添加合适的二级索引、改写慢查询SQL减少全表扫描从根源上降低重复查询的性能开销提升查询效率。三InnoDB缓冲池优化1. ‌核心容量参数‌‌innodb_buffer_pool_size‌建议设置为服务器物理内存的‌50%~70%‌例如32G内存的服务器配置为16G~22G保证能缓存绝大多数热数据页大幅降低磁盘IO开销。注意不要超过物理内存的70%避免触发操作系统swap交换反而导致性能骤降。2. ‌实例拆分参数‌‌innodb_buffer_pool_instances‌当缓冲池容量大于1G时建议设置为‌8~16个实例‌将缓冲池拆分为多个独立区域减少内部锁竞争提升高并发场景下的访问效率。3. ‌刷盘策略参数‌‌innodb_buffer_pool_pages_flushed‌监控脏页刷盘速率配合innodb_max_dirty_pages_pct设置脏页占比上限为‌75%‌避免大量脏页集中刷盘阻塞正常查询。‌innodb_flush_neighbors‌SSD存储环境下建议设为0关闭相邻页合并刷盘充分发挥随机IO性能。4. ‌预热与恢复参数‌‌innodb_buffer_pool_dump_at_shutdown‌设为ON停机时自动导出缓冲池热数据索引‌innodb_buffer_pool_load_at_startup‌设为ON重启后自动加载热数据避免冷启动阶段性能暴跌。5. ‌并发访问参数‌‌innodb_old_blocks_time‌建议设为‌1000毫秒‌避免一次性全表扫描的冷数据快速挤占热数据的LRU链表位置保护高频访问的热数据不被淘汰。四如何配置Redis来替代MySQL的查询缓存配置 Redis 替代 MySQL 原生查询缓存Cache-Aside 模式是提升高并发系统性能的主流方案。由于 MySQL 8.0 已移除原生查询缓存通过 Redis 实现应用层或代理层缓存成为标准实践。以下是具体的配置策略、一致性保障方案及高可用设计1. 核心读写策略配置Cache-Aside Pattern这是最基础且推荐的配置模式旨在平衡性能与数据一致性。‌读操作流程‌先查询 Redis 缓存。若命中Hit直接返回数据。若未命中Miss查询 MySQL 数据库。将 MySQL 返回的结果写入 Redis并设置过期时间TTL最后返回数据。‌写/更新操作流程‌‌先更新 MySQL 数据库‌。‌再删除 Redis 缓存‌而非更新缓存。‌理由‌删除缓存比更新缓存更可靠。如果先更新缓存随后数据库更新失败会导致缓存与数据库不一致且在高并发下直接删除缓存能避免复杂的并发写竞争问题让下一次读请求重新从数据库加载最新数据。2. 关键参数与一致性优化配置为了应对高并发场景下的数据不一致风险需配置以下机制A. 延时双删策略解决并发读写不一致在极端高并发下单纯“先删缓存再写库”或“先写库再删缓存”都可能产生短暂脏数据。配置‌延时双删‌可大幅降低概率先删除 Redis 缓存。更新 MySQL 数据。休眠短暂时间如 500ms - 1s具体取决于业务主从同步延迟。再次删除 Redis 缓存。‌目的‌确保在数据库主从同步完成前任何试图重建缓存的请求所生成的旧数据被二次清除。B. 设置合理的过期时间TTL‌基础 TTL‌为所有缓存 Key 设置一个基础的过期时间如 30 分钟至 24 小时防止因代码逻辑遗漏导致永久脏数据。‌随机抖动‌在基础 TTL 上增加一个随机值如 ±10%避免大量热点 Key 在同一时刻过期引发‌缓存雪崩‌。C. 监听 Binlog 异步失效最终一致性保障对于对一致性要求较高且更新频繁的场景建议引入 Canal 等工具监听 MySQL Binlog业务代码只负责更新 MySQL。Canal 捕获 Binlog 变更消息发送至 Kafka/RocketMQ。消费端接收消息后异步删除对应的 Redis 缓存。‌优势‌解耦业务代码与缓存失效逻辑统一处理所有入口的缓存失效避免漏删。3. 高可用与稳定性配置防止因缓存层故障导致数据库压力骤增穿透、雪崩、击穿。A. 防止缓存穿透查询不存在的数据‌布隆过滤器Bloom Filter‌在访问 Redis 前先通过布隆过滤器判断 Key 是否存在。若判定不存在直接返回不查数据库。‌空值缓存‌若数据库确实无数据也将空对象写入 Redis 并设置较短的 TTL如 5 分钟防止恶意请求反复冲击数据库。B. 防止缓存雪崩大量 Key 同时失效‌高可用架构‌配置 Redis Cluster 或主从哨兵模式避免单点故障。‌多级缓存‌引入本地缓存如 Caffeine/Ehcache作为一级缓存Redis 作为二级缓存。当 Redis 不可用时本地缓存可提供短暂的服务降级保护。‌限流降级‌在应用层使用 Hystrix 或 Sentinel 进行限流当检测到数据库压力过大时直接拒绝部分请求或返回默认值。C. 防止缓存击穿热点 Key 过期‌互斥锁Mutex Lock‌当发现热点 Key 过期时只允许一个线程去查询数据库并重建缓存其他线程等待或重试。‌逻辑过期‌不设物理 TTL而是在 Value 中存储逻辑过期时间。发现过期后由后台异步线程重建缓存前台请求仍返回旧数据直到新数据构建完成。4. 推荐配置清单总结配置项建议值/策略说明‌读写模式‌Cache-Aside (旁路缓存)读先缓存后DB写先DB后删缓存‌写操作策略‌删除缓存 延时双删第二次删除间隔需大于主从同步耗时‌Key 过期策略‌基础TTL 随机抖动避免集体失效导致雪崩‌一致性增强‌Binlog 监听 (Canal)异步统一失效作为兜底方案‌穿透防护‌布隆过滤器 / 空值缓存拦截无效查询保护 MySQL‌高可用架构‌Redis Cluster / 哨兵确保缓存服务自身的高可用‌降级策略‌本地缓存 限流极端情况下保护后端数据库通过上述配置Redis 不仅能高效替代 MySQL 原生查询缓存还能在分布式环境下提供更强的一致性控制和系统稳定性保障。