缓存更新策略

之前面试,面试官问到了我了缓存更新的问题:更新数据库和更新缓存的逻辑是什么样的?

当时我说的是:先失效缓存,然后再去更新数据库。当时我也说不出个子丑寅卯来,只怪自己用缓存只停留在表面阶段,没有太深挖原理,没有去想缓存的更新策略(平常没接触到这方面),也没有取想缓存更新失败的各种情形。同一个坑不能掉进去两次,这次借这个机会好好梳理一下缓存这块的知识。


缓存的基本概念和用法我就跳过,直接来看缓存的更新策略。

缓存更新的策略有四种:

  • Cache aside
  • Read through
  • Write through
  • Write behind


Cache Aside

读数据时:应用先从 cache 中获取数据,没有拿到,则从数据库中获取数据,成功后在放回到缓存中。

更新时:先把数据存到数据库中,成功后再让缓存失效。

这个应该是大家经常用到的模式吧,尤其是在读负载很重的时候。而且在这种模式下,缓存层对于系统来说并不是必须的,缓存挂了,系统还可以直接和持久层交互。

那么为啥叫 Cache Aside 呢?看下面这个图就知道了:

image

也就是 Cache 放在一边,应用可以同时跟缓存和数据库交互。

这里来画一下流程图,分析一下各种情况下,会出现什么问题。

image

假设这两个逻辑分别都能原子的执行,那么这种方式是没有啥问题的。问题在于这两种逻辑往往都是并发执行的,这样以来,可能会存在如下的执行逻辑。

image

在这种情形之下,红色的箭头代表的是执行时间的先后顺序,并不表示它们在同一线程中执行的,这样看来,缓存中其实就存在脏数据了。

有人会说,为啥不在更新数据库的时候,把缓存中的数据也一并修改了呢?

在并发情况下其实也会造成脏数据的产生,因为这是两个写操作,除非你能保证这两个写操作能原子地执行,否则还是有问题:

image

这不是仍然有脏数据么?

有一个问题就是读的时候写缓存好,还是更新的时候写缓存好?

缓存中出现了脏数据怎么办?

如何避免缓存中出现脏数据?


Read/Write Through Pattern

这种模式其实是将缓存服务作为主要的存储,应用的所有读写请求都是直接与缓存服务打交道,而不管最后端的数据库了,数据库的服务器由缓存服务来更新和维护。不过缓存中数据变更的时候是同步去更新数据库的,在应用眼中只有缓存服务。

image

这种策略的好处是出现脏数据的概率比较低,但是会对缓存强依赖,对缓存服务的稳定性要求较高。另外,增加缓存节点还会有初始状态空数据问题。

Read Through 的 through 则是通过的意思:

image

Write Throught 也是如此:

image

Write Behind

这个模式是 Read/Write Through 策略的变种,区别就是 Read/Write Through 模式的缓存写数据是同步的,而 Write Behind 模式的缓存操作数据库是异步的。

这种模式的特点是速度快,效率非常高,但是数据的一致性比较差,可能会有数据丢失的情况,实现逻辑也较为复杂。

image

Write Behind 不是立即写库,而是异步的有延迟。这种设计对于写负担很重是很有帮助的。

总结

这里介绍了不同的缓存策略,以及它们各自的优劣势。在实际项目中,需要仔细评估一下你的目标,理解数据的访问模式,选择最合适的策略或者组合。

转载于:https://www.cnblogs.com/tuhooo/p/10550603.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值