今天学了学这三个知识,这命名真是有点东西。
1.先说在命名方面与其余两个内容能明显区分开的缓存雪崩,简单来讲:
缓存雪崩就是缓存宕机了,也甭管咋宕机了,反正就是某一时刻,缓存用不了了。
那咋办,缓存用不了了,大量的操作就直接来到了数据库,数据库那压力闷了,不一会儿数据库就崩了。那么解决方法简单来将就设计多级缓存,多来几层缓存,不可能倒霉到每层都崩吧。
那说万一都崩了咋办,那还有redis集群嘛,redis集群我没学过,我大胆猜测redis集群就是一群redis缓存,然后多个集群进行汇总成一个redis群,就和一个年级进行分班一样。一个群干一个群的事儿。
2.缓存穿透:
缓存穿透和缓存击穿这两个玩意儿我是真有点分不清,不是概念分不清而是名字有些拗口,对于缓存穿透而言,首先得理解穿透这个概念,穿透穿透,说明缓存还在正常运行但是不起效果了。
诶,这样一解释好像说得通了。
那么缓存穿透指的就是缓存尸位素餐了,为啥呢?大概是认为,毕竟缓存没有思维,只能进行认为破坏嘛。
所以简单来说缓存穿透实质上就是人对服务器得一种攻击,通过生成大量的无意义得内容访问服务器。比如现在人人都能访问我的连接,比如我的网址是:
www.sjhp.com/demo/1至www.sjhp.com/demo/100
我的调用接口是www.sjhp.com/demo/{id}
那么此时,我的/1到/100对应的资源都存放在我的缓存中。
如此简单的请求方式,人为攻击过于简单,只需要不停的往我的连接www.sjhp.com/demo/{非0至100}发送无意义的数据内容,此时我的服务器接收到这些无意义的内容不仅在数据库无法查找,缓存中也没有。
那么根据缓存一般的存储特性,缓存无法命中,这些无意义的数据就会直接攻击我的数据库,造成我的数据库持续的进行查找,从而导致数据库崩溃。
这就是缓存穿透,简单来讲就是缓存尸位素餐。
那处理缓存穿透的最好办法就是在前端做防护,让人不要那么轻易的拿到数据连接进行访问,所以就需要对前端url进行加密,这个不理解的可以看看各大云盘的网址加密()
那么后端人员从来都正常看待前端发来的信息看的,所以后端人员还需自行加护。
第一种鸵鸟式防御就是,空值返回。
刚才不是说你人就是奔着我数据库来的嘛,那我得想办法让我缓存帮我数据库分担压力啊
此时有人就说头疼了捂嘴
你攻击我数据库,那你和我缓存说去吧,对于人为传递来的不存在于数据库的攻击信息直接存储在缓存中,用null进行标记。
之所以是头疼了捂嘴啊,因为攻击者换个链接又能继续攻击了。目前没有经历过实际的项目,只能理解这么多了。
第二种方式就是添加新的布隆层,可以看作是一种算法,对攻击起到一定的隔离效果。
3.最后说说缓存击穿
这又是个啥呢?缓存穿透是缓存正常运行只不过对面攻击是真伤啊,缓存没der用啊,直接给我数据库造成真实伤害。
这缓存击穿从名字来看,他就是奔着我缓存来的:
那么场景也很明显了,啥时候会直接给我的缓存干崩呢?
那么就不得不说缓存击穿的另外一个雅称:热点KEY问题
缓存本身存储的就是高热点的内容,那么当每个热点数据对应的缓存在某个时间消失了,最简单的就是TTL过期,那么此时大量的并发线程来访问某个数据热点,此时缓存没命中,显然就会去查询数据库。
我们众所周知,这个查库的速度是相当慢的,而大量的并发线程正在轮番蹂躏缓存,发现缓存数据不存在,咋办?那又同时去访问数据库嘛,最后造成数据库的崩溃。
这个防御方法可以去设计互斥锁模式和逻辑过期模式。
互斥锁就很简单,同一个数据要访问我缓存的时候,诶我直接给你锁上,你其他线程进不来,等第一个上厕所的吃干抹净,再开锁。那很显然,其余线程上不了厕所只能外边儿等。
这就避免一个厕所几万个人上干的到处都是的矛盾(),但是虽然里边儿安静了,外边儿可闹腾了。那这就是上厕所上锁的方式。
然后说逻辑过期:
上面的方式不太人道,虽然先来先到,但是我们不能不解决大多数人的实际问题。
这时候有人想了个高招,原来之所以慢是因为原来的进程上厕所玩儿手机,一次干个30分钟,谁受得了。所以限定访问时间很重要。那此时某个进程A进去访问缓存,发现缓存命中但是过期了(啥意思呢,就类似于数据库的逻辑删除,数据没删但是标记这数据删了),此时这个进程A说,爱咋咋地,我管你这那的,我拿着已经被逻辑删除的数据我就回了,然后通知另外一个牛马进程B取对数据进行读取与缓存回写。那么在回写的过程中,其余的进程看进程A都这样干了,那他们也有样学样了。