数据不一致问题描述的是相同的数据可能同时存在于DB和缓存中。可能会出现DB和缓存中的数据不一致的情况。如果缓存有多个副本,那么多个缓存副本中的数据也可能不一致。原因分析不一致的问题,大部分都与缓存更新异常有关。例如更新DB后,写缓存失效,导致缓存中存有旧数据。另外,如果系统采用一致性Hash分布和rehash自动漂移策略,节点多次上下线后也会产生脏数据。当缓存中有多个副本时,更新某个副本失败也会导致该副本中的数据为旧数据。业务场景导致数据不一致的场景也有很多。如下图,当缓存机器带宽满了,或者机房网络波动时,缓存更新失败,新的数据没有写入缓存,会导致缓存和数据不一致数据库。缓存rehash时,某台缓存机器反复异常,多次上线下线,多次更新请求rehash。这样,一条数据存在于多个节点中,每次rehash只更新某个节点,导致部分缓存节点产生脏数据。解决方案应该尽量保证数据的一致性。这里也给出了三个选项,大家可以根据实际情况选择。第一种方案,缓存更新失败后,可以重试。如果重试失败,失败的键将被写入队列机器服务。缓存访问恢复后,这些键将从缓存中删除。当再次查询这些key时,会从DB中重新加载,以保证数据的一致性。第二种方案,缓存时间适当缩短,让缓存的数据提前过期,然后从DB重新加载,保证数据的最终一致性。第三种方案不使用rehash漂移策略,而是使用缓存分层策略,尽可能避免脏数据。数据并发竞赛问题描述第五个经典问题是数据并发竞赛。在互联网系统中,在线流量比较大,缓存访问容易出现并发数据竞争。数据并发竞争是指在高并发访问场景下,一旦缓存访问找不到数据,就会有大量请求并发查询DB,导致DB压力大幅度增加的现象。并发数据竞争主要是由于多个进程/线程中有大量并发请求获取同一个数据,而这个数据key由于各种原因,比如刚刚过期或者被移除,在缓存中不存在.没有Any协调,然后并发查询DB,请求同一个key,最终会导致DB的压力大幅度增加,如下图。业务场景的并发数据竞争在大流量系统中也很常见,比如票务系统。如果某个车次的缓存信息过期,大量用户还在查询车次信息。再比如在微博系统中,如果某条微博恰好被缓存淘汰了,但是这条微博仍然有大量的转发、评论、点赞。以上几种情况都会造成车次信息和微博并发竞争阅读的问题。解决方案要解决并发竞争,有2个选项。选项一是使用全局锁。如下图,当缓存请求未命中时,首先尝试加全局锁,只有加全局锁成功的线程才能去DB加载数据。当其他进程/线程读取缓存数据miss时,如果发现key有全局锁,就会等待上一个线程将数据从DB返回到缓存中,再从缓存中获取。第二种选择是保留缓存数据的多个备份。即使其中一个备份中的数据过期或被删除,其他备份仍然可以访问,从而减少数据并发竞争,如下图所示。
