缓存-缓存问题概述

7 篇文章 0 订阅
2 篇文章 0 订阅

缓存问题

缓存一致性的解决方案

实时同步:

增量,主动,强一致性。

  1. 对数据库进行更新的时候(增删改)淘汰缓存(缓存失效)
  2. 读取数据的时候去更新缓存,为了避免缓存击穿带来的雪崩问题,我们需要做同步处理,控制只有一个线程去读取数据,然后更新缓存,其他线程阻塞等待。
  3. 设置缓存失效时间,兜底操作,假设在更新缓存失败这个缓存失效时间一道,就会把缓存失效。

读取的时候,先去查看缓存是否存在,再去看看数据库里面的对不对

更新的时候,先删除缓存,再更新数据

准实时同步:

增量,被动,准一致性

  1. 对数据更新操作的时候在更新数据库后,发送一个更新缓存的MQ消息(如果要保证数据不丢失的话,建议可以建立本地一个消息表,在发送MQ失败的时候可以重试)
  2. 缓存更新服务消费MQ更新数据消息后,读取数据库,进行相应的业务处理。
  3. 更新服务更新业务处理结果数据到缓存中。

任务调度更新

  1. 分布式调度任务,进行定时的更新缓存,使用场景:报表统计数据,对账数据定时更新到缓存等实时性不高的场景
  2. 实现简单:
    1. Timer或者ScheduledExecutorService
    2. SpringTask定时任务。@Scheduled(cron=“0 0 0 /1 * * ?”)
    3. 定时任务框架Quartz

binlog日志订阅

  1. binlog来更新缓存,消费服务作为mysql的一个slave,订阅binlog,解析出更新内容,再更新到缓存。
  2. 优点:模拟mysql的slave主从,性能比定时任务要好,数据的一致性可以得到保证。mysql压力不大的时候延时也比较低。
  3. 缺点:要单独搭建一个同步服务,

缓存穿透

  1. 利用不存在的key频繁攻击应用,就会导致应用挂掉
  2. 针对业务场景,对请求的参数进行有效性校验,防止非法请求击垮db,比如用户id<=0的直接拦截
  3. 如果db查询不到数据,保存空对象到缓存层,设置较短的失效时间。
  4. 采用布隆过滤器来保存缓存过的key,在访问请求到来的时候,可以过滤掉不存在的key,防止这些请求到达db层。

缓存击穿

  1. 缓存当中没有数据,但是数据库当中有数据(一般是缓存时间到期了),并发用户比较多,同时缓存又没有读到数据,就一起去数据库当中读数据,引起数据库压力瞬间增大,造成过大压力。
    1. 设置热点数据永不过期。如果缓存数据不设置失效时间的话,就不会存在热点key过期,导致大量请求到达数据库
    2. 加互斥锁:当缓存失效的时候,保证一个请求能访问到数据库,并且更新缓存,其他线程等待并且重试

缓存雪崩

  1. 大批数据到达过期时间,查询数量巨大,引起数据库压力过大,甚至down机。
  2. 缓存击穿是指查同一个数据,缓存雪崩是好多数据都过期了,很多数据都查不到,从而查数据库。
    1. 缓存过期时间设置随机,防止同一时间大量数据过期现象发生。
    2. 如果缓存数据库是分布式数据库,将热点数据均匀分布在不同的缓存服务器当中
    3. 设置热点数据永不过期
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值