缓存与数据库数据一致性问题,始终是面试官很喜爱问的问题,你晓得有多少计划,每种的优缺点是啥?最终会采纳哪种计划较好,你感觉呢?
我的公众号:MarkerHub,Java 网站:https://markerhub.com
更多精选文章请点击:Java 笔记大全.md
作者:叶不闻
https://juejin.im/post/5d5c99…
背景
缓存是软件开发中一个十分有用的概念,数据库缓存更是在我的项目中必然会遇到的场景。而缓存一致性的保障,更是在面试中被重复问到,这里进行一下总结,针对不同的要求,抉择恰到好处的一致性计划。
缓存是什么
存储的速度是有区别的。缓存就是把低速存储的后果,长期保留在高速存储的技术。
如图所示,金字塔更下面的存储,能够作为上面存储的缓存。
咱们本次的探讨,次要针对数据库缓存场景,将以 redis 作为 mysql 的缓存为案例来进行。
为什么须要缓存
存储如 mysql 通常反对残缺的 ACID 个性,因为可靠性,持久性等因素,性能广泛不高,高并发的查问会给 mysql 带来压力,造成数据库系统的不稳固。同时也容易产生提早。依据局部性原理,80% 申请会落到 20% 的热点数据上,在读多写少场景,减少一层缓存十分有助晋升零碎吞吐量和健壮性。
存在问题
存储的数据随着工夫可能会发生变化,而缓存中的数据就会不统一。具体能容忍的不统一工夫,须要具体业务具体分析,然而通常的业务,都须要做到最终统一。
redis 作为 mysql 缓存
通常的开发模式中,都会应用 mysql 作为存储,而 redis 作为缓存,减速和爱护 mysql。然而,当 mysql 数据更新之后,redis 怎么放弃同步呢。
强一致性同步老本太高,如果谋求强统一,那么没必要用缓存了,间接用 mysql 即可。通常思考的,都是最终一致性。
解决方案
计划一
通过 key 的过期工夫,mysql 更新时,redis 不更新。这种形式实现简略,但不统一的工夫会很长。如果读申请十分频繁,且过期工夫比拟长,则会产生很多长期的脏数据。
长处:
- 开发成本低,易于实现;
- 治理成本低,出问题的概率会比拟小。
有余
- 齐全依赖过期工夫,工夫太短容易缓存频繁生效,太长容易有长时间更新提早(不统一)
计划二
在计划一的根底上扩大,通过 key 的过期工夫兜底,并且,在更新 mysql 时,同时更新 redis。
长处
- 绝对计划一,更新提早更小。
有余
- 如果更新 mysql 胜利,更新 redis 却失败,就进化到了计划一;
- 在高并发场景,业务 server 须要和 mysql,redis 同时进行连贯。这样是损耗双倍的连贯资源,容易造成连接数过多的问题。
计划三
针对计划二的同步写 redis 进行优化,减少音讯队列,将 redis 更新操作交给 kafka,由音讯队列保障可靠性,再搭建一个生产服务,来异步更新 redis。
长处
- 音讯队列能够用一个句柄,很多音讯队列客户端还反对本地缓存发送,无效解决了计划二连接数过多的问题;
- 应用音讯队列,实现了逻辑上的解耦;
- 音讯队列自身具备可靠性,通过手动提交等伎俩,能够至多一次生产到 redis。
有余
- 仍旧解决不了时序性问题,如果多台业务服务器别离解决针对同一行数据的两条申请,举个栗子,a = 1;a = 5;,如果 mysql 中是第一条先执行,而进入 kafka 的程序是第二条先执行,那么数据就会产生不统一。
- 引入了音讯队列,同时要减少服务生产音讯,老本较高。
计划四
通过订阅 binlog 来更新 redis,把咱们搭建的生产服务,作为 mysql 的一个 slave,订阅 binlog,解析出更新内容,再更新到 redis。
长处
- 在 mysql 压力不大状况下,提早较低;
- 和业务齐全解耦;
- 解决了时序性问题。
毛病
- 要独自搭建一个同步服务,并且引入 binlog 同步机制,老本较大。
总结
计划选型
- 首先确认产品上对提早性的要求,如果要求极高,且数据有可能变动,别用缓存。
- 通常来说,计划 1 就够了,笔者征询过 4,5 个团队,根本都是用计划 1,因为能用缓存计划,通常是读多写少场景,同时业务上对提早具备肯定的包容性。计划 1 没有开发成本,其实比拟实用。
- 如果想减少更新时的即时性,就抉择计划 2,不过没必要做重试保障之类的。
- 计划 3,计划 4 针对于对延时要求比拟高业务,一个是推模式,一个是拉模式,而计划 4 具备更强的可靠性,既然都违心花功夫做解决音讯的逻辑,不如一步到位,用计划 4。
论断
个别状况,计划 1 够用。若延时要求高,间接抉择计划 4。如果是面试场景,从简略讲到简单,面试官会一步一步诘问,咱们就一点点推导,宾主尽欢。
(完)
举荐浏览
Java 笔记大全.md
太赞了,这个 Java 网站,什么我的项目都有!https://markerhub.com
这个 B 站的 UP 主,讲的 java 真不错!