浅谈本地缓存的应用

前言

        缓存的本质是内存的读写速度优于磁盘,加速数据处理、加快请求响应,在并发场景下,减轻DB读的压力。本地缓存的使用,是缓存架构的基石。无论系统简单还是复杂,都离不开本地缓存的使用。

本地缓存的选择

 本地缓存可选择:JVM堆 / Ehcache / Guava Cache

(1)Ehcache:支持堆外缓存,持久化。以前集中式架构,尤其是企业IT系统,用物理机或虚拟机部署,需要缓存的数据量很大,为了合理利用机器资源,基本选择Ehcache。
(2)Guava Cache:支持LRU的ConcurrentHashMap。有同学说缓存系统的一些配置项(如:接口名称),缓存这些理论上不会变的又不太放心的东西。
(3)JVM堆:现在的分布式系统都是容器化部署,基本都是4C8G或者8C8G的规格。JVM堆内存一般都会分到4G-6G,这样已经可以最大幅度的利用了容器资源了。

   容器化时代,JVM堆缓存可以最大化利用容器资源,使用本地缓存的场景都可以用JVM堆缓存。

本地缓存的清理

  本地缓存清理策略:定时更新 / 实时更新

(1)定时任务清理。数据发生变化后,更新数据状态,然后用定时任务周期性扫描数据状态,若发现数据发生变化,更新本地缓存。这种方式更新缓存会有一定的延迟,如果把调度任务设定的非常短,就会不断占用一个线程去处理缓存,数据基本不变的情况下,这样没必要的,CacheCheck以及CacheReLoad的设计很重要。
(2)缓存实时更新。数据变化后,通知缓存立刻更新。在单实例情况下,数据更新完直接调用清理本地缓存的方法即可,但多实例情况下,数据在一个实例上的更新,要通知其它实例同步更新本地缓存,这就需要用到MQ广播。这种本地缓存清理机制,实时性高,但只适合定义类这种每次修改的数据量不会很大的场景,如果一次性修改了大量的数据,会产生大量需要广播的消息,会使MQ集群出现容量瓶颈甚至宕机,这个时候就要参考kafka设计思想,做消息合并转发处理。   之前某项目上,我们MQ集群总被压挂,UAT过程中多次中断,多次扩容收效不大,终于忍不住查了一下消息源是我们自己的压测……    

本地缓存的使用场景

  缓存使用场景:永久性缓存 / 实时性缓存

(1)永久性缓存。配置类、定义类、基础数据、商品名称等,这些业务场景的特点就是一经配置完成,基本不会变,纵使有些许调整,在较小的一段时间内也能容忍其变化,这类缓存在服务启动时就可以统一的加载到容器的JVM堆中,用定时任务5-10min扫描更新一次缓存即可。
(2)实时性缓存。订单、交易、支付、发薪等,这类业务场景实时性强,还需要100%的准确。使用缓存是为了保证每个请求对同样的数据,只从数据库获取1次即可,避免对数据库的多次调用。保证每个请求中数据一致,绑定线程的东西ThreadLocal,执行结束一定要remove()。每次八股文上天天rr加next-key lock防幻读,就很神奇,为什么一次请求中同样的语句要多次执行?

附:本地缓存还有一个作用,作为redis被击穿后最后的兜底。

 

你可能感兴趣的:(缓存,java,后端,jvm)