缓存问题
Posted youmingddd
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了缓存问题相关的知识,希望对你有一定的参考价值。
1、缓存穿透
多次访问一个不存在的key,会导致每次都去请求数据库,增加数据库负担
解决方法:1、对于请求数据库后仍然不存在的key设置为缓存,value中放null值,并设置一个缓存的失效时间,缓存有效时间可以设置短点,这样就不会多次请求数据库了,第二次就会直接返回null
2、采用布隆过滤器,使用一个足够大的bitmap,用于存储可能访问的key,不存在的key直接被过滤;
2、缓存击穿
指缓存中没有但数据库中有的数据(一般是缓存时间到期),同时有大量的请求,这些请求都会击穿到DB,造成瞬时DB请求量大、压力骤增。
解决方法:1、设置热点数据永远不过期。
2、在访问key之前,采用SETNX(set if not exists)来设置另一个短期key来锁住当前key的访问,访问结束再删除该短期key。
3、缓存雪崩
3.1、过期时间设置相同的一大批缓存同时失效,而查询数据量巨大,引起数据库压力过大
解决方法:过期时间设置的时候加上随机数,不同时失效
3.2、缓存服务器崩溃
解决方法:部署缓存服务器集群
热点数据问题
1、热点数据都部署在同一条服务器上,导致单机qps过高
解决方法:设置合理的hash算法,能将热点数据随机平均的分配到多台缓存服务器上
2、某个key的请求特别高,全部打到相同的机器的相同的队列里面造成单机压力过大
解决方法:因为只有在商品数据更新的时候才会清空缓存,然后才会导致读写并发,所以其实要根据业务系统去看,如果更新频率不是太高的话,这个问题的影响并不是特别大,但是的确可能某些机器的负载会高一些。
双写不一致问题(数据库和缓存不一致)
1、更新数据时,先更新数据库,再更新缓存,如果在更新完数据库后,去更新缓存时出错,会导致数据库和缓存不一致
解决方法:先删缓存,再更新数据库,等到需要数据的时候,请求再去数据库中读取数据,然后放入缓存
2、高并发的情景下,在更新数据时,先删除缓存数据,然后去更新数据库,此时A线程正在更新数据库,B线程去读取该数据时发现没有缓存,
然后读取了旧的数据库,并更新到了缓存中,然后A线程更新了数据库,此时缓存中与数据库中的值不一致,读取时只会读取到缓存的值
解决方法:根据数据的唯一标识,将操作路由后发送到要给队列中,这样对于同一个数据操作的时候就是串行的,排除了并发问题,对于队列中多个重复的操作可以进行优化
ps:由于读请求进行了非常轻度的异步化,所以一定要注意读超时的问题,每个读请求必须在超时时间范围内返回。
参考:
以上是关于缓存问题的主要内容,如果未能解决你的问题,请参考以下文章