缓存简介
缓存 简介 简而言之,即是数据存储的缓冲区。使用缓存之后,可以减轻访问数据库的压力,显著的提升系统的性能。
使用缓存的一般流程如下:
缓存通常有两种:
服务器主集本身的内存缓存,也就是我们说的二级缓存。 相比于缓存中间件性能更好。但只能应用于本机,若系统分布式部署,会存在数据不一致的问题。 缓存中间件,比如:Redis、Memcached等 适用于分布式缓存,解决分布式数据一致性问题 有些业务场景,分布式缓存和二级缓存可以一起使用
缓存带来的问题 1. 缓存雪崩 缓存雪崩指的是当某一个时间段出现大规模的缓存失效的情况,此时大量的并发请求直接命中在数据库上面,导致数据库压力巨大,甚至宕机。
分析
造成缓存雪崩的关键在于在同一时间段大量的key失效。出现这个问题的可能性:1. 缓存宕机。2. 采用了相同的过期时间。
解决方式
过期时间采用随机值 若真的发生了缓存雪崩,使用熔断机制。当流量到达一定阈值,直接返回“系统拥挤”之类的提示,防止过多的请求打在数据库上。至少能保证一部分用户是可以正常使用,其他用户多刷新几次也能得到结果。 提高数据库的容灾能力,可以使用分库分表,读写分离的策略。 防止Redis缓存宕机导致缓存雪崩的问题,可以搭建Redis集群,提高Redis的容灾性。 2. 缓存击穿 缓存击穿指的是大量并发集中访问某一个 key,突然这个 Key 缓存失效了,导致大并发一时间全部命中在数据库上。
与缓存雪崩对比
缓存雪崩是大量的 key 失效导致的 而缓存击穿是大规模访问一个失效的 key 导致的 分析
关键在于某个热点 key 失效了,导致大并发集中打在数据库上。
所以要从两个方面解决,第一是否可以考虑热点key不设置过期时间,第二是否可以考虑降低打在数据库上的请求数量。
解决方式
若业务允许,对热点 key 可以设置永不过期 使用互斥锁。当缓存失效时,只有拿到锁才可以查询数据库,降低了在同一时刻命中在数据库上的请求。 可以对 Key 进行加锁 相应的,加锁会导致系统性能降低。 3. 缓存穿透 假如请求的 key 是在缓存中是不存在的,那缓存查不到就会去数据库查询。如果有大量这样的请求,这些请求像“穿透”了缓存一样直接命中在数据库上,这种现象就叫做缓存穿透。
分析
关键点是缓存中查不到 Key,这些 key 是不存在的
PS:说明了边界安全的重要性。应该做好参数检验,外界不可信
解决方式
把无效的Key存入缓存。如果缓存查不到,数据库也查不到,可以把这个 Key 值存入缓存,并设置value=“null”,当下次再通过这个Key 查询时就不需要再查询数据库。
弊端是,假如传进来的这个不存在的Key值每次都是随机的,那这种做法无意义。 使用布隆过滤器。布隆过滤器的作用是某个 key 不存在,那么就一定不存在,它说某个 key 存在,那么很大可能是存在(存在一定的误判率)。因此,可以在缓存之前再加一层布隆过滤器,在查询的时候先去布隆过滤器查询 key 是否存在,如果不存在就直接返回。