哪一些因素 考虑使用redis,毕竟 redis 也要增加成本
1 热点数据
2 读的成本非常大
3 读多写少
4 对数据一致性要求 没有那么严格(可以出现数据与数据库不一致)
1 秒杀场景
2 微信抢红包
3 物流查询轨迹(热点数据 激活的数据是被缓存到redis 当中)
缓存key 一个时间点过期的时候,如果缓存数据为热点数据,那么在过期时间点超高并发访问这个 key,压力就会传导至数据库挂掉
解决方法 使用互斥锁, 思路是这样,大并发过来,抢到锁 去请求数据库,请求成功,设置到 redis 中,其他没有抢到的 sleep 一秒,这个时候,缓存中已经有数据,这样 其他查询 都会获取缓存中的数据,问题解决
static Lock reenLock = new ReentrantLock();
public List<String> getData04() throws InterruptedException {
List<String> result = new ArrayList<String>();
// 从缓存读取数据
result = getDataFromCache();
if (result.isEmpty()) {
if (reenLock.tryLock()) {
try {
System.out.println("我拿到锁了,从DB获取数据库后写入缓存");
// 从数据库查询数据
result = getDataFromDB();
// 将查询到的数据写入缓存
setDataToCache(result);
} finally {
reenLock.unlock();// 释放锁
}
} else {
result = getDataFromCache();// 先查一下缓存
if (result.isEmpty()) {
System.out.println("我没拿到锁,缓存也没数据,先小憩一下");
Thread.sleep(100);// 小憩一会儿
return getData04();// 重试
}
}
}
return result;
}
缓存击穿,是某一个key在某一个时间点失效,有大量并发请求过来
缓存穿透,是利用自己伪造的key,这个key它在缓存里面一定不存在
最后 都去查询数据库
最简单的方法,所有的key 存到 set 或者 list集合 ,存在 合法请求,不存在 非法请求
布隆过滤器 解决过滤器 问题