#技术分享# 关于JAVA体系下Cache的一些心得体会

原创
2019/11/29 20:53
阅读数 328

      下午收好自己在公司的一切家当,心怀满腔的落寞,踏上了回家的归途,沿路景色依旧,我却无心欣赏,今天下午,本人有幸成为“中间危机”的践行者。 长期高速的运转的大脑忽然闲置下来,有点不知所措,一定要做点什么让大脑继续高速运转,否则心里空唠唠的,特别是此景下的我。言归正传~~~今天就谈谈Java 体系中的Cahce的一些基础设计,结合DDD的一些思想,我们一起搭建一套自己的Cache-Demo,本教超老少咸宜,男女通吃。尽情享受Cache的饕餮大餐。

     首先我要给Java体系下的Cache下个定义(仅代表本人观点),所谓“Cache”指的就是 Java 语言在运行时能够提供【快速】【还原业务实体状态】(场景)的【安全】【可选】的存储(容器)。这话有点意思“初念甚浅,转念甚深”。 在该定义中 隐藏了一些关于Cache的细节定义,我们一定要用善于观察业务的眼睛去挖掘定义背后的含义,这也是DDD思想教导我们的方法论,要认识一个事物,首先要给一个事物明确的定义 (类似于我们些需求文档的中特定的章节:名词解释)(而哲学告诉我们,不要给事物下定义,因为你下定义的同时也就失去他本身),嘻嘻,太形而上的还是算了,我们的口号是:“务实为第一要务”。要学会“咬文嚼字” 解刨Cache的定义,看看定义的背后到底隐藏了什么~~~~阿弥陀佛,出家人不打妄语。

       第一关键词:【快速】,它是某个参考系下的参考量,速度的优化,也就意味着系统的优化,一般而言,本地内存(LocalCache) > 远程内存(远程Cache) >  DB  , 具体用那一类的Cache,没有定论,一切按需使用。

       第二个关键词:【还原业务实体状态】,我们从Cache中取出来的缓冲对象,能够精准的还原当时的业务对象状态,通俗而言,存进去是什么取出来就是什么,作为种瓜是瓜,种豆是豆。该业务状态应该具有  “方法的无副作用” 这是DDD里提到的一个概念,调用该对象的任何方法,都在产生一个他的副本,而不是修改缓冲值本身,它应该是一个类型安全的对象。

     第三个关键词:【安全】:主力所谓的安全是指,在多线程并发下,如何保证大家读取Cache中的值的一致性问题,这个话题比较庞大,我们先挂起,以后再议。

    第四个关键字:【可选】:说明Cache 相对于整个系统而言,他是作为系统的优化策略而存在的,系统本身不应当由于是否使用Cache而需要对其进行编码的修正,在使用Cache之前,首先要判断它是否存在吧,有则更好更快,无Cache时,除了慢点以外,无他~~~~,当然实际使用考虑的因素要多于目前,有说的不准确的地方,烦请多多包涵~~~~

    基于上述四点,我们就可以定义一个Cache了。。。。小伙伴们~~你们的系统中是否有在使用Cache呢?明白了定义,接下来的章节就比较好理解了。

    有了Cache的静态定义之后,我们继续讨论它的动态部分,既然是一个存储(容器),那么它一定有一套自圆其说的内部系统,支撑着Cache良性运行,否则Cahce会如同人类的“癌细胞” 一样,缓存的对象变得不受控制,最后OOM了,如何控制呢?Cache存储对每一个存入的对象额外贴了一些基本的标签,用这些标签来判断当前值是否值得保留,还是内部自己把它处理掉。一般而言,Cache容器会对存储在它内部的对象贴如下的标签:【创建时间】【命中次数】【最后一次访问时间】【最后一次写入时间】等,这些是最基本的标签,基本示意图如下:

 

有这这些基本的标签时刻记录Cache实体运行时的状态,那么Cache容器就会轻易的了解每个Cache实体在容器中的是情况了,更进步就可以更具这些参数进行有策略的调整(自动刷新Cache 后者自动 失效Cache 等) ,一般策略有如下几种(当容器的容量达到上限的时候)会进行如下的一些策略更新:1、创建时间最早的优先被清理 2、命中次数最少的优先被清理、3、最后访问时间间隔最久的被优先清理 等,可以互相叠加出更多的一些策略,用于在实际运行时,灵活调配Cache,以便于达到最佳的性能诉求。

     我使用的Cache主要是基于JVM自身内存的 Guava-Cache, 以及更为独立的Redis Cache 着两种,两种Cache各有优缺点,我们在使用的时候,肯定是扬长避短,混合使用(或者单一使用),混合使用的状态可以吧他们作为一级Cache与二级Cache来对待,当然要同步一级与二级Cache的状态需要更加复杂的代码封装,但是基本原理都是一致的。

     在使用Cache之前,我喜欢用硬编码的方式访问,灵活性掌握在自己手里,其实我更加喜欢采用GuavaCache技术,简单粗暴直接,但是在单个Cache的粒度控制上有所牺牲,在使用的时候可以不用考虑序列化与反序列化的过程,整体效率还是蛮不错的。 如果大家的系统都局限于单机(单模块化),模块之间少有数据互用,则可采用LocalCahe为主,如果的分布式的场景,还是推荐使用 Redis 技术,使用集中Cache更好。

    Cache的使用比较灵活,一般我采用K_V模式,但是K_V的度着由自己来调节,例如在 最新的项目中,我把每个公司的门店 合集作为数组,用一个V来表示,每次获取通过遍历数组获取对应的实际门店详细信息。   不一定是 每个KEY 值应对与一个Value,这个需要自己实际编码的时候要注意。少用注解,注解模式的灵活度不够。 后面写的有些发困,中午没有午休~~ 后期在完善一下,Cache技术博大精深,我仅仅是抛砖引玉

 

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
0 评论
0 收藏
0
分享
返回顶部
顶部