资料来源:小男孩摘蜗牛的前言在分布式系统中,当高速缓存和数据库同时存在时,如果存在写操作,应该先操作数据库还是先操作高速缓存?本文将分为5种方案以扩大比较范围,感谢您的阅读〜如果高速缓存维护方案是读(线程B)和一个写(线程A)操作,则“先操作高速缓存,然后再操作数据库”。流程图如下:1.线程A启动写操作,第一步是delcache。2.线程A在第二步中将新数据写入DB。线程B启动读取操作,并且高速缓存未命中高速缓存无效。 4.线程B从数据库获取最新数据。 5.线程B执行setcache以将从DB读取的数据更新到高速缓存。 “以这种方式看,没有问题。”让我们看一下第二个流程图,如下所示:1.线程A启动写操作,第一步是delcache 2.此时,线程B启动读操作,cachemiss 3.线程B继续读取DB ,并读出旧数据4。然后将旧数据设置到高速缓存5中。线程A将最新数据写入DB OK中,姜子,有一个问题,旧数据在高速缓存中,“每个如果读取的是旧数据,则高速缓存和数据与数据库数据不一致。 。缓存维护计划2上一个计划是一次读取和一次写入。如果是双重写入操作,则“首先操作高速缓存,然后操作数据库”,将发生什么? 1.线程A启动写操作,第一步是setcache2。线程A在第二步中将新数据写入DB。线程B启动写操作setcache4。线程B在第二步中将新数据写入DB。 “看,没关系。”但是有时候事情可能适得其反。让我们看一下第二个流程图,如下所示:1.线程A启动写操作,第一步是setcache2。线程B启动写操作,第一步是setcache3。线程B将数据库写入DB4。线程A将数据库写入数据库后,缓存将在B操作之后保存数据,而数据库是A操作之后的数据。 “缓存和数据库数据不一致。”高速缓存维护方案具有三个写(线程A)和一个读(线程B)操作,“首先操作数据库,然后操作高速缓存”。 1.线程A启动写操作,第一步是writeDB2。线程A的第二步是delcache3。线程B启动了一次读取操作,即cachemiss4。线程B从DB 5获取了最新数据。线程B也setcache某些朋友可能会认为,在第一步中,在删除步骤2中的缓存之前,该怎么办?线程B在读吗?此时,旧数据被缓存。这可以视为正常的业务逻辑,并且下次将读取正确的数据。该解决方案“没有明显的并发问题”,但是“步骤2未能删除高速缓存”。仍然是一个问题。但是,概率相对较小,“比第一和第二选择要好”。第三个选项也可在正常工作中使用。总而言之,我们通常使用选项三,但是对于选项三的弊端,是否有完美的解决方案?高速缓存维护方案四这是方案三的改进方案。它是先操作数据库,然后再操作高速缓存。让我们看一下流程图:使用数据库的“ binlog”“异步删除密钥”。以mysql为例,您可以“使用Ali的Canal收集binlog日志并将其发送到MQ队列,然后”通过此更新消息“确认通过ACK机制进行处理”,删除缓存,并确保数据缓存的一致性。但是还有另一个问题,“如果它是一个主从数据库该怎么办?”高速缓存维护方案5:主从数据库问题:因为主从数据库同步存在延迟。如果在删除缓存后,在将数据同步到备用数据库之前有一个请求出现时,“将从备用数据库中读取脏数据”,该如何解决?解决方案如下:高速缓存维护摘要总之,在分布式系统中,当高速缓存和数据库同时存在时,如果存在写操作,则“首先操作数据库,然后操作高速缓存”。如下所示:1.读取高速缓存中是否有相关数据2.如果高速缓存中有相关数据值,则返回3.如果高速缓存中没有相关数据,请从数据库中读取相关数据并将其放入缓存键->值,然后返回4。如果有写入数据的更新,请首先操作数据库,然后再操作缓存。 5.为了确保更新高速缓存的第四步成功,请使用binlog异步通知操作。 6.如果它是一个主从数据库,则