聊聊如何利用 redis 实现多级缓存同步
前阵子参加业务部门的技术方案评审,故事的背景是这样:业务部门上线一个专为公司高管使用的系统。这个系统技术架构形如下图:
按理来说这个系统因为受众很小,可以说基本上没并发,业务也没很复杂,但就是这么一个系统,连续 2 次出现数据库宕机,而导致系统无法正常运行。因为这几次事故,业务部门负责人组织这次技术方案评审,主题如何避免再次出现类似这种故障?
当时有个比较资深的技术,他提出当数据库出现宕机时,可以切换到 redis,redis 里面缓存热点数据,另外一个技术说他赞同这个方案,但他提出不需要用到 redis,直接用本地缓存即可。因为 tomcat 是集群部署,就等于本地缓存也具备了集群能力。而如果切换成 redis,redis 也可能会挂现象。
然后那个说用 redis 的技术又说,用本地缓存,如果数据变更,其他集群的本地缓存如何感知数据已经发生变化,他觉得还是用 redis 靠谱,首先 redis 容量肯定是比本地缓存高,而且 redis 也可以部署集群,可用性可以得到保障,利用 redis 集中存储,当数据发生变更,其他集群也可以感知到。
在他们争论不休的情况下,有人提出不然就同时使用,当数据库挂了,切换到 redis,redis 挂了,使用本地缓存。这个方案得到不少人的同意,包括这两个争论不休的技术。但使用这种方案,就得考虑多级缓存数据如何同步。
铺垫了那么多,才刚要说今天的主题,多级缓存数据如何进行同步
多级缓存数据同步
1、方案一:使用 MQ 或者 canal 进行同步
方案如下图:
如果是使用 MQ 来同步,实现方案大致如下,数据发生变更,业务系统发送变更数据到 MQ,其他系统从 MQ 消费。
如果是使用 canal,实现方案大致如下,数据发生变更,canal 会接到到变更的 binlog,业务系统编写 canal tcp 客户端,和 canal 进行交互获取变更数据
2、方案二:利用 redis6 提供的客户端缓存机制
方案如下图:
redis6 客户端缓存实现机制原理,官方有详细文档介绍,感兴趣大家可以查看如下链接 redis.io/docs/manual…
这边就讲下如何使用
如何使用 redis6 客户端缓存
前置条件:redis 服务端版本必须是>=6。lettuce 版本>=6 目前 java 的 redis 客户端找了一圈,貌似只有 lettuce 6 支持,其他客户端估计后期会支持
1、项目中 pom 引入 lettuce GAV
2、利用 lettuce6 提供的 ClientSideCaching 进行实现
3、测试
redis 里面的 zhangsan 数据未发生变更时,
控制台输出的数据为。
我们将 redis zhangsan 的密码改成 9999,
看本地缓存能否立马捕捉到
控制台发现密码已经改成 9999
总结
由示例我们可以看出 redis6 提供了一个很好的多级缓存同步的实现方案。
我们再聊下那个技术评审的后续,后面业务部门并没有采用当 mysql 宕机,使用 redis 作为兜底,也没采用本地缓存,更没采用两者结合的方案。
不知道大家开会的时候,有没有这样的体会,有时候我们在聊一个东西,后面聊着聊着就发散出去,把方向搞丢了。业务部门他们需要数据库宕机的解决方案吗,看着像是,其实他们更核心的需要,是业务系统不宕机。
奥卡姆剃刀定律:如无必要,勿增实体。其实不管加 redis 或者本地缓存,额外都增加系统维护成本。因为系统本身不复杂,加了缓存,就要额外考虑缓存数据一致性等
后面业务部门的处理方式,是将自己搭建的 mysql,切换成云厂商的 mysql。这样的好处是,云厂商的 mysql 会更稳定,其次当出现问题,可以找云厂商进行解决,毕竟云厂商的运维能力是比较强的,花钱买心安
这次事故会让业务部门那么重视,主要是使用方是高管,如果是一般使用者,挂就挂吧,大不了重启,使用对象不一样,应急处理方式就不一样
作者:linyb 极客之路
链接:https://juejin.cn/post/7179037112195350588
来源:稀土掘金
评论