开发中的缓存设计

来源:互联网 发布:uu大魔王淘宝店 编辑:程序博客网 时间:2024/06/07 02:33

缓存在互联网的项目中扮演这越来越重要的作用了,用于高并发,大流量的场景下效果尤为明显。

所以就需要注意缓存和数据库之间的数据一致性问题。缓存的淘汰和更新等一系列问题。

  • 场景需求
缓存是一种提高系统读性能的常见手段,所以对于一些读多写少的场景下会常用缓存进行优化。例如在账户的余额需求上,用户有99%的请求是查询,1%的请求是更改。

由于大部分的请求是查询,所以我们建立一个uid到money直接的关系,能够极大的降低数据库的压力。
读的操作流程:
  1.  用户请求过来,获取到用户uid,去缓存中用用户uid查用户的money,是否命中?
  2. 命中了用户的本次请求,返回用户的余额。
  3. 没有命中本次请求,从数据库查用户的余额,放入缓存中,在返回给用户余额。

在这个例子中,缓存的命中率=缓存的命中个数/总的请求数。

那么问题来了,当数据发生变化的时候,该怎么去更新缓存的数据?

  1. 是更新缓存的数据还是淘汰缓存的数据?
  2. 是先操作缓存的数据呢还是先操作数据库的数据呢?
  3. 缓存与数据库的操作在架构上是否还有优化的空间?
一、更新缓存 PK 淘汰缓存

更新缓存:数据不单会写入数据库还会写入缓存,优点是不会增加一次miss,命中率高。
淘汰缓存:数据只写入数据库,淘汰缓存的数据。

到底是淘汰还是更新?主要取决于更新和淘汰的复杂度。
例如上面的余额案例。淘汰缓存的操作:dele(uid),更新缓存的操作:set(uid,newMoney);更新缓存的代价并没有多大,所以我们可以采用更新缓存的策略来提高缓存的命中率。
如果此刻的余额要经过很复杂的业务系统取计算出来,例如要扣掉优惠券的信息,要计算本次交易的手续费,本次交易的税费,本次交易的发票费等。我们可以直接淘汰缓存的uid.

然而,淘汰缓存只会增加一次miss率。而且在业务开发中不需要去考虑整个业务系统的复杂性,所以,可以用淘汰策略用作统用的处理方式。如果淘汰失败,就停止本次操作!

二、先操作数据库还是先操作缓存?
当更新操作发生了,我们用淘汰策略去更新缓存的数据,我们此刻又面临一个问题,我们是先操作缓存还是先更新数据库的内容?
1.先更新数据库,然后淘汰缓存
2.先淘汰缓存,然后更新数据库
这里我们的原则是如果出现不一致,谁先做对业务的影响最小,就采用谁。

结论:数据库和缓存的操作时序先淘汰缓存,后更新数据库。
新问题又出来了。。。淘汰缓存后,写db前,在主从的数据库结构中可能有别的请求进来把缓存又个更新了,这怎么办呢?
双刷缓存策略





0 0
原创粉丝点击