缓存雪崩
产生原因
在同一时间缓存数据集体失效,此时大量请求访问失效数据,导致大量并发直接访问数据库造成数据库压力
解决方式
- 将需要缓存的数据进行分散失效处理,将缓存的数据的失效时间设置一个随机值,避免大量缓存数据在同一时间集体失效
- 将部分经常做查询且不经常更新的数据的缓存时间设置为永不失效
缓存击穿
产生原因
对于统一个key下存储的热点数据在key的失效时间到达时,此时有高并发的请求访问该数据,就会造成大量请求直接访问数据,造成数据库压力过大
解决方式(我所了解到的)
- 是设置热点数据永不失效(避免缓存雪崩和击穿,不过会造成内存负载过大的问题)。可以设置定时任务解决内存过大的问题,定时任务在热点数据的key过期前进行数据刷新,这样也是对数据的永不过期处理,不过这样设置系统的复杂度会增加。
- 对缓存数据进行加锁处理,当需要查询的数据被访问时其他线程不能访问该数据,可以对get获取缓存数据时加锁处理,单线程访问这样会降低查询性能。我们可以在查询数据库之前先查询缓存是否有数据,如果缓存有数据直接返回数据不走加锁后的方法,如果缓存没有数据再走加锁后的方法(感觉这样也会造成短暂的性能问题)。
- 使用互斥锁,先查询缓存数据判断,如果缓存没有数据,在判断是是否有线程并发访问该方法(判断锁是否被占用,如果被占用就让访问线程休眠一定时间,当占用锁的线程执行完后缓存中的数据就会被存入,之后其他线程访问直接反问缓存中的数据即可,不需要再访问数据库避免缓存击穿造成的数据库压力过大)
缓存穿透
产生原因
当有人可以攻击系统时,采用一个一定不存在的数据访问数据库,此时缓存中不存在对应的数据,会直接访问数据库,反复访问造成数据库压力过大崩溃称为缓存穿透
解决方式
- 在接收参数时进行判断,将不符合条件或逻辑的查询条件进行检验
- 当一个数据被反复访问且数据库中不存在时,进行缓存空值,将缓存时间设置的相对较短点,频繁访问时返回缓存中的空值或者是提示信息
目前了解到的缓存问题,以后有新的发现会及时补充