缓存-应用场景

微服务架构-缓存-使用场景

Posted by Nova on 2020-12-26

缓存作为高并发解决方案之一,用好缓存的重要性不言而喻. 【分布式缓存】

当然在 内存与CPU交换数据中、前端缓存(vue等) 也存在缓存的使用.

缓存背景

常用的、经常访问的、不经常变化的数据. 使用缓存可以有以下好处:

  • 缓存的目的:减少数据库IO,减轻服务器压力,减少网络延迟,加快页面打开速度(业务快速响应)

缓存的本质:用空间换时间,牺牲数据的实时性,以服务器内存中的数据暂时代替从数据库读取最新的数据

但引入缓存后,也会有新的问题出现,比如:

  • 缓存代价:额外的资源支持(硬件资源、内存资源)
  • 高并发缓存失效问题(缓存穿透、缓存雪崩、缓存击穿); 瞬间数据库访问量增大,甚至崩溃可能
  • 缓存与数据库数据同步(缓存和数据库无法做到实时同步;redis主从无法做到实时同步)
  • 缓存并发竞争:多个redis的客户端同时对一个key进行set值时(由于执行顺序引起的并发问题)

在解决以上问题之前,先梳理下 可以使用缓存的一些业务场景:

  • 菜单/权限/类别/数据字典
  • 数据服务(给其他业务线提供数据访问的服务;如果都查库,压力太大无法支撑)
  • 某些后端服务接口,为了提升接口响应效率, 减轻后端压力
  • 热点数据.

Redis应用场景

除了以上缓存场景,redis也可以用在:

  • 秒杀
  • 分布式锁
  • 唯一ID生成

缓存各种问题解决

缓存一致性问题

只有在更新数据的时候 存在缓存不一致问题

当数据存入缓存,如果需要更新的时候,往往会带来一些问题:

  1. 要更新的时候,先更新缓存还是先更新数据库? 如何确保更新缓存和更新数据库这两个操作的原子性?
  2. 更新缓存的时候该怎么更新?修改还是删除?
1
2
3
4
5
// 正常来说,有四种方案
先更新缓存,再更新数据库。
先更新数据库,再更新缓存。
先淘汰缓存,再更新数据库。
先更新数据库,再淘汰缓存。

a. 先淘汰缓存,再更新数据库:
问题(并发问题):先删除缓存,数据库还没有更新成功,此时如果读取缓存,缓存不存在,去数据库中读取到的是旧值,缓存不一致发生。

  • 解决办法
    延时双删:a. 先删除缓存; b.更新完数据库后,再定时延迟删除.

b. 先更新数据库,再淘汰缓存
问题(并发问题):更新数据库成功,如果删除缓存失败或者还没有来得及删除,那么,其他线程从缓存中读取到的就是旧值,还是会发生不一致。

  • 消息队列
    先更新数据库,成功后往消息队列发消息,消费到消息后再删除缓存,借助消息队列的重试机制来实现,达到最终一致性的效果。
  • 进阶版消息队列
    发送引入的消息队列 —>> 使用binlog

借助消息队列的重试机制来实现,达到最终一致性的效果

问题衍生:cpu缓存、各个存储的缓存一致性问题 都有哪些问题? 怎么解决的?

缓存比较(Redis和memcache)

多级缓存架构