缓存数据一致性如何保证

By | 2021年3月17日

缓存数据一致性如何保证

最近在思考的一个问题,如何保证缓存和数据库数据的一致性,防止出现类似于余额这种数据,在缓存里是1,而数据库修改为0后,用户再次发起扣费操作时,由于每次先会去判断缓存内余额的数据,缓存数据不一致,导致本应失效的一次请求被判断通过。这种情况在并发低的时候不太容易产生,当并发增大极有可能发生。

我在项目中主要靠两种方式来保证数据一致性:

  1. 数据必须设置随机过期时间

缓存数据最重要的目的是提高数据查询速度,在第一次查库之后将数据放入缓存,之后直接从缓存里拿数据即可,所以缓存数据的持久化并不重要,只要保证在数据库层面能够将数据持久保存就行,保证即使在缓存挂了之后,大不了每次请求都走数据库,虽然会慢,但不影响正常执行过程。所以数据必须设置过期时间,具体的设置规则要参加热点数据的属性来判断,诸如用户名,应用名,接口名之类的,改动概率很小的数据可以将过期时间设置在一天之内,而像校验次数一些更新很频繁的数据,过期时间可以设置的短一些,100s左右。

时间为什么一定要是随机的,这里是为了防止出现缓存雪崩的情况,例如热点数据同时在上午访问量比较高的某一刻失效,导致大面积请求去查库,会造成整体请求的耗时增加甚至拖垮数据库。

  1. 变更发生时让缓存立即失效

当业务上出现用户充值或修改信息时,在这些地方要及时让缓存失效,这样用户修改完成后,下次访问数据的时候可以先去数据库查询最新的数据,再放入缓存里,防止数据不一致的发生,但这里还有一个问题

这两个操作并不是原子的,很可能在1.更新数据库之后,还有其他请求在查询缓存,所以我采用的策略是先让缓存失效,在更新数据库。

以上场景都比较简单,如果是更加复杂的场景,可能还要考虑需要保证缓存和数据库的实时一致性,还是最终一致性。

发表评论

电子邮件地址不会被公开。 必填项已用*标注