高并发项目缓存常见问题
缓存穿透问题
什么是缓存穿透?如何解决缓存穿透?
访问数据时, 访问缓存中没有该数据, 数据库中也没有该数据, 像是穿透了缓存直达数据库.一般是人为的攻击手段.
解决方案
- 当查询一个不存在的数据时, 向缓存中存入一个设置了一定过期时间的key的数据, 使其访问不会直达数据库.
- 使用布隆过滤器. 先把缓存中的key全部存入布隆过滤器, 查询缓存前,先判断要查询的key在布隆过滤器中是否存在,不存在则返回, 可能存在则查询缓存.
布隆过滤器: 把数据存入布隆数据库时对Key进行Hash运算,再对位数组长度进行取余,得到一个下标,将该下标值设置为1,把全部数据存入后,进行查询一个key是否存在过滤器中时, 先对该key进行Hash运算, 得到下标, 当位数组对应的下标上有一个或多个0时,则该key一定不存在, 当位数组对应的下标上全部都是1是, 则该key有可能存在, 再进行查找.
缓存击穿问题
什么是缓存击穿?如何解决缓存击穿?
当缓存中一个热点数据的key突然过期,造成大量用户请求直达数据库, 就是缓存击穿.
解决方案
- 热点数据永不过期, 设置定时任务,在访问量低的时候更新缓存数据.
- 接口限流或降级, 限制同一时间内的访问量.
- 分布式锁
缓存雪崩问题
什么是缓存雪崩?如何解决缓存雪崩?
缓存中在同一个时间点有大量的key同时过期,请求查询缓存中没有数据,访问直达数据库,造成数据库宕机,这就是缓存雪崩问题.
解决方案
- 热点数据永不过期, 设置定时任务,在访问量低的时候更新缓存数据.
- 分布式锁
- 给缓存中的key设置随机过期时间, 这样可以避免key同时过期.
缓存不一致问题
如何保证缓存一致性?
当对数据 实时性要求不高时, 可以采用 弱一致性解决方案:
先 更新数据库 再删除缓存, 这样可以保证数据的 最终一致性,数据查询 效率高, 但是可能会导致在更新数据库之后, 删除缓存之前, 数据会有 短暂不一致的情况, 但最终数据还是会一致.
当对数据 实时性要求高, 对数据 查询性能要求不高时, 可以采用 强一致性解决方案:
加分布式锁, 把 更新数据库,再删除缓存 的操作当成一个原子性操作,给这个操作加锁. 这样可以保证查询到的数据与最终的数据 始终保持一致, 但是查询性能较差.