本文转载请联系大鱼仙人公众号.小伙子你眼光真好,看完这篇文章你就赚到血了。这篇文章一定会让你开心。这是面试的杀手级工具。其实Redis,我个人觉得,真的真的很强大,但是嘛,感觉被吹的太过了,但是他们确实有这个资本,他们有强大的性能,而且操作也很简单。它们提供了多种持久化方法来解决掉电问题,读写速度也很快。每秒几万,甚至几十万的速度,功能强大又好用,所以大部分公司都会用到Redis。于是乎,Redis面试的优先级也有了很大的提升,而Redis中经典的缓存的各种问题也成为了程序员必备的技能之一。缓存雪崩、缓存穿透、缓存击穿都是典型的问题。当然,本文就是为大家讲解这三者。这是怎么回事,一般情况下如何解决相应的问题。当然,本文没有特别强大的方法。估计百度上应该有很多对应的方法吧。相遇即是缘分,你们看到这篇文章就结束了,当然我要为各位小伙伴们准备一份最完整的解决方案,帮助你们了解和学习如何解决这些问题。缓存雪崩。当然,我想为亲爱的大家准备一份最完整的解决方案,帮助大家真正理解并学会解决这些问题。雪崩,这个词听起来很可怕,很多人可能已经猜到了。指的是大面积的缓存集体失效。举个典型的例子,写这篇文章的时候,比如我们到了618,很快就会有一波大促销,抢购,因为访问量特别高。因此,需要将这些产品放入缓存中,以提高效率。假设这个页面的数据缓存了一个小时,那么在凌晨一点,这些商品的缓存就会过期,而这批商品的访问,都落在了DB上,这样DB很容易崩溃。当某一点每秒有8000个请求时,缓存最多可以容纳每秒5000个请求,但是当缓存突然失效时,每秒8000个请求直接打到DB上,数据库就不会了能直接处理,有可能直接挂掉。如果此时不采用特殊的解决方案来处理这种故障,DBA也很容易崩溃。重新启动数据库,但它会立即被阻塞。下面的流量崩塌是我个人对缓存雪崩的理解。同时cachebiginterview失败。对于线上的情况,应该是一场灾难。如果你这样做了,恭喜你,你种下了大雷,想一想,如果DB直接崩溃了,那意味着用户可能开始黑客攻击了。这个时候,用户正在熬夜,熬夜等待购买自己喜欢的产品。结果你的软件当机了,什么都买不到,连我辛辛苦苦抢了好几天的优惠券都不能用了。什么破软件,卸载了,再也不用了。如果真的出现这样的场景,收拾好自己的东西。这是个大问题。你通常如何处理这种情况?你如何解决?这很简单。批量往Redis中放入数据时,给每个key的过期时间加上一个对应的随机值。这样可以避免大面积缓存数据同时过期的问题。公司一般使用的Redis都是集群部署的,所以将热点数据均匀分布在不同的Redis库中也可以避免所有故障的问题。有时将失败时间设置为随机或者将热点数据设置为永不过期是一个很好的策略,更新操作直接更新缓存即可。如果看到数据A的缓存已经过期,重新缓存一次。如果数据B的缓存过期了,重新缓存B,这样也可以刷新缓存。缓存穿透与缓存击穿先说缓存穿透。缓存穿透是指缓存和数据库都没有的数据。但是,用户继续发起请求。此类请求很可能是恶意请求。比如我们数据库的ID,都是自增的。如果发起者的ID为-1,或者ID不存在,此时用户很可能是攻击者,对数据库的攻击压力会变得很大。其实在这种情况下,程序员一般都会过滤掉这种恶意情况,但是万一出现漏洞,万一程序员忘记验证参数,如果这种情况持续下去,就用一个小于0的参数来请求你。每次都可以绕过Redis,直接打DB。找不到数据库。每次都会发生这种情况。如果并发度高,可能很容易崩溃。一些小的单机系统基本上用Postman可能就可以崩溃了。至于缓存击穿,这个和缓存雪崩有点类似,但肯定是有区别的。缓存雪崩是由于大面积的缓存失效导致DB崩溃,但缓存击穿不同。缓存故障是指非常热的键。比如之前某某酷炫的东西,占据了大众资源的关注度,大家纷纷喷。这个时候这个key就是一个大热点。并发访问集中在这一点上。当此刻key失效,也就是某酷的key突然失效,持续的大并发会直接穿透缓存,直接向DB发送请求。这就像在一个完好的桶上挖了一个洞,那么如何解决呢?缓存穿透和击穿。是缓存穿透?这是程序员必须采取的预防措施之一。接口层的Verification,比如参数校验,用户认证行为等,对于那些非法的请求,只是返回或者报错。在开发的时候,我们不仅要猜测用户的行为,还要做到最重要的是提防各种恶意请求,我对于程序的每一个界面,我们都要有一颗不信任的心。这种不信任指的是对各种参数和用户行为的各种考量,因为你不能确定传入的请求一定是正常的,也不能保证调用者一定是正常的调用者,所以需要进行一定的检查和处理那些异常调用者的缓存渗透。这就需要根据业务的实际情况在代码中进行相应的控制。这应该是基本要求之一。如果在生产中出现这种情况,那一定是T1级别的重大错误。我们通常的做法是先从缓存中取数据。如果无法从缓存中获取数据,可以直接从数据库中获取数据。如果获取不到,可以将key和value作为null写入缓存。设置一定的时间,可以有效防止恶意用户重复使用同一个ID。暴力攻击,其实我们也可以在网关层做相应的控制,因为用户不能在短时间内进行大量的多次请求,当有IP或者频率请求异常的机器时,这些IP和机器限制缓存故障。其实最简单的方法就是设置缓存永不过期。这应该是最简单粗暴的方法了,或者你也可以通过使用互斥锁来解决这种Bloomfilter。其实在redis中还有一个过滤器的高级用法,BloomFilter,也可以很好的防止缓存穿透。可以说这是为了防止这种情况而诞生的,用一个很小的空间就可以表明是否存在大量的数据,但是这样也有一定的弊端。缺点是会有一定的误报率。Bloomfilter可以利用其高效的数据结构和算法,快速判断你操作的key在数据库中是否存在,直接返回即可,不需要到DB,从而解决了可以很好地避免缓存穿透。就算很多IP同时发起攻击,其实普通的redis集群也能抵挡。小公司普遍使用小型redis集群,但一般不感兴趣。简单给这些公司讲解一下布隆过滤器的原理。Bloomfilters,你第一个想到的是什么,肯定想到为什么叫这个名字,玩过lol的朋友,脑子里第一个蹦出来的肯定是这个吧lol,我点了play,玩完一个,感觉队友很生气,于是又玩了一遍。。。好吧,所有笑话都是笑话,大家来了解一下这个Bloomfilter,我这里只是粗略的讲讲原理,不详细解释Bloomfilter:它由一个大的位数组组成。当系统初始化时,它会存储数据库中已经存在的产品ID。然后通过hash映射到bit数组的位置,最后可以通过数组上对应位置的值是否正确来判断是否有商品。说到这里,可能有点晦涩难懂。举个例子:现在有一个大位数组,将所有位置初始化为0,数据库中有商品1、2、3,然后我们有16个哈希函数,通过16个哈希函数映射1得到16个哈希values,而这16个hash值会对应bit数组的16个位置都设置为1;对2和3同样的操作也会产生16个hash值,即对应的32个hash位置也都置为1;最后最多会生成48个位置,为什么是最多,因为1、2、3的映射可能映射到同一个位置,所以最极端的情况是会生成48个1的位置。此时如果恶意请求携带了-1的乘积,也会对-1进行相应的操作,所以我们得到16个哈希值,对应位数组中的16个位置,判断是否有-1的乘积在数据库中通过判断16个位置是否都是1你可能也看到了这种方式会有一定的误判率,也就是有一个极限的情况。1、2、3生成的所有位置的映射值已经将-1的16个位置全部设置为1。当然,这种情况也是比较少见的一句话概括:必有没有0,但是全1不一定存在,所以有一定的误判率,这很好,小伙子,经过这么多轮的盘问,看来你很感谢面试官的夸奖。优惠什么时候会发送到我的电子邮箱?毕竟一个多月没上班了,也没有工资。一个工人没有工资是非常困难的。而我的副业还在起步阶段,还在慢慢写。如果大家能点个赞和关注,我也可以靠这个来订餐,不用那么急着要offer了。可以多面试几轮,多给大家讲废话(疯狂暗示)。我明白。接下来问一下你的设计模式,差不多,因为我们公司对设计和编码的要求比较高,所以需要考察你的编码设计能力,没问题,感谢面试官透露重点下次面试,我会回去强行准备下一系列的总结。其实这些题都是类似的题,都是比较常见的题,不要混淆这三个,这些问题应该是面试的重头戏,很多面试官都会问,即使你不问,如果你能引出这些问题,并向面试官说明要求,那么面试官将非常满意您的要求。商誉也会大大增加。我们一般针对redis解决三个时间段的各种问题:1.Redis高可用,sentinel,主从架构,集群,避免整盘直接崩溃的那种,主要是为了避免灾难性事故2.期间过程,这个地面ehcache缓存,Hystrix限流降级解决高流量,避免大流量直接crashDB3,然后redis持久化:RDB和AOF,重启自动加载数据,快速恢复缓存数据,合理配置可以几乎零丢失数据
