码恋

ALL YOUR SMILES, ALL MY LIFE.

莞尔君笑,倾我余生
  menu

微服务架构下缓存的统一管理

一、痛点

多模块服务协作开发背景下,随着缓存越来越多,缓存的一致性维护难度随之提升。

  • 多模块服务之间的缓存 key 维护容易造成遗漏,如 OP 与各服务之间的缓存交互。

  • 单独模块多人开发甚至独立开发时,随着业务缓存的数量增多,在缓存的处理上也会有遗漏。


    结论
    人工维护极易遗漏,沟通时也会出现理解偏差,造成缓存不一致,后期排查定位问题难度增加。其中的种种,带来很多的时间成本、沟通成本和开发成本。

二、思考

难点其实在于 数据查询方数据更新方 的沟通问题,思考:

  • 数据查询方
    查询数据时,我加了缓存之后需要告诉哪些服务我缓存了这些数据?什么时候需要刷新缓存?数据有变动,有什么机制通知到我更新缓存,或者帮我做刷新?
  • 数据更新方
    数据更新时,那些缓存与之相关需要更新?什么情况下需要更新?

结论
加缓存时通知加了 什么表 的缓存,什么时候 需要刷新缓存;
数据表更新时按照缓存的 刷新时机 刷新。

三、解决方案

首先讨论缓存的更新机制都有哪些:

  • 单条更新时(id,userId 等特定标识,适用单条缓存)
  • 单表有数据更新时(表全量数据缓存或难以通过特定标示定位到的)
  • 多表有数据更新时(缓存的数据与业务多表强相关,一张表有更新就要更新缓存)
    ...

解决思路:

1、加缓存,规则统一无需通知

按更新机制配置 Hash name , 命名方式为 表名 + 更新机制,下属 key 的命名可以按照模块前缀 + 自定义方式。

2、更新缓存,端 + Syncer 管理。

缓存的刷新由服务本身管理 + Syncer 统一管理的方式。服务可以自主更新缓存,并发送更新消息至 Syncer , 解析消息后刷新缓存。

消息格式:

表 + 更新机制 即上述的 Hash name,对应的更新机制消息:

  • 单条更新,带上 id;
  • 单表更新, 多表更新
    • 能准确定位 id ,带上各表 id
    • 其他

交互图:

image20200511114243776.png

3、通知方式

  • 各服务自己控制缓存更新时发送消息,注解 AOP
  • Mybatis 拦截器
  • binglog
    ...

四、应用到生产环境的解决方案

  • 使用发 MQ 的方式解决,每个表为特定的 topic ,对数据有修改则发消息,消息内容为 {"source":"app1","id":1...} ,其中 source 是标示发消息的应用,再带上关注的索引,一般 key 都是以重要的索引来作区分,比如 id ,userId...
  • 应用订阅关心的 topic ,自己消费做缓存同步处理。

标题:微服务架构下缓存的统一管理
作者:wangning1018
地址:https://aysaml.com/articles/2020/05/11/1589170001785.html