文章目录
MySQL缓存
MySQL缓存:缓存用户定义的热点数据 ,用户直接从缓存获取热点数据,降低数据库的读 写压力。
Redis-缓存用户定义的MySQL中的热点数据。
场景分析:
①内存的访问速度是磁盘访问速度的10万倍
②读的需求远远大于写的需求
③mysql自身的缓冲层(BufferPool)和业务无关,一个是缓存MySQL中最近最少使用的,一个是缓存用户定义的热点数据的
④mysql作为项目的主要数据库,便于统计和分析
⑤缓存数据库作为辅助数据库,存放热点数据。
其他提升MySQL性能的方式
读写分离
MySQL也有主从复制:避免单点故障

在某些场景下,读的需求没有那么高(非读一致性需求),可以采用写到主数据库,读到从数据库。从而降低了主数据库的读压力。
连接池
在服务端 创建多条与数据库的连接
并发提升数据库的访问性能,同时复用连接资源,避免连接建立,断开以及安全验证的开销。
异步连接(reactor网络模型)
在服务端创建一个连接,采用非阻塞Io
缓存方案实现
MySQL与缓存的一致性状态分析
①MySQL有,redis无
②MySQL无,redis有
③MySQL有,redis有,数据一致
④MySQL有,redis有,数据不一致
⑤都无
制定用户定义热点数据的读写策略
读:
先读缓存,缓存存在直接返回;缓存不存在,访问mysql获取,有返回并同步到缓存,没有说明整个系统都没有这个数据
写:
- 以安全为主: 先删缓存(整个hash 结构)为了让其他连接获取到变更后的值, 然后对MySQL DML操作,**MySQL数据变更同步到redis。**使用伪装从库的方式进行同步
- 降低安全需求,提升效率(trade off):先写缓存并设置过期时间 ,再写MySQL,等待MySQL同步到redis中。过期时间选择:与MySQL网络传输的时间+MySQL处理时间+MySQL同步到redis的时间。但是带来一个安全问题:时间窗口内其他连接可能读到脏数据。
MySQL和Redis的同步方案
同步方案1:
伪装从数据库,从mysql中拉取数据同步到redis。
阿里Canel

或者另一组件
go-mysql-transfer
在go-mysql-transfer中定义热点数据,执行同步方案。
同步方案2:
udf+触发器,缺点是udf不支持事务操作,每一次都要与redis建立连接。
同步方案3:
Canel+Canel客户端:高可用,但是比go-mysql-transfer多了一个流程
缓存方案的故障以及解决
缓存穿透
数据在缓存和mysql中都无,一直读取不存在的数据,造成mysql访问性能急剧降低
解决:①缓存设置<key,nil>
②布隆过滤器 只能增加不能删除
缓存击穿
缓存无,mysql有,大量并发连接请求,造成mysql访问性能急剧降低
解决:①过热数据不过期
②分布式锁
缓存雪崩
大量缓存同时集中失效,但是mysql存在该数据,造成mysql访问性能急剧降低
解决:①间隔设置过期时间
②重启时,预先导入热点数据到缓存
缓存方案的弊端
①事务多语句必须走一条连接(尤其是有连接池的场景)
②在缓存方案中redis不支持回滚
③可能造成redis MySQL不一致