单线程

四季春风,不厌冬

  1. B端实时同步
    1. 新增数据
    2. 更新数据
    3. 优缺点
  2. C端批量同步
    1. 优缺点
  3. 数据不一致
    1. 改善

  Review了某营销服务中数据库与缓存同步功能,该功能包括B端和C端模块,B端为商家设置活动库存,C端为下单扣减活动库存。为了描述方便,该数据同步功能不考虑交易、订单、商品库存的交互,应用架构只涉及营销服务、数据库服务、缓存服务。   

B端实时同步

  B端一旦有请求进入应用服务时,应用先更新数据库,再更新缓存。

新增数据

  1. 请求入参中的数据落数据库
  2. 请求入参中的数据落缓存
新增数据db缓存同步

更新数据

  1. 更新数据库,并取出数据库最新数据
  2. 将数据库最新数据覆盖更新缓存
更新数据db同步缓存

优缺点

  • 优点:实时性同步
  • 缺点:数据库I/O频繁

C端批量同步

  C端请求更加频繁,且对响应时间要求更高,所以扣减活动库存的请求打在缓存上,并定期定量同步至数据库。(缓存失效情况不作分析)
消费数据缓存更新db

优缺点

  • 优点:降低数据库I/O频率
  • 缺点:数据库可能长时间不能被同步

数据不一致

  我发现B、C端的基准数据不是同一个,B端先更新数据库,则以数据库为准,C端先更新缓存,则以缓存为准,造成数据双向同步。缓存定时同步数据库功能中,存在一个窗口期,如果C端发生消费行为,缓存数据扣减,在定时任务未执行之前,B端商家对活动库存做了更新,那么缓存数据将被实时被数据库同步,而此时数据库的数据并不是最新,造成数据库数据不一致。
  
  举例:
  1. 某活动的初始活动库存为10
  2. C端消费1件,缓存-1,此时定时同步任务未执行
  3. B端修改活动库存+2,数据库更新为12,缓存同步数据为12
  4. 缓存定时同步任务执行,数据库同步为12,造成了超卖情况(真实活动库存应该是11)

db缓存数据不一致

改善

  我觉得造成数据不一致的原因有两点:
  1. 数据库和缓存的同步非单向(B端:数据库->缓存,C端:缓存->数据库)
  2. 缓存同步数据库非实时

  我的解决办法有两个:
  1. B端插入或更新数据均先更新缓存,再更新数据库,与C端保持一致
  2. B端更新数据库之前,加一个前置操作:对比数据库与缓存数据是否一致,如果不一致,则将缓存数据强刷入数据库,相当于手动触发了一次定时同步任务。
  但是问题仍然存在,因为更新数据库和更新缓存不在一个事务内,方案2只是降低了问题发生概率。根据业务分析得出B端同时修改同一个活动库存的情况相当少,所以方案2也可以接受,但是个人倾向方案1。

本文作者 : pengqin.zhou
本文使用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议
本文链接 : https://www.zhoupq.com/blog/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E7%BC%93%E5%AD%98%E6%95%B0%E6%8D%AE%E4%B8%8D%E4%B8%80%E8%87%B4%E5%88%86%E6%9E%90/

本文最后更新于 天前,文中所描述的信息可能已发生改变