当前位置: 首页 > 科技观察

一个简单的需求让我改了十几行代码,不得不吐槽什么是重码!_0

时间:2023-03-14 08:23:07 科技观察

话在我们这个行业是很幽默的。我们总说编程就是CV,黑客写的程序大部分都是靠复制粘贴。其实...0前言只要用到Redis缓存,就一定存在缓存和DB数据一致性的问题。如果数据不一致,业务应用从缓存中读取的数据不是最新的数据,可能会导致严重的错误。如果商品库存缓存在Redis中,如果库存数量不正确,下单时可能会出错,这是不可接受的。1什么是缓存和DB之间的数据一致性?一致性包括以下几种情况:缓存中的数据值与缓存中的数据必须与数据库中的数据值相同。DB中没有数据的缓存中的最新值不满足这两个条件。.2缓存的读写方式根据是否接收写请求,缓存可以分为读写缓存和只读缓存。2.1读写缓存如果要对数据进行增删改查,需要在Cache中进行。同时根据采用的回写策略,决定是否同步回写DB:2.1.1同步write-throughcache时,也同步写入数据库,缓存中的数据是与数据库中的数据一致。2.1.2异步回写写入缓存时,不同步写入DB,等数据从缓存中淘汰后再回写DB。使用该策略时,如果数据还没有写回DB,缓存就会失效,此时DB将没有最新的数据。所以,对于读写缓存,如果要保证缓存和DB数据一致,就必须使用同步直写。如果采用这种策略,需要同时更新缓存和DB。所以在业务代码中使用事务,保证缓存和DB更新的原子性,即两者:要么一起更新,要么不更新,返回错误信息,否则重试,不能实现同步直写。在一些场景下,我们对数据的一致性要求不高,比如缓存电商商品的非关键属性或者短视频的创建或修改时间等,那么可以使用异步回写。2.2只读缓存新增数据直接写入DB,删除数据删除修改DB,删除只读缓存中的数据,这样应用后续访问这些新增、删除、修改的数据时,有就是Cache中没有数据=》缺少缓存,这个时候把DB中的数据读到Cache中,这样以后访问数据的时候,直接读取Cache就可以了。接下来我们看只读cache看看我们会遇到什么问题,如何解决。3新数据直接写入DB,没有操作Cache,此时Cache本身没有新数据,DB是最新的值,所以在这个时候4删除和修改数据这时候应用程序需要更新DB和删除Cache,如果这两个操作不能保证原子性,可能会出现数据不一致的情况。4.1先删除Cache,再更新DB4.2先更新DB,再删除Cache旧值。所以我该怎么做?好像什么都会导致数据不一致?5数据不一致解决方案5.1不并发重试,将待删除的Cache值或待更新的DB值暂存在MQ中。当应用删除Cache或更新DB时:这些值从MQ中成功移除,避免重复操作,进而保证DB和Cache的数据一致性。失败重试。重新从MQ中读取值,再次做删除或更新。如果重试超过一定次数仍未成功,则向业务层发送错误消息。在更新数据库和删除缓存值的过程中,其中一个操作失败:先更新数据库,再删除缓存。如果删除缓存失败,请重试,删除成功。其他情况不再赘述。即使这两个操作第一次没有失败,当有大量并发请求时,应用程序仍然可能读取到不一致的数据。5.2高并发5.2.1先删除Cache,再更新DB假设条件:时间t1