我的编程空间,编程开发者的网络收藏夹
学习永远不晚

应用中引入缓存层后,缓存和持久化层数据一致性的思考

短信预约 信息系统项目管理师 报名、考试、查分时间动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

应用中引入缓存层后,缓存和持久化层数据一致性的思考

  一个应用中决定加缓存(Redis,memcached)之前,要考虑的第一个问题就是,引进了缓存之后,会带来哪些收益(利),付出哪些代价,引起哪些额外的问题(弊)? 任何新的中间件引进,收益和成本都是伴随的,只有当利大于弊的情况下,能够容忍其弊端(彻底解决?没有额外代价又没有负面影响,是不可能的,那就是不用就行了),才值得引进。   以Redis作为缓存为例,引进之后,其利和弊也是伴随的。 带来的收益:加速读写,提高并发性,降低后端持久化层数据库的负载 付出的代价:增加代码复杂,缓存本身的运维,潜在的数据不一致造成的影响。   数据不一致的存在 引进Redis(或者其他缓存)之后,应用程序到持久化层多了一个中间层,部分数据存储由原来的单一持久化层,变为缓存层和持久化层两份。 这两部分数据在相互同步的过程中,在某些时间点上的维度来看,可能会潜在不一致的情况。 其中,潜在的数据不一致,是任何一个引进缓存层之后最面临的最大的一个问题(缓存层和持久化层,最终的数据是要保持一致的,这一点是底线)。 首先需要衡量的就是,这种潜在的不一致,会引发什么样的问题,带来的问题是否可以接受范围之内,或者是否会对应用程序逻辑引起致命的问题。 缓存和持久化层存储可能会不一致,往往是缓存和持久化层未同步刷新引起的,
具体举例说明: 第一种情况,比如点赞次数,浏览次数等等(读多写少的场景,写MySQL,读Redis,写入了数据库但是尚未同步到缓存层这个间隙)。 不会对业务产生严重的逻辑错误,这种暂时性的数据不一致是可以忍受的,另外就是,通过刷新等手段,两者数据最终会达成一致。 第二种情况,比如银行卡取款取超,导致余额为负数,缓存和持久化层存储的不一致造成严重的逻辑错误,这种是无法忍受的。
就需要考虑这种缓存层本身的设计是否合理?   轻量级做法,代码逻辑实现 如果对于缓存的合理性没有问题,且业务逻辑上要求缓存和持久化层强一致,那么久要实现数据库的一致性操作。 对于缓存和持久化层数据的一致性实现,个人的话,思路有以下两种, 轻量级的做法如下: 对于引起数据变化的逻辑,一般都是“写操作”,比如对数据的update或者delete或者insert操作, 1,首先去delete缓存中对应的数据(而不是去对应的update、delete、insert,为什么?因为只要delete成功,缓存被清理之后,就消除了不一致的可能性,而非delete就做不到) 2,如果1执行成功,再去操作持久化层的数据库, 3,最后将写入成功之后的持久化层数据回写缓存层(这一步可选,或者其它手段同步)

重量级分布式锁实现,双写实现强一致
双写的安全性一般要通过分布式锁来实现,分布式锁可以通过zookeeper或者redis实现。
一旦考虑使用分布式锁,又要考虑分布式锁的载体的安全性,也即不管是用zookeeper或者redis,要考虑zookeeper或者redis的安全性(集群)。
这样下去,问题会变得非常复杂,纯粹变为解决问题-->引入新的问题-->解决问题的死循环。
如果要保持一致,当然双写也是一种选择,不过通过双写来确保数据的绝对一致,不但会对整体效率产生负面的影响,实现也是比较困难的,暂时不讨论这种方案。

如果是分布式锁,任何写入性操作,比如update,delete等,如下: 1,直接锁定相关key值 2,依次操作缓存层和持久化层,同时做好每一层的回滚操作,一旦任何一步失败,都要回滚 3,最终不管成功或者失败,都释放Key 分布式锁这种方式的话,实现起来,原代码中业务侵入性较多,比较复杂   重量级队列化请求 如果是使用队列,将可能导致不一致性的访问,队列化执行,其实这种方式,也是比分布式锁更加重量级的,基本上会颠覆原始的逻辑实现,一般很少采用。  

但是不管怎么样,缓存层和持久化层,最终的数据是要保持一致的,这一点是底线。
整体来看,引不引入缓存层,是从整体性能、业务逻辑、实现代价、数据一致性的容忍程度等多个方面决定的。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

应用中引入缓存层后,缓存和持久化层数据一致性的思考

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

应用中引入缓存层后,缓存和持久化层数据一致性的思考

一个应用中决定加缓存(Redis,memcached)之前,要考虑的第一个问题就是,引进了缓存之后,会带来哪些收益(利),付出哪些代价,引起哪些额外的问题(弊)?任何新的中间件引进,收益和成本都是伴随的,只有当利大于弊的情况下,能够容忍其弊端(彻底解决?没有额
2022-01-16

编程热搜

目录