00:00
各位同学大家好,接下来植入主题案例说话,那么杨哥请带着我们做一个可能会出现缓存击穿现象的一个工程案例,怎么解决,怎么预防?直白一点,杨哥听完以后能不能改吧改吧,用在我的项目上,写在我的简历上。好,那么同学们找一个来看一下天猫聚划算功能,我们来实现一下,且有缓存击穿的风险,那么请看一下你准备怎么干?来吧。首先。是什么?那那么我相信聚划算这个功能或多或少同学们应该了解知道,甚至亲自参与过。简单来看一下我们的诉求,来说一下我们的设计,最后咱们再编码淘宝网,不多废话。聚划算我一点跳到哪天猫OK,据品牌好货想划算好价,那说白了也就是防止拼多多对阿里电商业务的蚕食和攻击,那么来吧。
01:06
各位亲,点一下立即购买,不用我多说了吧,华硕什么什么电脑OK,那么多少多少钱,那类似于拼多多版的团购,或者是什么优选,类似于这样好吧,那么这些功能是什么,我就不废话了,大家都用过首页。一点开马上就出来了,那么啊来分析一下最上面啊,大家看是不是它的聚划算好货精选,那么来吧,同学们请看啊,这个最上面啊,一直滑到这进度调多少,是不是接近干掉了1/3了,啥意思啊?那么阿里为什么这么有钱?为什么阿里的程序员?基本上都是一年16个月薪水,累当然累,对吧,他们加班也挺多的,但反过来讲是吧,现在你干it行业。哪有不累的?来。越是精品,越是想被客户提前看到的。是不是越想放在。
02:04
拓这个顶端位置啊,一般同学们搂眼啊,应该1/3的坑位,你们觉得这个占坑位费,这个占座的费用就像百度的广告竞价排名。大家告诉我。花不花流量,花不花钱,所以说厂家商家也没办法,你要想越在前面被看到得加钱对不对,好那么这个是他的。聚划算的头条精选那么接下来第二楼开始大牌服饰。第三楼食品生鲜,我们可以简单来看一下啊,一二三四五六七八九十,十一十二十三十四十五十六十七十八十九,20。接近一页或者叫一楼就是20个产品对吧,那么名字啊,打开点击立即购买,真真正正购买页是在这,那限时折扣,品牌正品多少多少多少等等,好,那么注意看这,待会我们会说个细节好了,你自己爱买就去买那么一页20。
03:08
一楼20个产品来吧,那么生产案例我们当然要清楚,那么结合我们的需求是什么呢?同学们请思考。我点开这个超链接,弹到这个页面,100%要查询出来当前在合同范围以内的商家要参加的聚划算的团购和相关的精品业务,那么弟兄们,你们觉得这么一查?这个数据像看现在你看到的这些东东。请告诉我,你觉得存在MYSQL,他扛不扛得住?这是第一个问题,第二个问题请大家思考一下啊,我们呢,来看一眼。这是他计划算以前的页面大家没有看到我点过大,这有一天12个小时后结束,请尽快购买,诶诶怎么现在我一点开的话,它都是统一叫限时折扣。
04:03
品牌正品呢?那杨哥这个跟我们的缓存击穿。又有什么不一样的地方呢?问题就出在这儿,大家都清楚啊,以阿里电商天猫的这些程序员,P6P7P8,当然了,P8是应该是动嘴的了,六七是主力干活的,他们基础不会差,能进去人脑子不会笨,为什么以前人家会写着一个还有一天12小时后结束。那为什么现在点开了以后,到我们到2023年了,为什么都叫限时折扣,品牌正品也很少有那个倒计时呢?因为电商有一些羊毛掸。他们甚至就是大厂里面跳出来程序员加入了一些黑客产业链,甚至有些功能就是他们做的,哎,这个闲聊他倒计时多少多少多少的时候,那一瞬间。可能。他需要把一批新数据换上来,老数据删掉那一瞬间啊。
05:03
他知道了,也许还有一天24小时过,搞个道具,那一秒钟刷的猛的下一下单,诶,结果到最后有些将将收到了,那么这个时候他是会出错的,哎,它就会去薅羊毛,所以说在这块以后,尽量的他们处于一种前端的自我保护,前端开始就限制不让你知道这个活动什么时候下架,哎,那么这样的话是不是这些黑客就不大清楚了,这个热点T它什么时候失效,是不是进一步的从业务上,从前台页面上开始就规避了缓存机串的风险。听懂了吗?好,这是第一个考点,所以呢,他现在呢,改成了限时折扣品牌正品,不再告诉你具体倒计时几分几秒以后这个东东。没了,因为这些都是签约商家的,到时候你让人家出错了是不OK的,这是我们要计划好的,那么接下来请看啊。假设九阳小火锅也好,或者是这些,呃,品牌我现在点在这啊,有可能我这个页面就这么转着,随时有人可以来点,对吧,那么我们的业务诉求,如果三天以后我就参加三天元旦。
06:13
现在我在这点是可以的,那假设春节元旦到1月2号元旦23分59秒,59分的时候,应该下降那一秒钟。下架了以后,你应该有一些什么方式啊,在这一秒钟可能要实现新的数据下架哦,抱歉,旧的数据下架,新的数据下架,来做好这个切换,有可能有些居心不良的人,就在这一秒钟的时候点哎,就给你了。扑空了,可能点进去的时候,那瞬间换的话就会出问题,所以我们来看我们的技术方案实现的诉求和分析的过程。第一个,同学们100%就是高并发,你绝对不可以用买色票来实现,你聚划算类似于阿里电商、天猫,甚至包括去哪儿网中订机票这种业务最好放在里面。
07:03
一瞬间的并发量,满斯克是扛不住的,对吧,只有一秒钟。它的读。并发的请求达到10万级别,好,那么这个是我们第一个相关的考虑,第二个。我们是不是要把MYSQL里面参加活动的数据抽取出来放到我们的red,一般是要采用定时器扫描来决定上线活动是到时间了。也许每个。项目他就参加三天或者一天或者一周到期了,老的给我下架,新的给我上线,且这一瞬间老的下架以后有可能别人还会访问老大,那么这一瞬间你热点可失效了,就这一瞬间你要避免系统出现缓存。痔疮的情况要给我预防,要给我避免,你有什么好的方案好,那么下面顺便问一下同学们。定时扫描,我想问问各位同学,你们知道的有哪一些?如果知道,请把你们的答案打在对话框上面,有的同学呢,知道了,我们也是不是讲过叫叉叉叉。
08:05
L job对吧,Job还有like job等等,那么最起码还有spring course,时英啊等等一些定时任务啊,那么这个呢,是需要有所了解的,那么所以说商家签完合同以后一定是走需求排期,他后面有肯定会有一个巨大的轮询这样的一个业务,那假设啊,这一页的精选或者这一楼。比如说大牌服饰,人家就参加三天,三天以后好到期了,你看它的入口啊,第一层保护。然后呢?这个是我们的大牌服饰第二层保护,你看这样是不是就分层给你断开好,那么各位同学真真正正买的是在这啥意思啊,就说这些签了合同的商家,我们呢,只参加活动三天,三天到了以后可能这一页的精品就突然换了,甚至啊各位同学请看我点一下,有没有发现他每次都会有所更新,就是抄过去,后面它有一个轮巡的定时任务,要把red本次上线的。
09:12
产品给我撸出来,灌到前台页面灌到red,从前台从给我查出来,所以它需要有一个定时从后台扫描,扫描来决定上线的业务,比如说我们设置一些key,三天以后。他就下线了,那么这个key没了,那么你到时候你要补充一批新的过来,好,第三一个你要支持分页的功能,大家请看我这个是不是就是一楼20页品牌明白吧,那么请大家思考这些东西我们100%清楚来放RA那么高频发定时任务分页显示,请问结合这些业务诉求,结合还要支持分页的功能,我们想从里面查出这些数据,传给前台,让他进行展现,点了以后,我们这个是我们后面加入到购物车进行一个订单购物,购物车的另外一个模块为服务,我想问的问题是里面什么样子的数据类型可以支持分页?
10:11
且存进像这样一楼显示20条,一楼显示20条这样,那么请大家思考一下,把你的答案写在我们的对话框里面轻的回复啊,嗯,很好,大部分同学呢,都说对了,那。同学们思考一下是吧,带分页的。起码你得给我想到两个,一个是下我们的list,另外一个说下我们的z set,那么list天生就是按照怎么加进来的,对吧,不管从左边还是从右边加,然后呢,L给来进行取,那么this set它是不是带着一个分数,那么我们现在的诉求是不是从red里面轮询了以后,到时间了,签了合同的商家这一波要参加合同聚划算的三天,那么给我停留在这个页面上,食品生鲜这一栏给我三天,对吧,从里面。
11:00
取出来那么一页就是一楼就是一页,一页就是一楼给我显示20条记录,那么所以说同学们这个时候我们来看啊,比如说你用从左边l push,从右边r push都可以,比如说这个是聚划算机,那么我们这有十条记录,好吧,那么默认取出来本一次啊,就是同一天来参加这个聚划算的,那比如说食品生鲜,这个是第一页,那么就是前五条记录,当然这啊这五条就对标这20条都一样,那么从这个K里面取出来的前五个,那么就是第一页食品生鲜,那么取出来的六到十,第二页就是我们的美家数码,对吧?哎,所以我们呢用这个,那刚才呢,不错,还有同学们说我们用这个z set也可以啊,它不是带这个分数吗?那个分数就是第一页第二页第三页第四页那个value值的话呢,那么就这20条,记录一页20条,一页20条可不可以也可以,但是注意。在用法上啊,从习惯而言,一般list我们用的是什么,分页展示多一些,Set,在set主要是用于什么游戏啊,抖音啊,那些打赏啊,游戏玩家啊,一些英雄的排行榜,哎这样的功能,哎,可能就取这么前十条,前五个等等,他用排行榜用的多一些,好所以说在这我们确认了我们的诉求和需求分析,我们用的诉据,那么就是我们的list,那接下来理论完成实操编码,来看一下boot加red来模拟做一个这样的red聚划算业务。
12:35
接下来代码说话,看看怎么实现这样一个高并发且能够带着分页的模拟天猫聚划算业务来处理一下来。首先啊,商家跟天猫签了促销合同,来参加这个聚划算。那么现在走需求排期假设啊,每一个商家就参加一天,那么食品生鲜今天的,呃,在这块就是这20条记录。
13:03
那么我们比如说我们用我们自己做的是用五条模拟呢,就这20条对吧,就是一页或者叫一楼这一楼啊说好了,比如说第六到第十条,就是二楼食品生生鲜对吧,第11条到第15条,那就是三楼的这个美加素嘛,那么带分页,那说白了这些呢,商家呢,谈好了以后。把签好合同的数据给后台技术部门灌到里面,后台就需要有一个定时任务,那么按照时间我们给TK设定过期时间,假设啊,这个K。只能是存活一天,那么一天以后,就到今天晚上的23:59:59的时候,我们自然而然把它下架了,对吧?那么过了这一秒钟以后,再过来点聚划算的这个,其他的顾客来看到的这个食品,那么可能就不再是这个巧克力了,OK,能理解这个意思了吧?所以分页第二个定时任务,那么我们要干的是什么呢?就怕,就怕的就是某一瞬间,那一秒钟,就那点寸劲,这个K刚刚老数据要下架,新数据还没上来的时候,就怕这一秒钟,哎,热点K突然失效了,把我们的。
14:20
缓存跨过去直接打爆了我们的买色QL,你要晓得可能这个时候聚划算这种功能是在天猫里面的重量级业务,他用的是比较多的,对吧,所以说同学们你看他那就怕这种事,他的入口它不是让你直接进到这个页面点这好。点这怎么着也要超过一秒钟吧,就是尽量的也不告诉你什么时候会。到点下线,防止有人有黑客来。算计我对吧,不怕贼偷,就怕贼惦记,所以这些从业务上,从页面上,他规避和风险那么好,最终我们要落到代码上,不怕遗忘就怕忘一假设这一秒他下线了,出现了一个空缺,怎么保证不要热点梯失效,打到我的数据库来,同学们代码说话。
15:06
第一个修改我们的RED7的,也就是说白了就是放在同一个这个业务模块里面了,那么泡沫亚木主起道都不需要修改好我们做个简单的,因为本次我们主要突出的是什么呢?啊,我说的简单是把那些增项改查去掉啊,那么业务类同学们十题service control错了,来吧,NTT提前写好,那么这个呢,我随便做了一个啊这些就不解释了,那么来这产品,那也就是我们计划算啊,假设点开这个什么斜挎包,点开这这这么一个就是在这儿这块的啊,名字啊价格啊,什么立即购买等等等,那么就是一个ID,产品名字,价格,还有产品详情的一个简单的说明啊,就是个就是聚划算页面上面展现的一个product OK,好,这是我们的NTT,接下来service,那么干嘛呢?采用定时器。
16:01
要加合同到期了,参与计划算活动的特价商品新增进READY3中好这个service,那么同学们请跟着我看一下,这么干,首先聚换算我们定义了我们的K的前缀就叫聚换算啊,然后呢,Right,那么至于说怎么进CTRL了,Service又导入right plate见过很多遍了,To了过,那么第二个写增上改查,那么弟兄们呢,也已经明白了,我们用TK map或者是我们的通用MAP4啊,已经。点一下一键生成也演示过了节约时间,所以我们就写大家不熟悉没见过的内容,了解的这些数据库每被提次增加改查的一律不减,所以我这偷个懒就不加美被T了,我这呢就模拟我从你看get这个产品,从买CQ数据库查出了这个参加活动的20件特价商品,对吧,加载到聚划算的red里面,然后加载到聚划算的从red里面读出来加载到页面也记啊,我这点一下看到的这些就要要求你把。
17:06
里面参加活动的给我弄出来,好吧,那么来了,那么接下来弟兄们该怎么写呢?老规矩,先写我们的service,那么这个时候啊,Public初始化巨划算,来这波,看看我们的诉求,定时器将参与计划算活动的特价商品放进去,来。我一点进来就要有,那么自然而然,是不是我微服务一启动就要有,那么这个时候是不是又可以用这个了,OK,一启动为服务就可以进行加载的,对吧,这个呢很好用,那来吧,我们呢,罗个音这块写个什么呢?就是启动我们的定时器,那么天猫聚划算功能模拟开始,OK,好。
18:00
来就这么一个说过了一初始化以后就要跑起来一个后台定时任务,按照P。按照商家签的合同。合同某些key。到点了,说明这个T要过期,要被迪塔拿下,然后换上下一批次参加活动的热点TOK,所以我们这呢,就继续那第一步一步步给大家写清楚啊,我们用多线程啊,模拟定时任务啊,我就不想去开那些什么,不再开那些叉叉l job了这些东西了,听懂了吧,那也就是说。那么模拟一个定时任务。后台任务。那么定时加。MYSQL里面的特价商品,或者说是参加活动的商品刷新到red里面,OK好了,那么这呢,弟兄们来吧,那么这个呢,叫什么都可以啊,我要错,我呢在这后台一直跑着这么一个定时任务啊,我们这里用一个现场来模拟,首先那么典型的就是this.get这我们是不是每次啊,比如说啊,间隔一定时间从查出来一批数据要送给这个前台显示,那么数据哪来的一样,是不是来自于我们的myq OK,那么在这呢,我们就简写了,这个就是一个list好了,那么这个呢,第二步模拟从MYSQL查出。
19:45
数据用于加载到ready并给聚划算页面形式,好吧,这是我们的第二步,那么第三步,那干嘛?新加载来的这一批,同学们是不是先要把以前的给删掉,那么这块大家请看,那么是不是采用。
20:11
Red list数据结构的,还要push命令来实现存储,这个这波能明白吧,所以呢,Right temp点二。Delete他干嘛?我把我们的聚划算这个K先要删掉,因为这波就代表是什么,先删除一波到期过期的key,也就这波不再参加计划算的活动了,下线了,我们要换上来一波什么新的,OK,那么加入最新的数据给ready参加活动,那这波干嘛呢?那么ready,诶,Ready temp.OPS大家请看现在这是不是有个for list,它这有lr push right push从右边加对吧,我们这呢也有left push,你从左边加都可以听懂你们,所以说搁到这儿,弟兄们拿个T是不是本次参聚划算活动的最新参加此时此刻或者叫当天的啊,比如说这个聚划算活动你最起码参加一天嘛,对吧,那么也说这个T是不是要存在24小时啊,或者one带一天,那么现在。
21:28
那我演示的就是查出来聚划算里面的每个记录,一楼写全部记录,假设有这个100条对吧,五大品牌五楼,那么一楼显示20条,所以说在这块就给它弄过来,这么说能跟上,那么相当于说删掉。过期的加进最新查出来的,就这么简单好了,那么下面第五步这个就是我干嘛呢?那么暂停一秒钟啊,这是我们的第五步,我干些什么事呢?暂停一秒钟。
22:06
间隔对,应该抱歉不是,应该是60秒钟,我干脆这写成分钟吧啊。好,那么这个时候啊,一分钟,那我要做的事情呢,就是暂停一分钟那么间隔。一分钟执行一次,OK,模拟聚划算一天。执行的参加活动的品牌,也就是我们这的一分钟就模拟一天,弟兄们OK吧,好了,那么这个呢,就完成了我们的什么service,待会一启动,我们就把本次要参加计划算的撸出来,好,那么搁到这儿我们弹出了。
23:01
一样的CTRL这些啊,都是一些定义的一些前缀,聚划算的key的常量red,那么现在相当于这就是分页查询,只不过这是一页,就是一楼,一楼20个品牌,对吧,我们呢,在高频发,高频发的这种情况下,只能走RA查询,走DB的话必然会把MYSQL给打爆,所以搁到这,那么这些我省略了,OK就不写了,那么点一下我查找,那么就要把最新的加起来,相当于这啊,我点一下这个聚划算就是find的查找,当天有哪些参加了聚划算这个活动,便宜,我们可以团购好活动价是多少,那么来吧,叫这个例子哈,那么自然而然,前台这个list叫读起来,那是H5工程师的事,那么这个list那数据哪来的?剩下来就ready好吧,那么所以说各位同学到这,那么这个叫start,那么我们是不是要。搞定一下我们的分页对吧?那么配几减一乘以size,然后long这个呢,End等于多少,是不是我们的start加上我们的size再减一,能理解吗?比如说啊,现在我们一般啊,我们给人的时候呢,大家都清楚,我们不会说第零页,但是程序员从第零页开始,那么客户呢,你点一下啊,比如说第一页出来了,那么请问一减一是不是我们的零,假设我们的size按照计划算呢,是一一楼啊,一楼显示20个,我们这呢,就。
24:36
每次一,每页呢五条,那么假设我们这个S就是五,一减一是零吧,零乘五是不是开始就是零,那么再来零加上五减一是不是就是四,说明什么?是不是相当于我们的LRA积,然后LIST0到四,那么是不是就是前五条记录,也就说我们就认为前五条记录就把它放放在大牌服饰上好吧,那么这样呢,就完成了我们的一页,以此类推,好,这是我们的一个说法,那么接下来呢,同学们。
25:10
搁到这,我们就是采用list结构。里面的L命令。来实现加载和分页查询。那么来吧,弟兄们,List在这是不是就是我们的templ.options for list点什么?Run起来好了,哪一个活动是不是我们的聚划算这个关键,这个key,那么你从哪显示到哪,Start end,这么说弟兄们,OK吧,好了,那假设从right里面查不出来呢?那么这个时候我们的。
26:00
It's empty,假设这个list麻烦了,那么这个时候我们呢?Todo干嘛呢?走MYSQL查询这一波OK吧,那么说明肯定是出问题了,我们必须要从list加载,那么list没有,咱们是不是要去查MYQL?好,那么搁到这落个点in inform查询结果或者叫。参加活动的商家OK,好了,搁到这list没问题。那假如说啊,这块也没有什么资源关闭的一个动作啊,那么在这我们呢,如果list这没有,其买条也被打爆了啊,不用多讲,如果这一步走到这,那么一定是什么出缓存机穿异常了,那么一般啊red宕机了,或者red网络抖动导致time out,你呢可能需要同事OK,那么在这。
27:24
不好意思了,必须落点就不是付了,是error,对不起,请记下来,比如说去划算本次活动的exception。OK,好,那么。接下来如果这这种异常,你要是想加这个同事机制,你再还可以什么再次查询MYCQ啊,全查询,那么就看你的业务了,OK好了,那么各位亲,这个就是我们的第一组,我们先来尝试一下啊好,同学们请看啊,我假设我第一他聚划算没有这个K吧,好,那么接下来同学们。
28:14
一切准备妥当了,我们就来尝试一下,首次就把我们的第十任务跑起来,把20条记录加载进我们的ready,然后我们点一下模拟,这啊点一下来给我拿出五条记录是某一楼的记录来参加计划算好,那么各位同学启动一下我们微服务,我先暂停一下录屏同学大家请看啊,我们这启动定时器天猫聚划算功能模拟开始,哈哈,这款打出来了,应该程序没有什么太大问题,那么不妨啊,我们来看一下。我们的l RA list0到负一是不是查list,当然我们现在这个list是不是要巨划算,一查弟兄们怎么样,现在是不是有20条,那么有点类似于就说一到五条是第一楼,就是我们这的聚划算的什么东东,大牌服饰,然后呢,六到十条就是我们的食品生鲜,这一波弟兄们没问题吧,那么刷新一下我们的四袜哥来弟兄们看一下我们后台会不会成功的显示啊,并打出来,那么来吧,那么这块呢,搁到这儿。
29:23
我们呢,来一个聚划算的商品列表,尝试一下第几页啊,第一页五条对吧?好,我们查询一下同学们,请看这个时候是不是从后台打出参加活动的商家,那么这个时候ID产品的名字啊等等等等这些就是后面的数据了,就不再啰嗦了,说白了有点类似于当我们设定好这些参数以后,点一下这个相当于就点到了我们聚划算这个入口,一点进来了以后,是不是按照我们数据一次性查出了多少条,20条,那么按照我们的业务逻辑。
30:00
前五条就走食品生鲜六到12,每家数码,11~15,母婴国际,那么这样的话是不是参加单页此时此刻闹本次活动聚划算团购业务的全部商家就这20个,是不是历历在目?那么这个时候弟兄们你是不是就可以把它展现起来,然后假设我点到这一条了啊,这有个detail,那么这个detail呢,也许就是立即购买会吧,跳到另外一个订单,下订单,购物车的微服务模块,该怎么做就怎么做,打个标识,我是参加聚划算的,那么算这个价格,那么出现一些新的变动,OK,这个就完成好。那么同学们写到这儿应该没有太大问题,都很自然对吧,像大自然一样自然。个问题时,兄弟们老眼。至此步骤,上述计划算的功能完成了,请思考在高并发下面有什么经典的生产问题?也就是说,请同学们结合我们的业务要求和杨哥刚才写的这些代码,请你思考一下我有哪些隐含的bug,跟我们的缓存机窗有什么关系?好,各位同学思考一下。
31:17
功能完成,但是下面看看什么情况下我们这个代码里面存在着一些隐患,会导致缓存击穿,把我们的MYSQL打爆,下面弟兄们请看一下bug和隐患说明。热点key突然失效,导致可怕的缓存击穿,来,弟兄们请看一眼。回到我们的service。这段代码呢,就是都好说对吧,反正下面每一分钟又重新查一次,最多这些序号啊,编号呢,换了一下无所谓,关键的代码是在这儿,也只有他这会出错,死在哪儿呢?死在这儿。
32:00
请告诉我,各位亲,这是我们的service,这是我们controller controller去调service。那么service这delete和。L push这个它们两个是原子操作吗?这个是不是两条命理,也就是说商家在这儿,也许母婴国际这儿,23:59:59。今天的活动结束,下线好上,对不起,删掉旧的,我是不是才能给你灌进去新的。那一秒钟聚划算业务是不会停的,也许这一秒钟刚好你在山的十号,就在这第59行,这也有人一叠发现这个燕子包啊,什么裁缝链条什么没了。不好意思啊,程序还在这忙着加呢,数据没了,我直接导到我们的买,这就是杨哥前面所说的,旧的还没有退,全部退下来,新的还没有补上去,新环不接,有个缝,直接被人家偷机了,所以它不是原子命令,存在热点缓存失效的隐患。那么大家请看我们上面是我们的service,那么controlr了。
33:24
如果我现在去查,对不起,删掉了这个list倒是从白次就查出来了,删掉了,但是对不起,第二批要参加的还没灌进去呢,你一旦没有灌进去,我现在马上去查,哎呀,怎么页面是空的,一空的话,为了避免失效,马上去查MYCQL,如果你不加以控制的话,弟兄们爽死你了,一下子就缓存击穿了,被打爆,被打爆了,OK,所以弟兄们。怎么解决。那么。第卡命令执行的一瞬间有空隙,其他请求线程继续找着维纳打到了MY色Q暴击缓存基础啊,好,咱们来吧,弟兄们,我们。
34:08
最终的目的是要干什么?两条原子米原子性都还是其次的,主要是防止热气突然失效,暴击MYSQL,打爆系统啊,那么来吧。怎么解决缓存击穿产生的原因就是热点key失效,那么它解决方案是不是要互斥更新,随机退避和差异失效时间,那么弟兄们怎么玩?杨哥互斥更新嘛,我也能理解是吧,就加那个双双锁对吧?双锁减那个双检索的那个机制,那么什么叫随机退避和差异失效时间呢。好,那么我们的最终目的也都明白,那么请问杨哥该怎么解决我们的这个bug和隐患?Bug和隐患,前面给大家进行了详细的说明,那杨哥痛快点,如何进一步升级和加固我们的案例呢?来。
35:08
热点可失效导致缓存击穿解决方法,互斥更新,随机退避,差异失效时间杨哥互斥更新前面你介绍过了,无非就是什么加锁双减的策略懂,那什么叫随机退避和差异失效时间呢?那么下面请听我慢慢到来,第一个互斥更新双减加速过第二个差异失效时间,意思就是。因为我们的缓存突然这一份没了,我怕它点空了,暴击买色Q击穿,干脆我来两份,那么也记我们的双缓存策略,请看如何解决缓存击穿分两个。构建,也就是加载的时候怎么加,就是从MYSQL如何把数据加进我们的,第二个怎么查,一步步来,请大家看。
36:02
后台是不是有个定时任务,要定时更新。如果以前只有一份,它突然没了就没了,那么现在我干两份,所以我新建的时候开辟两块缓存,主A从B,先更新B,再更新A,严格按照这个顺序啊,先B后A来进行更新新建,那么查询呢?先查询A,如果A没有消失了,时间到期了,被删掉了或过期了,再去查询B,相当于这份。数据有两个且一样的内容,但是两份缓存它们的过期时间是不一样,有点类似于啊,我们呢,查的时候先去查A,就是我们的正常业务的red缓存,但是A里面又包了一层B,内容是跟我一样的,那么如果我这23:59:59,假设那一瞬间啊,我这个缓存应该比delete失效,但是就这一秒钟。
37:01
我这块点,我为了尽量避免缓存击穿这一秒钟的,我还有一份这个B,真过了这一秒删干净了以后,我们新数据上来了,假设你就是客户去点,再点,哎,我不要叶子包,哎,再刷新下,回来一看哦,已经更新完了,那么这个时候就那一秒钟,我们呢,业务上是可以接受的,所以在这儿弟兄们我们再说一下,相当于啊,我们这个write。有点类似于套了两层,这么说弟兄们能跟上啊,那么下面请看啊我们的讲解。我们在这儿呢。我们的查询是先查询A,就是外面这个是A,如果A没有了,再查询B,所以说我们现在外面这个。说我们的A,也就是我们之前一直所说的red缓存,但是A里面又有一个B,两个数据内容一样,相当于是什么这个人套了两件防弹衣,以前只有A的时候,那对不起,没有就没有了,这儿red没了,打爆白色条,那么现在我们差异这个失效时间,哎,有可能A失效的时候,那一瞬间有人来查,也可能没有人来查,如果没有人来查最好,可是有人来查的时候,是不是前面说过一种情况最极端最危险的怎么着?
38:29
旧的数据没删干净呢,新的数据还没接上来呢,金环不接的时候容易产生我们这样的麻烦,因为迪delete塔和这个两条的命令,它并不是原子性,那么聪明如你你,你会想,哎,杨哥,这他妈还有什么好说的,简单。Lock按洛搞定第二个干嘛?Look脚本你不说非原子的吗?我给它干成个原子的不就行了吗?这个原子命令加锁会不会慢?这是第一个,第二个你要是用UR脚本,请告诉我,如果你没有第二层,你现在在这个录二脚本时候,它可能是按比例塔。
39:15
没上完。那么这个时候我这个程序一查查不到马上就去查马C买,是不是还是会杜绝不了这种问题,还会产生,听懂了吗?所以这个问题的关键不是枷锁,或者用lur脚本把它合成一块就行了。如果真这么简单的,干脆以后全部用R脚本干调用这个RA不就完了吗?全么原子性的做完了再来,别人这是两条,如果更用复杂业务三条呢,三条执行起来也很慢呢,我这巨划算,我可是天天点着呢,我要求你查不到就马上给我数据,我这儿交了钱给阿里这块空了我这个验资包服务宕机了十分钟,这个损失谁赔?你怎么知道我这十分钟也许有个大卖家一口气买了1万个呢,那么这个时候是赔不起的。OK,所以各位亲,问题不是在这儿,不是加不加锁录不漏啊脚本问题是查不到了,你要迅速给我返回来,明白吗?好,所以在这我们就要清楚。
40:12
搁到这两层缓存,双缓存架构来解决这个问题,如果A到点失效或者被删掉了,新环不接的时候,A还没有更新完,不好意思啊,我还有一份BA找不到,我去找BA,反正也这一秒钟就把这个数据线给你,等完成了,我们马上数据又更新了,所以呢,顺着查倒着更新,什么意思啊,先更新B再更新,哎,听懂了吗?OK,好,我们同学们思路整明白,我们下面来写一下我们的代码来,老规矩,杨哥呢,还是节约时间啊。上面这个是我们初始化第一次,下面这个,那么来吧,我们呢就分成AB2套缓存,那么这个呢,我呢就先给它注掉,或者还是开着吧,在这块啊,因为我怕它数据数据乱了,那么我先把这个给它注掉,不让它加载,好同学们来看一下这块该怎么写吧,那么来吧,这块呢,天猫淘宝都一样啊,跟上面统一的就叫天猫,那么来写一下,那杨哥该怎么写呢?
41:23
好,我们来写一下我们相关的落地代码,结合我们刚才的分析,那么首先我们现在呢,就要开启AB2套缓存,明白,所以这个是我前面定义的聚划算A,聚划算B这两个常量用在这儿来,那么同学们。还是熟悉的配方,还是熟悉的味道,搁到这儿靠哪了啊,直接拷贝,那接下来呢,我们呢,这两个咱们就不要了,听好,接下来这个是关键。回到我们的设计,现在我们先写的是service层,也即缓存的新建和更新,一定要体现出一个东西叫差异失效时间,也即主缓存A,就是原来我们要去参加计划算活动,先从A查出来,但是假设某个活动就参加一天23:59:59那一瞬间那点寸劲,导致我们的系统到期时间以后,Right自动的把它拿下来,那么就会出现新环不接,旧数据还没有下来,新数据还没有更新完成,那么那一瞬间就容易存存在热点可失效,导致缓存被击穿。所以我们开辟两块缓存主A从B先更新B,再更新A,也就是说一个人穿两件防弹衣,外面这个是A,里面这件是B,让B的时间。
42:58
要比A多一点,那么就保证就算A那一瞬间因为各种原因,比如说活动时间到期23:59:59~0.1天到了下降,那这个时候突然有人来反问,A没有了,但是B它还存在,因为那个时候我们的按照业务逻辑判断,旧的没有完全下架,新的还没有完全更新上去,还是以旧的为准,OK,那么这个严格按照这个顺序来进行更新,那么所以说我们先搞定我们的新建体现差异失效时间,来吧,同学们业务讲清楚,那么在这块我们呢,继续第三步,就是我们的先更新B缓存,且让B缓存过期时间超过A缓存,如果A突然失效了,还有B都底。
43:59
防止击穿,那这个该怎么写呢?right.delete我们先把。
44:07
缓存B给我删掉,咱们是不是先更新B嘛,然后ready some point.os for list添加进来,Left push or,然后去划算B,哪个数据是我们刚才的list,然后呢,再来spare过期时间,那么巨划算BOK,那么过期时间的话,假设啊,我们这个时间呢,就是参加一天,一天是24小时,24小时就是86400秒,这么说没问题吧,但是注意这是B,我们希望它的时间是要超过A的,A能够用86400,所以B呢,给你多个十秒钟,明白了吧,一般正常情况下啊,因为参加聚划算的活动,按照我们刚才所说的一页一楼就是20条记录,删一个key 20条记录,它不是什么大key,十秒钟左右正常一。
45:07
第五应该是商的完了,OK,好,那么同学们这个呢,就是我们的B,那接下来第四步呢,我们就在更新A缓存,好还是一样的代码。搞到这,那么同学们请看,在这边我就改成A,在这边全部改成我们的A,然后这个也是A,好它呢就是86400秒,好,那么这个秒改一下啊,86400秒刚好就是一天,代表某一楼这20条记录,参加聚划算的这个活动就是一天,那么好,一开始我们从这个MYSQL数据库加载,我们要参加本次活动的。
46:01
全部历测数据,然后完了以后啊,间隔一分钟我们就模拟一天数据呢,又重新换一次,这个呢,就是我们预先加锁AB2个缓存的。参加第一次活动的,那么过了一分钟,相当于说早一秒。定时任务一跑扫一遍引号,又是第二次,又参加第二次活动的新的20条数据,好吧,注意在这块是不是达成了差异,失效时间这个要比A晚过期十秒钟,好吧,那这个呢,完活,那接下来。回到我们的第二个方法,那节约时间,写过的同学们不再啰嗦了,那接下来主要的业务逻辑我们来写一下,还是刚才的,那这个时候呢,就是AB双缓存架构,防止热点T突然失效,那么这个时候我们返回去的list对不对?中间呢是一个分页的,一个最简单的对吧,一页。
47:02
一楼就20条记录,我们这模拟呢,就一页大概就是五条,对吧?好了,你这块怎么办呢?这个list就是要从register缓存里面加载过来的,那么list等于点OPS for list.range哪一个?那么现在注意我们的说法,更新完成了,查是先查什么?先查外面这层防弹机主缓存A,先查A,先A后B,那么弟兄们还记得吧,先A后B,那么正常情况下,一天A只要没失效,永远从A查到就没事了,但假设A那一秒钟突然失效了,出现青黄不接的情况。马上要有一个兜底了,找到B,那么这个时候旧的没有换完,新的还没上去,我们还是以老数据为主,因为新的还没到嘛,那么老的先顶一下,如果你觉得参加这个活动这一秒钟还不是,那么你把购物车清空,再刷一次,一秒钟以后就有了,OK,从业务上来做一个这么一个约定好了,那么这个呢,就对应的就是我们的A,然后A的话呢,Start,然后呢,End,没问题吧,那接下来if connection you is empty list,假如说从这来查询A不是空,那么自然而然就是从A这儿取到了我们这一楼的要参加计划算活动的数据,送给前台显示啊过,那问题是如果它空了呢?空了的话同学们都清楚啊,如果那一秒钟A突然空了,没有其他补救措施啊,是不是导致了传统的red热点T失效,管它一下子全部达到MYB?
48:44
对吧,那这个时候我们要避免,尽量的就防止系统被打爆打穿,不要全部激活攻击MYCQL,要么双减加锁,要么用我们这样的双缓存架构,那么此时如果A是空的,那对不起,Log因符要记下来A缓存。
49:03
已经过期失效,或者说是什么。活动结束了,记得人工修补和B缓存继续顶着,OK,当然啊,这个时间的话呢,我这是十秒钟对吧,你呢可以再设的长一点,就看你的业务好了,你这时候我们把这个意思说清楚啊,那接下来还是这个例子,他怎么着,他是不是就从A查不到了,以后不要马上去找数据话给我去找谁,给我去找B,因为AB他们现在两个的数据是一样的,只要但凡走到这一步就说明什么。老数据没有删干净,下没有下线干净,新数据还没有完全上线,对吧,那再查一次啊,那对不起,如果现在再查一次以后这个是从B过来的,那么B如果不为空了,OK,那么返回保证我们的系统没有被打穿,但是如果两次缓存都是A查也是空,B查也是空,那么正常而言,你的业务架构和技术上应该有问题啊,不应该两次缓存都是空了,你这个非常严重了,所以说呢,各位亲,如果当然啊,这种情况很少,允许你去走我们的买色条,OK,好,那么最终我们来查一次,好,其他的那也就是之前写过的代码好了,那么同学们,我们这启动一下我们的程序,完成一下我们对应的业务操作,看看能不能加出两个数据,好,我们启动一下我们对应的程序,我先暂停一下录屏。
50:45
去呢,成功启动,那么来同学们L,我们这儿呢,回到我们的ready,先看看啊,有没有加载成功,那么这个时候就是我们的聚划算A0到负七全部,大家请看是不是5334啊,有了吧,那么再来对应的找我们的B,也就是参加这一天计划算活动的,那么大家请看是不是5334,然后20条记录分门别类的都给你整好了,这么说能跟上好了,那么弟兄们在这块以后,我们这呢,稍微等一下啊,一分钟以后他是不是就模拟暂停一分钟时间,间隔一分钟执行一次计划算一天执行参加的活动,对吧,86400秒就刚好是一天,好,我们这儿呢,等待。
51:31
一分钟,它。重新刷新一次缓存,也就是说一分钟以后我们的第一条记录就不应该ID是5334,这个换了一批数据听到好,我先暂停一下录屏,哎,大家请看一下啊,时间到了以后,一分钟重新刷一次缓存,我们第一次第一批参加活动的是53334是头条记录,现在我再查A多少了,是不是变成2442了是吧,下一批参加数据的活动的数据又改变了,大家请看。
52:00
现在每隔一分钟啊,假设A是7741,又过了,假设B,大家请看7741,那么这样是不是AB2个缓存都有同一批数据,由于差异了过期时间,那么自自然然的如果从A能查得到最好,突然A失效了,有一个B跟A是一样的,就来兜底,不要导致因为热点T突然失效,打爆买体。
我来说两句