redis已经是java后端程序员必知必会的一个技能点,今天来说一下redis的会出现的一些问题和解决方案。废话少说开撸。
0.前提
首先咱们应该知道整体的处理流程,查询请求过来后,先到达缓存层,如果在缓存里找到数据,就直接返回;如果没找到,就去查询数据库,然后把结果保存到缓存里。这样下次查询的速度就很快了。
Ps.缓存是从内存查询,内存的查询速度6ns 左右,数据库一般是从硬盘查询,查询速度大概在,0.14ms (1ms =1000000ns),内存的查询速度比机械硬盘查询快大概4个数量级。所以热门的数据要一定要放缓存了。
1.缓存穿透。
缓存击穿是,用户每次都查询,id为-1的值,缓存没有存id等于-1的情况,所以每次查询都会打到数据库里,然后拖慢正常查询的效率,严重的话,会导致数据库崩溃瘫痪。
这就好比你开了一个书店,书店里请了个小姐姐服务员,她把买的比较多的书都记录到一个小本本上了,某人如果来买书,就先在小本本上找,如果找不到,再在整个书店找一遍。如果有就给顾客,没有就说没有,某天突然来了一卡车小混混,来到书店排队买书,小姐姐也不敢怠慢,去接待。怎知第一个顾客要买一本叫做《那些年奇怪的旅行》的书,小姐姐在小本本上找了一遍,又费劲巴拉的在书店里找了一遍没找到,给第一个顾客说:抱歉,我们书店没有这本书,你到其他书店再问问吧,做一个摊手的表情。没想到第二个顾客也要买这本书,PS.服务员小姐姐是没有记忆的,她只有一个小本本能记忆。小姐姐,又在小本本上找了一遍,又在书店里找了一遍,还是没有。小姐姐从早上上班一刻也没休息干到晚上日落,一本书没卖出去,净接待这帮家伙了。你说气人不气人。晚上吃饭时,他跟老板抱怨说有一帮小混混,一直来问咱们店没有的书,怎么办呢?
老板说,你把问得多的那本书也记到小本本上,谁再来问,你就没有不就好了。
解决方案:
1.直接在接口里添加校验,如图书Id校验,id做基础校验,id<=0的直接拦截。
2.在缓存里没找到的数据,并且在数据库中也没有取到的,这时就直接可以将key-value 设置为key-null ,缓存有效时间可以设置短一点,如30秒,(设置太长会导致正常情况也没办法使用)。这样可以防止用户反复用同一个id或参数暴力攻击。
二.缓存击穿
缓存击穿就是,当用户访问时,缓存中没有这个数据,但是数据库中有数据(一般时缓存到期),这时候由于并发用户特别多,同时读缓存没读到,又同时去数据库找数据,引起数据库压力瞬间过大,造成数据库压力过大。
解决方案:
1.设置热点数据永不过期。
2.请求同一个key的请求之间,加互斥锁,只允许一个请求去读数据库,其他的原地等待100毫秒,当第一个读取后并写入缓存后再释放锁,后面的请求就直接走缓存了,就没问题了。
三.缓存雪崩
? 缓存雪崩就是,当缓存里的数据大批量过期的时候,就会把大量的请求打到数据库上,然后导致数据库压力过大导致宕机。和缓存击穿不同的是,缓存击穿是并发去查询一条数据,而雪崩是不同的数据过期了,许多数据都查询不到了,然后去查了数据库的情况。
解决方案:
1.缓存数据的设置的过期时间尽量随机,以防大量数据同时过期的事件发生。
2.如果缓存数据库是分布式部署的,那么就将热点数据均匀分布在不同的缓存数据库中。
3.设置热点的数据永不过期。
战友们,春季温差大,注意别感冒啊!
|