遇到缓存问题

问题:在事务中在进行数据库查询所有的数据后,将其中的数据更改几个后,重新进行查询。发现此时返回的数据并不是修改之后的数据。

经过学习后发现是Mybatis的一级缓存问题,同时也了解的Mybatis的二级缓存:

Mybatis一级缓存:

  • 当在一个方法中执行多次,查询同一个sql语句的命令的方法

    • 当不加事务的时候执行sql,执行完之后会话就会结束,一级缓存就会消失。

    • 当加事务的时候,一级缓存不会消失,再次查询同一个sql的时候(参数也得一样)就会使用前面查出的数据。

  • 一级缓存可以帮助我们减少重复的数据库查询

  • 缺点:但是当我们第一次查询之后对相关数据进行更改后,依旧会得到一级缓存的数据

    • 解决方式:将一级缓存关闭在配置文件中

    • 参数:statement:sql语句 session:会话 默认为会话,换为statement则每执行一个sql本地缓存就清空

      mybatis.configuration.local-cache-scope=statement

Mybatis二级缓存:

多次执行同一个sql,如果二级缓存生效则只执行一次(适合读多写少的接口,比如查询所有车次接口和查询所有车站接口)

如何开启:在mapper.xml中在需要开启的sql下加入<cache></cache>即可。同时需要将实体类做一个序列化

失效:对同一个namespace做增删改操作时二级缓存就会清空

序列化:实现Serializable接口

  • 当一个类需要保存起来,下次再还原成类是就需要序列化,或者需要远程传输,比如放到redis里,也需要序列化

  • 缺点:当有多个节点时,都执行了二级缓存查找,当进行删除命令时只会进入到一个节点去删除,那么数据就会改变。而另一个节点并不知道,拿原来的数据导致数据不一致问题。

接着对Springboot的内置缓存以及redis进行了学习

springboot内置缓存

引入依赖,在各模块添加注解@EnableCaching,开启缓存,在需要开启事务的方法上添加@Cacheable(value = "t")//注解。value为缓存的名字。

相当于开辟了一块空间,根据不同的请求参数,空间内会缓存多个结果,会根据请求参数生产一个key,需要对请求参数生产hashcode和equals方法,用于生产key。

根据不同的参数重写hashCode()与equals()方法。

强制刷新缓存方法 @CachePut,每次去数据库中查找,查完会将结果放到缓存中去。

实现:将两个方法结合

程序去查询queryList()方法,自动读取缓存。当数据发生变化时主动执行queryList2()强制刷新同一缓存名区的值,将数据放到缓存里面去。

问题:但是并没有设置缓存的过期时间。存在多台缓存的问题。

集成redis:

第一行为将spring的cache放在redis中,

接着两行为放在redis中的key的前缀(防止多个项目冲突)

接着一行为是否可以为空

最后一行为设置redis缓存为60s

将类放到redis中,有一个远程传输的动作,对类进行远程传输就需要将类进行序列化

redis解决问题:

  1. 高性能:提高访问速度,mysql单机版QPS约为2000,redis为10万

  2. 数据的持久化:解决多节带你共享缓存,机械重启也不会丢失数据

缓存击穿与解决方案:

在抢票功能中,很可能出现。

缓存击穿:热点的一个key失效,大量的请求直接访问数据库,导致数据库压力增大

解决方案:

  1. (解决缓存超时问题)主动刷新缓存。假设时间为60s,当时间快到时我们可以主动调用@CachePut注解中的方法,主动刷新缓存时间(定时任务)。

  2. (如果缓存直接失效:比如缓存机器换了,热点key突然没有了)使用分布式锁,只让一个请求拿到锁并查询数据库,其他请求都失败,告诉其他用户稍后等待。

缓存穿透与解决方案:

第一步:判断当前缓存是否有数据

  • 没有则去数据库去读取->数据库中也没有数据就会造成缓存穿透的问题

  • 有则直接返回数据

解决方案:

  1. 分布式锁,100个请求只能让一个请求进入

  2. 如果查询到空列表,那么也将其放到缓存中去。在第一步中区分null和[] 如果是null去数据库中查,如果是[]就不去数据库中查找(允许缓存为空)。

缓存雪崩与解决方案:

缓存雪崩:由于短时间内,大量的key失效,导致数据库压力剧增。

常见缓存过期策略:

  1. TTL 超时时间

  2. LRU 最近最少使用

  3. LFU 最近最不经常使用

  4. FIFO先进先出

  5. Random 随机淘汰策略

解决方案:

  1. 将热点KEY主动打散 :定时任务将热点KEY主动刷新 超时时间再加上一个随机值

  2. 给接口限流,让访问数不过大

  • 11
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值