查看原文
其他

两次被裁之后,我终于解决了数据库缓存一致性问题

码农小说家 PHP开发者 2022-09-07

我是一名毕业两年的程序员。

算上实习,工作三年了,正是一个程序员的黄金时代,这让我普通而自信。

但是从实习期,我就被辞退两次了。

今天是我的又一场面试,而且是大厂面试。我要一洗前耻,证明自己。

好了,我要赶紧出发,不然通往美好生活的996路公交车又堵了。

经历过西二旗的人潮人涌之后,我按时来到了面试官面前。

和面试官寒暄了几句,他直接问了一个技术问题

"如果网站流量太高,我们通常会加缓存来减轻数据库压力,读缓存很简单,如下图

关于写缓存,你知道怎么设计这个方案,保证缓存与数据库的数据一致性吗?"

一刹那,往事涌上心头,因为我在这个问题上,已经栽了两次了。

第一次是在实习期。

那年二十,刚刚工作,每日如喽啰。

实习的公司是一家外包公司,没有什么技术规范,按时上线是大家最重要的诺言。

我的第一个任务就是增加缓存,降低Mysql的压力。

这个任务最核心的就是写缓存时怎么保证缓存和数据库的一致性,当年还是实习生的我显然没有意识到这个需求的复杂性,直接采用的方案就是

先更新数据库,再更新缓存

上线第二天,网站就出了Bug,我就被甲方爸爸投诉了。

后来,在复盘中我才发现,网站挂了的原因是:

如果同时有请求A和请求B进行更新操作,那么会出现

请求B是最后请求的,那么应该是他最后更新缓存为正确的数据,但是有可能请求A处理的更慢,所以请求A更新了最后的缓存。

另外这个系统写数据库场景比较多,而读请求比较少,这种方案就导致数据压根还没读到,缓存就被频繁的更新,浪费性能。

然后我当天就被辞退了,理由是在办公室工位吃螺蛳粉。

没想到啊没想到,在这个问题上,我还能梅开二度。

毕业之后进入的第一家公司,兢兢业业两年半,业务量也逐渐上来了。

访问量上升,代表着我的薪水也有机会上升。我立马做了个方案,准备在一向不看好我的经理面前表现一把。

核心逻辑就是采用

先删缓存,再更新数据库

经理看完方案,直接画了下面一个图

淡淡说道:"这样的话,缓存都是脏数据了。"

我想了下,说:"确实,不过可以双删缓存。"

public void write(String key,Object data){  
     redis.delKey(key); // 删缓存  
     db.updateData(data); //更新数据库  
     Thread.sleep(1000); // 根据业务执行时间确定具体的时间  
     redis.delKey(key); // 我再删缓存  
 }  

经理笑了笑,说:"我们可是采用了MySQL读写分离架构啊,如果有下面这样两个请求

还是会导致数据不一致啊!"

我有点不悦,这可是我主动加班做的方案,一句赞赏都没有,怎么老是被质疑?

但还是回答道 "那就sleep时间修改为业务执行时间+主从同步时间就可以了,就是等主从同步完了再删一次。"

经理又问道:"嗯,可以。不过你这样删除缓存两次,会造成吞吐量降低,怎么办?"

我觉得很不爽了,又不是他开发。算了,我回应到:"那就将第二次删除改为异步的。即重新起一个线程,异步删除。"

经理又问道:"那要是第二次删除缓存失败呢?"

我无奈了:"您说呢,毕竟您也是经理,要不您也说两个方案让我学习一下?"

经理笑了笑:"年轻人,路走窄了啊!"

然后我当天就被辞退了,理由是我代码缩进用的Tab而非空格。

此刻,我坐在面试官前面,面对这个问题已经有三年了,我也早已胸有成竹。

想到这,我直接站了起来,走到白板面前,说道:"实不相瞒,前两次我的离职都和这个问题有关,所以我也思考了很多,不如直接我就讲讲最优解法。那就是

先更新数据库,再删缓存

当然,这样也会有并发问题,比如

但是数据库读操作速度远快于写操作,所以存在脏数据的可能性为0。

当然如果您问,如果真的存在怎么办?

简单,双删就行了,即第一次删除缓存之后,等待一段时间重新再删一次。

当然您如果还问,删除缓存失败了怎么办,解决方法如下

即引入消息队列,删除缓存失败的记录下来重复删除,直到成功方可。如此一来,万无一失。"

面试官点了点头,鼓了鼓掌,叹到:"优秀,不过我好奇你前两次的离职,可以和我讲讲吗?"

面试官听完我的经历之后,对我深表同情,问道:"假如我给了你offer,你走到之前那些开除你的人面前,你会说什么呢?"

我走到窗户旁边,望向远方,轻声道:"我会走到他们面前,把offer甩给他们看,告诉他们,我等了三年,就是要等一个机会,我要争一口气,不是想证明我了不起,我只是要告诉人家,我失去的东西一定要拿回来!"

参考资料 https://www.cnblogs.com/rjzheng/p/9041659.html

- EOF -

推荐阅读  点击标题可跳转

1、71张图详解IP 地址、IP 路由、分片和重组、三层转发、ARP、ICMP

2、这是我见过对DNS最通俗易懂的解释了

3、好家伙,你管这破玩意叫文件系统?


看完本文有收获?请分享给更多人

推荐关注「PHP开发者」,提升PHP技能

点赞和在看就是最大的支持❤️

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存