1、业务网关刚启动时 , 本地缓存没有数据 , 读取 Redis 缓存 , 如果 Redis 缓存也没数据 , 则通过 RPC 调用导购服务读取数据 , 然后再将数据写入本地缓存和 Redis 中;若 Redis 缓存不为空 , 则将缓存数据写入本地缓存中 。
2、由于步骤1已经对本地缓存预热 , 后续请求直接读取本地缓存 , 返回给用户端 。
3、Guava 配置了 refresh 机制 , 每隔一段时间会调用自定义 LoadingCache 线程池(5个最大线程 , 5个核心线程)去导购服务同步数据到本地缓存和 Redis 中 。
优化后 , 性能表现很好 , 平均耗时在 5ms 左右 。最开始我以为出现问题的几率很小 , 可是有一天晚上 , 突然发现 app 端首页显示的数据时而相同 , 时而不同 。
也就是说:虽然 LoadingCache 线程一直在调用接口更新缓存信息 , 但是各个 服务器本地缓存中的数据并非完成一致 。说明了两个很重要的点:
【聊聊本地缓存和分布式缓存】1、惰性加载仍然可能造成多台机器的数据不一致
2、LoadingCache 线程池数量配置的不太合理, 导致了线程堆积
最终 , 我们的解决方案是:
1、惰性加载结合消息机制来更新缓存数据 , 也就是:当导购服务的配置发生变化时 , 通知业务网关重新拉取数据 , 更新缓存 。
2、适当调大 LoadigCache 的线程池参数 , 并在线程池埋点 , 监控线程池的使用情况 , 当线程繁忙时能发出告警 , 然后动态修改线程池参数 。
五、总结Fred Brooks 在 1987 年所发表的一篇关于软件工程的经典论文《没有银弹:软件工程的本质性与附属性工作》 。
论文强调真正的银弹并不存在 , 而所谓的银弹则是指没有任何一项技术或方法可以能让软件工程的生产力在十年内提高十倍 。
通俗来讲:在技术领域中没有一种通用的解决方案可以解决所有问题 。技术本质上是为了解决问题而存在的 , 每个问题都有其独特的环境和限制条件 , 没有一种通用的技术或工具可以完美地解决所有问题 。
缓存是把双刃剑 , 一方面我们享受缓存带来的系统性能提升 , 另一方面引入缓存会提高系统复杂度 , 因为你要考虑缓存的失效、更新、一致性等问题 。
在面临缓存选型时 , 一定要结合业务场景 , 研发效率 , 运维成本 , 人力模型 , 技术储备等因素 , 做出合理的选择 。
推荐阅读
- 银河护卫队3|银河系天团重装出发,聊聊《银河护卫队3》
- 粮票|聊聊玻璃种翡翠的那些事
- 外来媳妇本地郎|《外来媳妇本地郎》突然“领盒饭”的8个角色,哪个是你的意难平
- 康天庥|《外来媳妇本地郎》最好的大结局:幸子送枝子出嫁,康天庥喜当爹
- 周子瑜|《外来媳妇本地郎》康家四子戏外都生女,有的已嫁人,有的出道了
- 聊聊|为何不吃米和面,体重下降得会比较快?是时候聊聊减肥的那些事了
- 外来媳妇本地郎|《外来媳妇本地郎》11对真夫妻,香兰老公不简单,还有一对主持人
- 刘涛|幸子刘涛首谈《外来媳妇本地郎》大结局:我还没回来,可不能结局
- 聊聊|不只是神话故事,聊聊《西游记》中的职场现象
- Stable Diffusion背后团队发布开源大语言模型 可用于本地部署