查看更多当前 - 案例分析 - 数据库系统与缓存设计
简单
案例题
2019年11月第4题
#必须掌握
#超纲

阅读以下关于分布式数据库缓存设计的叙述,在答题纸上回答问题1至问题3。
【 说明 】
某初创企业的主营业务是为用户提供高度个性化的商品订购业务,其业务系统支持PC端、手机App等多种访问方式。系统上线后受到用户普遍欢迎,在线用户数和订单数量迅速增长,原有的关系数据库服务器不能满足高速并发的业务要求。
为了减轻数据库服务器的压力,该企业采用了分布式缓存系统,将应用系统经常使用的数据放置在内存,降低对数据库服务器的查询请求,提高了系统性能。在使用缓存系统的过程中,企业碰到了一系列技术问题。

分值(12分

该系统使用过程中,由于同样的数据分别存在于数据库和缓存系统中,必然会造成数据同步或数据不一致性的问题。该企业团队为解决这个问题,提出了如下解决思路:应用程序读数据时,首先读缓存,当该数据不在缓存时,再读取数据库;应用程序写数据时,先写缓存,成功后再写数据库;或者先写数据库,再写缓存。
王工认为该解决思路并未解决数据同步或数据不一致性的问题,请用100字以内的文字解释其原因 。
王工给出了一种可以解决该问题的数据读写步骤如下 :
读数据操作的基本步骤 :
1.根据key读缓存;
2.读取成功则直接返回;
3.若key不在缓存中时,根据key(a);
4.读取成功后,(b);
5.成功返回 。
写数据操作的基本步骤 :
1.根据key值写(c);
2.成功后(d);
3.成功返回。
请填写完善上述步骤中(a)~(d)处的空白内容。

参考答案

原方案采用“写缓存再写数据库”或“写数据库再写缓存”,看似能保证缓存与数据库的数据一致,但实际上存在双写不一致问题
例如,先写缓存后写数据库时,如果缓存写成功而数据库写失败,会导致数据不一致;反之,若先写数据库再写缓存,缓存更新失败时也会造成矛盾。
此外,当多个请求同时发生时,可能出现读写冲突,即一个请求刚写数据库但缓存未更新,另一个请求却从缓存读到旧数据,造成脏读。这些问题说明,双写方案并不能彻底解决一致性。

王工的改进方案采用缓存淘汰机制(Cache-Aside Pattern)。
读操作:优先从缓存读,若未命中,则从数据库读并更新缓存;写操作:先写数据库,再删除或使缓存失效。
这种方式的优势在于避免了缓存与数据库的双写,只需保证数据库正确写入即可。缓存失效后,下一次读请求会触发数据库读取并刷新缓存,从而实现最终一致性。
由于删除缓存的操作是轻量级内存操作,失败概率极低;即便出现偶发不一致,也会在下一次读取时自动修复。
因此,该方案在保证高性能的同时,极大地降低了缓存与数据库不一致的风险,成为业界常见的实践。

(a)从数据库中读取数据或读数据库
(b)更新缓存中key值或更新缓存
(c)数据库
(d)删除缓存key或使缓存key失效或更新缓存(key值)

凯恩解析

在原有方案中,应用程序写数据时,先写缓存,成功后再写数据库;或者先写数据库,再写缓存。这里存在双写不一致问题。不管先写缓存还是数据库,都会存在一方写成功,另一方写失败的问题,从而造成数据不一致。当多个请求发生时,也可能产生读写冲突的并发问题。
王工的解决思路是(同样是旁路模式,但是写操作的细节进行了改进,变成了删除缓存):读操作的顺序是,先读缓存,如果数据在缓存中,则直接返回,无须数据库操作;如果数据不在缓存,则读数据库,如成功,则更新缓存,如失败,则返回无此数据。
读操作主要解决查询效率问题。写操作的顺序是先写数据库,如失败,则返回失败;如成功,则更新缓存。

Cache-Aside Pattern 更新缓存的方式有:如缓存中无此key值,则在缓存中不作处理;如缓存中存在此key值,则删除key值或使该key值失效。写操作的顺序主要防止数据库写操作失败,缓存更新为内存操作,失败的概率很小。同时删除key或使key失效,则在下一次查询该key值时,会发起数据库读操作,并同步更新缓存中的key值,从而最大程度上避免双写不一致问题。

联系我们
隐私协议
用户协议
微信公众号
知乎
小红书
浙ICP备2021029036号
@2022-2026
嘉兴市安芯网络科技有限公司 版权所有