编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

两级缓存J2cache的小问题(二级缓存2mb)

wxchong 2024-10-26 16:01:01 开源技术 87 ℃ 0 评论

背景

由于系统性能需求 现在将某些数据做了缓存 目前的策略是最长10分钟过期

java

这部分数据有特点如下:

  1. 数据不要求实时更新【查询次数多 更新次数少】

  2. 数据对于日期敏感

  3. 无特殊条件 各个用户数据相同

问题

实施反馈了一些数据如下

java

但是随后告知了开发

java

那么如何着手这个问题呢?

分析

  1. 首先在代码未变动之前 客户未反馈过此问题 初步排除是客户端缓存【不然应该以前也反馈该问题了】

  2. 那么大概率由于服务端加了缓存导致的 如果说是缓存出现了问题 那么客户清理了浏览器缓存怎么也不会发生数据正常【除非恰巧那个时间过期了】

  3. 那么集合我们使用两级缓存来分析吧 关于两级缓存的说明

    java

既然使用了多级缓存那么必然是分布式环境才有价值

考虑了一下上述流程存在一个问题

  1. 由于ehcache这一步写数据到redis中是使用list的那么势必无法对redis每个key设置各自的ttl 因此对于

  2. 对于ehcache来说我们知道ehcache的过期是懒过期 何为懒过期?就是过期的策略在执行get的时候才会检查 参考关于两级缓存的说明 这样有可能发生一个问题

java

很明显了确实ttl是-1

java

  1. 当多台机器的时候 一旦某一台机器正在发布等场景 为了简单描述我们分别设置为机器A 机器B

    机器A上的为ehcacheA 机器B上的为ehcacheB 【两者完全等价】

  2. 如果用户访问的数据此后再不会访问的话

    当机器A需要发布的时候 此时机器A上的ecacheA将会清空

    那么就会出现在ehcacheB上的数据存在 而此时ehcacheA上并没有该key【当然redis中也存在】

    此时机器A发布完成 来进行机器B的发布 那么此时机器B上ehcacheB的对应的缓存key也会消失

    那么现在唯一留着数据的地方就是redis

    第二天用户访问该数据就会发现本地ehcache没有数据 那么访问机器A会生成本地ehcacheA数据 访问机器B会生成本地ehcacheB数据【出现下次第一次访问的时候直到ehcache过期时间达到才会清除数据】

  3. 当机器A需要发布的时候 用户通过机器B来访问服务 此时机器A上的ecacheA将会清空

    此时机器A发布完成 来进行机器B的发布 那么此时机器B上ehcacheB的对应的缓存key也会消失 此刻用户通过机器A获取服务【ehcacheA上写入了新的数据】

    如果用户访问的数据此后再不会访问的话 那么就会出现在ehcacheA上的数据一直存在【ehcache懒过期】 而此时ehcacheB上并没有该key【当然redis中也存在】

    用户下一次【比如现在的场景 下一天】访问时假设第一次访问的是机器B 发现ehcacheB中没有数据 随即去了redis中获取了脏数据 那么此时ehcacheB和ehcachA中数据已经不一样了

    那么用户如果一直访问机器B的话直到ehcache过期时间达到才会清除数据 但是由于nginx策略通常会随机访问到机器A的服务 此时由于懒加载策略发现时间已经过期 因此去除了缓存 发送了expire广播

    此时机器A 机器B 和redis中数据都被清除 但是此时访问到了真正的服务【通常是db】将新的结果同时存入了redis和ehcacheA中 用户获得了正确的结果

推广开应该很多场景下会有此问题 需要开发人员注意一下~

解决方案

由于用户关心的数据对日期比较敏感

因此考虑增加日终任务在12:00 自动清除该缓存~

在这里给大家按点福利:具有1-5工作经验的,面对目前流行的技术不知从何下手,需要突破技术瓶颈的可以加群。在公司待久了,过得很安逸,但跳槽时面试碰壁。需要在短时间内进修、跳槽拿高薪的可以加。如果没有工作经验,但基础非常扎实,对java工作机制,常用设计思想,常用java开发框架掌握熟练的可以加群。java中高级群:463884523一起交流一起进步。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表