缓存使用带来的一致性问题 ---- 数据同步,有四类方式
(1)要求高的场景下,使用实时更新策略----- 即数据有变化时,更新的线程直接同步缓存数据
(2)如果允许,可以单独架设第三方方案,来同步缓存数据,常见的有 发布订阅/MQ方式
(3)容忍度较高的场景,可使用缓存过期策略 --- 允许数据短期不一致
(4)定时任务,适合数据变化特别不频繁的情况下,如统计型的数据
缓存雪崩
解决办法:
1.加锁排队(用细粒度锁,比如说用一个hasMap来做一个标识,当key存在时表示当前有线程正在更新缓存,其中不同的key表示不同的锁)
2.设置不同的过期时间
3.永不过期,缺点:不保证一致性,代码复杂度增大(每个value值都要维护异步更新代码),容易堆积垃圾数据。
4.双缓存方案,主缓存:有效期按照经验值设置,主要读取的缓存,主缓存失效后从数据库加载最新值,备份缓存:有效期长, 获取锁失败时读取的缓存,主缓存更新时需要同步更新备份缓存。 其实就是缓存降级策略。:
缓存穿透
当外界有恶意攻击时,会向我们请求不存在的数据。因这个数据肯定不会在缓存中存在,故一定会抵达我们的mysql
此时mysql查询将不堪重负,解决办法,使用布隆过滤器
(1)布隆过滤器的使用方法,类似java的SET集合,只不过它能以更小的内存,存储更大的数据
类似以下伪代码
SET set = new HashSET(); //创建布隆过滤器
初始化加载业务数据
set.add(id)
查询
query(id){
set。contain(id)==true ---》 去查数据库
}
(2)对应的生产代码,使用如下: