`
iamzhongyong
  • 浏览: 795034 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

关于java中的本地缓存-总结概述

    博客分类:
  • java
阅读更多

java中的本地缓存,工作后陆续用到,一直想写,一直无从下手,最近又涉及到这方面的问题了,梳理了一下。自己构造单例、guava、ehcache基本上涵盖了目前的大多数行为了。

 

为什么要有本地缓存?

在系统中,有些数据,数据量小,但是访问十分频繁(例如国家标准行政区域数据),针对这种场景,需要将数据搞到应用的本地缓存中,以提升系统的访问效率,减少无谓的数据库访问(数据库访问占用数据库连接,同时网络消耗比较大),但是有一点需要注意,就是缓存的占用空间以及缓存的失效策略。

 

为什么是本地缓存,而不是分布式的集群缓存?

         目前的数据,大多是业务无关的小数据缓存,没有必要搞分布式的集群缓存,目前涉及到订单和商品的数据,会直接走DB进行请求,再加上分布式缓存的构建,集群维护成本比较高,不太适合紧急的业务项目。

         这里介绍一下缓存使用的三个阶段(摘自info架构师文档)

          

 

本地缓存在那个区域?

         目前考虑的是占用了JVM的heap区域,再细化一点的就是heap中的old区,目前的数据量来看,都是一些小数据,加起来没有几百兆,放在heap区域最快最方便。后期如果需要放置在本地缓存的数据大的时候,可以考虑在off-heap区域,但是off-heap区域的话,需要考虑对象的序列化(因为off-heap区域存储的是二进制的数据),另外一个的话就是off-heap的GC问题。其实,如果真的数据量比较大,那其实就可以考虑搞一个集中式的缓存系统,可以是单机,也可以是集群,来承担缓存的作用。

 

搞一个单例模式,里面有个Map的变量来放置数据

关于单例模式,一个既简单又复杂的模式(http://iamzhongyong.iteye.com/blog/1539642

非常典型的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class SingletonMap {
    //一个本地的缓存Map
    private Map<String,Object> localCacheStore = new HashMap<String,Object>(); 
 
    //一个私有的对象,非懒汉模式
    private static SingletonMap singletonMap = new SingletonMap(); 
 
    //私有构造方法,外部不可以new一个对象
    private SingletonMap(){
    }  
 
    //静态方法,外部获得实例对象
    public static SingletonMap getInstance(){
        return singletonMap;
    }
 
    //获得缓存中的数据
    public Object getValueByKey(String key){
        return localCacheStore.get(key);
    }
    //向缓存中添加数据
    public void putValue(String key , Object value){
        localCacheStore.put(key, value);
    }
}

 这种能不能用?可以用,但是非常局限

1
2
3
4
5
6
7
8
但是这种的就是本地缓存了吗?答案显然不是,为啥呢?
1、  没有缓存大小的设置,无法限定缓存体的大小以及存储数据的限制(max size limit);
2、  没有缓存的失效策略(eviction policies);
3、  没有弱键引用,在内存占用吃紧的情况下,JVM是无法回收的(weak rererences keys);
4、  没有监控统计(statistics);
5、  持久性存储(persistent store);
所以,这种就直接废掉了。。。

 

引入EhCache来构建缓存(详细介绍:  http://raychase.iteye.com/blog/1545906

EhCahce的核心类:

A、CacheManager:Cache的管理类;

B、Cache:具体的cache类信息,负责缓存的get和put等操作

C、CacheConfiguration :cache的配置信息,包含策略、最大值等信息

D、Element:cache中单条缓存数据的单位

典型的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public static void main(String[] args) {
        //EhCache的缓存,是通过CacheManager来进行管理的
        CacheManager cacheManager = CacheManager.getInstance();
         
        //缓存的配置,也可以通过xml文件进行
        CacheConfiguration conf = new CacheConfiguration();
        conf.name("cache_name_default");//设置名字
        conf.maxEntriesLocalHeap(1000);//最大的缓存数量
        conf.memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LRU);//设置失效策略
         
        //创建一个缓存对象,并把设置的信息传入进去
        Cache localCache = new Cache(conf);
         
        //将缓存对象添加到管理器中
        cacheManager.addCache(localCache);
                 
        localCache.put(new Element("iamzhongyong"new Date()));
         
        System.out.println(localCache.getSize());
        System.out.println(localCache.getStatistics().toString());
        System.out.println(localCache.getName());
        System.out.println(localCache.get("iamzhongyong").toString());
        System.out.println(localCache.get("iamzhongyong").getObjectValue());   
    }

当然,Cache的配置信息,可以通过配置文件制定了。。。

优点:功能强大,有失效策略、最大数量设置等,缓存的持久化只有企业版才有,组件的缓存同步,可以通过jgroup来实现

缺点:功能强大的同时,也使其更加复杂

 

引入guava的cacheBuilder来构建缓存

这个非常强大、简单,通过一个CacheBuilder类就可以满足需求。

缺点就是如果要组件同步的话,需要自己实现这个功能。

典型的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class GuavaCacheBuilderTest {
    public static void main(String[] args) throws Exception{
        GuavaCacheBuilderTest cache = new GuavaCacheBuilderTest();
        cache.getNameLoadingCache("bixiao");
    }
    public void getNameLoadingCache(String name) throws Exception{
        LoadingCache<String, String> cache = CacheBuilder.newBuilder()       
            .maximumSize(20)//设置大小,条目数        
            .expireAfterWrite(20, TimeUnit.SECONDS)//设置失效时间,创建时间      
            .expireAfterAccess(20, TimeUnit.HOURS) //设置时效时间,最后一次被访问       
            .removalListener(new RemovalListener<String, String>() { //移除缓存的监听器
                public void onRemoval(RemovalNotification<String, String> notification) {
                    System.out.println("有缓存数据被移除了");
                }})
            .build(new CacheLoader<String, String>(){ //通过回调加载缓存
                @Override
                public String load(String name) throws Exception {
                    return name + "-" "iamzhongyong";
                }
        });
        System.out.println(cache.get(name));
        //cache.invalidateAll();
    }
}

 

缓存预热怎么搞?

A、全量预热,固定的时间段移除所有,然后再全量预热

适用场景:

1、数据更新不频繁,例如每天晚上3点更新即可的需求;

 2、数据基本没有变化,例如全国区域性数据;

B、增量预热(缓存查询,没有,则查询数据库,有则放入缓存)

适用场景:

1、  数据更新要求缓存中同步更新的场景

 

​集群内部,缓存的一致性如何保证?

如果采用ehcache的话,可以使用框架本身的JGroup来实现组内机器之间的缓存同步。

如果是采用google的cacheBuilder的话,需要自己实现缓存的同步。

A、非实时生效数据:数据的更新不会时时发生,应用启动的时候更新即可,然后定时程序定时去清理缓存;

B、需要实时生效数据:启动时可预热也可不预热,但是缓存数据变更后,集群之间需要同步

 

至此,告一段落。。。。

分享到:
评论

相关推荐

    Click&Clean 清除浏览记录-9.7.8.1.zip

    概述:删除浏览历史记录,输入的网址,Flash cookies,所有网上活动痕迹以保护您的隐私。 描述: 清除隐私数据当您关闭浏览器: -清除浏览历史记录,清除下载历史记录 -清空缓存 -删除Cookie -清除已保存的密码,清除...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

    第2章 Java对象持久化技术概述  2.1 直接通过JDBC API来持久化实体域对象  2.2 ORM简介  2.2.1 对象-关系映射的概念  2.2.2 ORM中间件的基本使用方法  2.2.3 常用的ORM中间件  2.3 实体域对象的其他持久化模式...

    java前后端分离源码-yalla-challenge:yalla-挑战

    ),并将结果存储在本地缓存/数据库中。 后端将数据库中的结果返回给前端 前端将相应地显示结果 指示 快速阅读 grails 框架和 groovy 语言的基础知识 Fork 这个仓库 在您的前叉上创建新功能 完成后提出拉取请求 重要...

    java项目p2p源码-p2psockets:在P2P网络上创建Socket/ServerSocket抽象和类似DNS的命名空间

    java项目p2p源码#P2P 套接字 #注意:不再维护或支持 P2P 套接字。 它存在于此处用于存档目的。 ##概述 P2P Sockets 使得编写基于 JXTA 的对等应用程序变得容易。 P2P Sockets 允许程序员获得 JXTA 的大部分功能,...

    疯狂JAVA讲义

    第1章 Java概述 1 1.1 Java语言的发展简史 2 1.2 Java的竞争对手及各自优势 4 1.2.1 C#简介和优势 4 1.2.2 Ruby简介和优势 4 1.2.3 Python的简介和优势 5 1.3 Java程序运行机制 5 1.3.1 高级语言的运行机制 6...

    java面试宝典

    42、一个“.java”源文件中是否可以包含多个类(不是内部类)?有什么限制? 12 43、说出一些常用的类,包,接口,请各举5 个。 12 44、Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类?是否可以...

    Java数据编程指南

    数据库性能问题 本地编译机制 挑选适当的JDBC驱动程序 连接池 事务和批量查询 存储过程和JDBC准备语句 JDBC准备语句 在程序块上检索大数据集合 高速缓存频繁使用的数据 性能监控 小结...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part4

    第2章 Java对象持久化技术概述  2.1 直接通过JDBC API来持久化实体域对象  2.2 ORM简介  2.2.1 对象-关系映射的概念  2.2.2 ORM中间件的基本使用方法  2.2.3 常用的ORM中间件  2.3 实体域对象的其他持久化模式...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part3

    第2章 Java对象持久化技术概述  2.1 直接通过JDBC API来持久化实体域对象  2.2 ORM简介  2.2.1 对象-关系映射的概念  2.2.2 ORM中间件的基本使用方法  2.2.3 常用的ORM中间件  2.3 实体域对象的其他持久化模式...

    Java核心技术II(第8版)

    12.1 从Java程序中调用C函数 12.2 数值参数与返回值 12.2.1 用printf格式化数字 12.3 字符串参数 12.4 访问对象域 12.4.1 访问实例域 12.4.2 访问静态域 12.5 编码签名 12.6 调用Java方法 12.6.1 实例方法 12.6.2 ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part1.rar

    第2章 Java对象持久化技术概述  2.1 直接通过JDBC API来持久化实体域对象  2.2 ORM简介  2.2.1 对象-关系映射的概念  2.2.2 ORM中间件的基本使用方法  2.2.3 常用的ORM中间件  2.3 实体域对象的其他持久化模式...

    Oracle自学(学习)材料 (共18章 偏理论一点)

    1 Oracle 结构组件 目标 1-2 基本结构概述 1-3 Oracle 服务器 1-4 Oracle 实例 1-5 建立连接和创建会话 1-6 Oracle 数据库 1-7 物理结构 1-8 内存结构 1-9 系统全局区(SGA) 1-10 共享池 1-12 库缓存 1-13 数据字典...

    开涛高可用高并发-亿级流量核心技术

    17.3.2 本地缓存 352 17.3.3 多级缓存 353 17.3.4 统一入口/服务闭环 354 17.4 引入Nginx接入层 354 17.4.1 数据校验/过滤逻辑前置 354 17.4.2 缓存前置 355 17.4.3 业务逻辑前置 355 17.4.4 降级开关前置 355 17.4....

    UNIX-IBMAIX5L参考-性能管理指南.chm

    关于本书 本书的使用者 突出显示 在 AIX 中区分大小写 ISO 9000 相关出版物 性能概述 系统工作负载 性能目标 程序执行模型 硬件层次结构 软件层次结构 系统调谐 性能调谐 性能调谐过程介绍 性能基准 对 AIX 5.2 的...

    J2EE开发全程实录(JAVA项目开发)

    2.2.4 Java中的Map接口... 20 2.3 HashMap. 21 2.3.1 应用举例... 21 2.3.2 Map与HashCode. 26 2.4 使用缓存... 29 2.4.1 缓存的概念... 29 2.4.2 LRUMap类... 30 第3章 AOP. 33 3.1 AOP概论... 33 3.2 AspectJ. 35 ...

    vue全国志愿服务信息系统源码.zip

    utils 全局工具类 (codeValue 代码值, bus:EventBus 事件总线, Cache: 内存缓存, LocalStorage: 封装的处理本地缓存数据的方法, upload:文件上传, config:全局上下文, publicMethods: 公共校验方法) permission ...

    spring security 参考手册中文版

    20.1.1缓存控制 157 20.1.2内容类型选项 158 20.1.3 HTTP严格传输安全(HSTS) 159 20.1.4 HTTP公钥密码(HPKP) 161 20.1.5 X-Frame-Options 163 20.1.6 X-XSS保护 164 20.1.7内容安全策略(CSP) 165 配置内容安全...

    android-rest-client-template-master:我的推特应用

    通过ORM层将数据持久存储到本地SQLite存储中 显示远程图像数据并将其缓存到视图中 以下库用于实现此目的: java-用于处理身份验证流程的简单OAuth库。 具有JSON解析的简单异步HTTP请求 用于管理OAuth身份验证和...

Global site tag (gtag.js) - Google Analytics