谈谈redis缓存穿透和缓存穿透的区别,以及它们造成的雪崩效应腾讯面试,面试官问我缓存击穿和穿透的区别;我回答说他们是一样的,面试官立马抬起头用细长的单眼皮盯着我说“Areyousure?”,最后面试提醒我,既然名字不同,就一定不同,也就是说缓存穿透和缓存穿透不是一回事;所以今天我们将看看这两者之间的区别以及它们造成的后果;为项目添加缓存一般情况下,我们会将热点数据放在缓存中,比如常用词典、用户信息、订单明细等;也就是在项目启动的时候,先把热点数据加载到redis中,以后不用每次需要数据的时候都去数据库查询。这样既减轻了数据库的压力,也提高了访问速度。可谓一举多得!缓存穿透缓存穿透是指缓存或数据库中不存在的数据,用户却不断发起请求,比如id为“-1”的数据,或者id特别大的不存在的数据。这个时候用户很可能就是攻击者,攻击会对数据库造成过大的压力。解决方案:在接口层添加校验,比如用户认证校验,id为基础校验,id<=0直接拦截;无法从缓存中获取的数据,不从数据库中获取,此时也可以将键值对写成key-null,缓存有效时间可以设置短一些,比如30秒(设置太长会导致正常情况下无法使用)。这样可以防止攻击用户重复使用同一个id来暴力攻击缓存击穿。缓存崩溃就是大量的key同时过期,但是有大量的请求需要使用这些过期的key,所以在redis中找不到程序。收到数据后,会去数据库查询。当数据库处理大量请求时,压力会瞬间增大,造成压力过大,甚至导致崩溃。可重入锁,当多个key过期时,同时只向数据库发送一个查询请求,其他key等待一个一个查询,可以避免数据库压力过大的问题;代码如下:staticLocklock=newReentrantLock();publicStringgetData(Stringkey)throwsInterruptedException{try{//从redis中获取值Stringdata=getRedisData(key);//如果key不存在,从数据库中查询if(null==data){//尝试获取锁if(!lock.tryLock()){//获取锁失败,100ms后重试TimeUnit.MILLISECONDS.sleep(100);数据=getData(键);}//走到这里表示成功获取锁//从myqsl获取锁data=getMysqlData(key);//更新数据到redissetDataToRedis(key,value);}返回数据;}catch(Exceptione){e.printStackTrace();扔e;}finally{//解锁。开锁();}}穿透和击穿的区别穿透和击穿的区别上面已经介绍的很清楚了,这里总结一下穿透:大量请求不在缓存和数据库中的数据,每次都查询数据库,导致数据库压力过大。故障:大量key同时过期,导致所有请求都到达数据库,导致数据库压力过大。雪崩效应雪崩效应是指穿透和击穿对数据库造成的压力,如果过大,最终会导致整个数据库宕机。一旦数据库崩溃,带来的连锁反应是很可怕的。当数据库不可用时,你的服务器无法使用;这就是雪崩效应;完全地
