缓存

一、定义 --ces

存储器的基本性质

  1. 存取时间越快,每“位”的价格越高
  2. 容量越大,价格越低
  3. 容量越大,存取速度越慢

由于存储介质的特性,存储介质的读写速度有很大的差异,为了提高数据的读取速度,将数据存储在读取速度较快的存储介质中,这种存储介质就是缓存。

二、缓存系统效率

缓存系统的速度和命中率成正比。具体的关系为: t=T1H+T2(1H) t=T1*H+T2*(1-H) 其中:

  • t: 缓存系统的整体存取时间
  • T1: 一级存储器的存取时间
  • T2: 二级存储器的存取时间
  • H: 缓存命中率

drawing

三、缓存分类

本地缓存

本地缓存是指缓存和应用在同一个进程内,缓存的数据是应用进程的私有数据。

  • 优点是: 距离应用实例近,访问速度更快。
  • 缺点是: 缓存数据是应用实例私有的,不同应用实例之间不能共享。不同应用实例之间的缓存数据很可能不一致,就需要更频繁地淘汰缓存数据。

本地缓存实现

  • Ehcache
  • guava cache

服务端缓存(分布式缓存)

缓存数据和应用在不同的进程内,缓存的数据是多应用实例共享的。

  • 优点是: 缓存数据可以共享,不同应用实例之间的缓存数据一致。
  • 缺点是: 距离应用实例远,访问速度慢。

分布式缓存实现

  • memcached
  • redis

四、缓存的问题和解决方案

1. 缓存过期策略

缓存系统一般会实现一个过期策略,当数据长时间未被访问时,缓存系统会淘汰该数据。常用的过期策略有:

  • 定时过期

为每个设置过期时间的 key 都需要创建一个定时器,到过期时间就会立即清除

  • 惰性过期

只有当访问一个 key 时,才会判断该 key 是否已过期,并且进行删除操作

  • 定期过期

添加一个即将过期的缓存字典,每隔一定的时间,会扫描一定数量的 key,并清除其中已过期的 key

2. 缓存淘汰策略

相对于数据库,缓存系统一般空间有限,当缓存数据量超过一定阈值时,需要淘汰部分数据。 常用淘汰策有:

  • 先进先出(FIFO)
  • 最近最少使用(LRU)
  • 最近最不使用(LFU)
  • 随机淘汰

淘汰策略需要灵活配置,根据应用场景选择合适的淘汰策略。如果数据获取成本比较高,可以考虑让数据保留在缓存中

3. 缓存穿透

缓存和主存中都没有的数据,而用户不断发起请求,导致请求直接穿透到主存中。 解决:

  1. 缓存空对象
  2. 布隆过滤器

4. 缓存击穿

缓存击穿,是指一个key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个屏障上凿开了一个洞。

解决:
  • 使用互斥锁(mutex key)

这种思路比较简单,就是让一个线程回写缓存,其他线程等待回写缓存线程执行完,重新读缓存即可。

  • 热点数据永不过期
  1. 物理不过期,针对热点key不设置过期时间
  2. 逻辑过期,把过期时间存在key对应的value里,如果发现要过期了,通过一个后台的异步线程进行缓存的构建

5. 缓存雪崩

缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,请求直接落到数据库上,引起数据库压力过大甚至宕机。和缓存击穿不同的是,缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。

解决方案
  1. 均匀过期

设置不同的过期时间,让缓存失效的时间点尽量均匀。通常可以为有效期增加随机值或者统一规划有效期。

  1. 加互斥锁

跟缓存击穿解决思路一致,同一时间只让一个线程构建缓存,其他线程阻塞排队。

  1. 缓存永不过期

跟缓存击穿解决思路一致,缓存在物理上永远不过期,用一个异步的线程更新缓存。

  1. 双层缓存策略

使用主备两层缓存:

  • 主缓存:有效期按照经验值设置,设置为主读取的缓存,主缓存失效后从数据库加载最新值。
  • 备份缓存:有效期长,获取锁失败时读取的缓存,主缓存更新时需要同步更新备份缓存。

五、缓存和DB的同步

如何在缓存和主存储系统之间同步数据,主要有三种策略:

Read-Through (Cache-Aside)

基本流程

drawing

优点

  • 频繁读取时,减少了数据库的压力(其实就是懒加载的优点)

缺点

  • 首次读取的时候延迟高

Write-Through

基本流程

drawing

优点

  • 保证了缓存和主存数据一致性

缺点

  • 写延时,因为数据需要同时写入缓存和主存
  • 访问频率低的数据,也被写入缓存,缓存利用率低

Write-Behind

基本流程

drawing

优点

  • 写数据时,只写入缓存,不写入主存,减少主存压力
  • 写入速度快

缺点

  • 有丢数据的风险

六、参考文档

  1. 缓存指南
  2. 数据一致性
  3. 失效策略:缓存过期都有哪些策略
  4. 携程最终一致和强一致性缓存实践

results matching ""

    No results matching ""