场景
相信各位看官在实际项目中或多或少的使用过Redis,常用用场景如图,在Service层和Dao之间通过添加Redis来减轻对数据库的访问压力(1->2)。
缓存穿透
产生场景:特定情况下(如恶意攻击),大量通过key值(如ID)查询结果不存在于数据库中的请求导致缓存穿透,程序频繁访问数据库,如下图不进行3处,只会进行1、2步骤: 解决方式:
1.Redis中保存value为空的数据同时设置一个短的缓存的过期时间(存在数据一致性问题)
2.布隆过滤,对所有可能查询的参数以hash形式存储,在控制层先进行校验,不符合则丢弃,从而避免了对底层DB的查询压力
缓存雪崩
产生场景:缓存在某个时间点全部失效,造成无法获取缓存中数据,直接访问DB。
出现原因及解决方式:
1.redis服务器down掉了,造成缓存雪崩,我们可以通过搭建redis集群(哨兵模式、redis-cluster)方式来使得redis服务高可用,多个节点部署防止缓存雪崩。
2.缓存的失效时间点设置过于集中,我们可以根据业务情况设置多个失效时间点。
缓存击穿
产生场景:同一时间点,大量并发请求同时读取缓存,此时失效没数据,又同时去访问数据库。
解决方式:
1.对于热点比较高的缓存我们可以设置为永久缓存,就不存在读缓存读不到数据。
2.对于其他缓存我们可以在程序中进行加锁处理,一旦缓存中没数据,进入DB操作并加锁处理,使得缓存击穿的时候只有一个请求访问DB,其他请求处于等待状态然后又去获取缓存。
至此表示缓存常见问题(缓存穿透、缓存雪崩、缓存击穿)已解决,文章若有不足之处,欢迎指正。