JBossCache 讲解说明

是什么?

一个树形结构、支持集群、支持事务的缓存技术。

有什么作用?

JBoss Cache是针对Java应用的企业级集群解决方案,其目的是通过缓存需要频繁访问的Java对象,提高应用的可用性并大幅度提升应用的整体性能。

JBoss Cache这样的分布式缓存扮演的是一个处于应用服务前端和数据库间的中间层的角色,提供对持久性数据状态在内存中的快速访问。JBoss Cache能够确保缓存中的数据状态和数据库中的状态一致、及时更新数据状态、并且保证JVM不会出现堆溢出问题。

为什么不使用Map?

很多人认为Map是考虑缓存的出发点(实际上,JSR-107 JCACHE专家组曾经在Map的基础上扩展实现javax.cache.Cache)。尽管Map非常适合用来存储简单的键/值对,在缓存必需的其它特性上,它就难免有点黔驴技穷,比如内存管理(eviction)、钝化(passivation)和持续性、细粒度锁定模型(首先,HashMap根本不是线程安全的;而ConcurrentHashMap采用的锁是粗粒度级的,它甚至不允许非阻塞用户或多用户从map中读取数据)等。而对于“合格的”缓存来说,它还需要具备一些“企业”特性,包括JTA兼容、附加侦听器等功能。

Map虽然是个好的起点,但如果需要实现或者管理我刚才提到的那些特性的话,选择缓存还是要比Map来得更合适一些。

JBossCache的缓存方式

JBoss Cache提供两种缓存方式:核心缓存(TreeCache)和POJO缓存(TreeCacheAOP)

核心缓存: 会直接把传递给它的数据存储在一个树型结构中。键/值对被存储在树的节点上,出于复制或持续性的需要它们都被序列化了 POJO 缓存: 则采用比较复杂的机制——利用字节码编织来内省(introspecting)用户类,并向用户类的域添加侦听器,一旦域值有任何变化,侦听器会立刻通知缓存。例如,如果要在POJO缓存中存储一个庞大、复杂的对象,会导致POJO缓存内省对象的字节码,最终只把该对象的原始域存储到树结构中。一旦域值有所变化,缓存只复制这个改变了的域值而不会去复制整个用户类,这是高效的细粒度复制。

在缓存面对庞大、复杂的对象的时候,细粒度复制确实有助于提高性能。但如果只是用它来存储一些String的话,细粒度复制就没有什么特别价值。类似地,对简单的用户对象运用POJO缓存——比方说一个只拥有两个String域的Person类,与其说对性能有什么帮助,倒不如说它是浪费开销。

下面主要针对核心缓存(TreeCache)进行讲解。

TreeCache的分类:

TreeCache按功能分为三类:本地(Local)Cache、复制(Replication)Cache和失效(Invalidation)Cache。 分布式Cache(复制和失效Cache)又分为两种,同步(REPL_ASYNC)和异步(REPL_SYNC),同步

Cache是在一个Cache实例做修改时,等待变化应用到其它实例后才返回,而异步Cache是在一个Cache实例做修改时,即刻返回。

缓存模式

LOCAL - 本地,非集群缓存。本地缓存不参与集群,也不同集群里的其他缓存通信。 因此,他 们的内容也不用串行化。但是,我们推荐将他们串行化, 这样将来的某一天想要改变缓存模式 时允许一定的灵活性。

REPL_SYNC - 同步复制。复制缓存将所有的变化复制到集群中的其他缓存。 同步复制意味着, 复制变化时,调用是阻塞的,直到收到复制确认。

REPL_ASYNC - 异步复制。与上面的 REPL_SYNC 类似, 复制缓存将所有的变化复制到集群中的 其他缓存。 因为异步,调用者不用阻塞直到收到复制确认。

INVALIDATION_SYNC - 如果缓存配置为失效而不是复制, 每次缓存里数据更新,集群里的其他 缓存将收到通知消息, 通知他们的数据已经陈旧了,应该从内存中驱逐。 这将减少复制的开 销,然而仍然能够使远程缓存中的陈旧数据失效。

INVALIDATION_ASYNC - 象上面一样,但是这个失效模式是用异步的方式广播失效消息的。

JBossCache 不得不说的那些机制 缓存加载器 缓存加载器是 JBoss Cache 的一个重要组成部分。 他们允许将节点持久化到磁盘或远程

缓存集群, 当缓存运行内存溢出时,允许钝化。 另外,缓存加载器允许 JBoss Cache 实现“温和启动”, 其中内存状态可以从持久存储中预先加载。 JBoss Cache 带有几个缓存加载器实现。

驱逐策略 驱逐策略通过管理有多少节点允许存储在内存中,以及他们的生命范围来控制着 JBoss

Cache的内存管理。 服务器上的内存限制决定了它不可能无限增长,因此需要有策略限制缓存的大小。驱逐策略绝大多数情况下与缓存加载器一同使用。配置文件中有相应的属性可供选择。

缓存钝化 当一个缓存驱逐数据时,可以用缓存加载器强制节点的钝化和激活。缓存钝化是当驱逐时,

从内存缓存移除一个对象并将它写入二级数据存储 (例如,文件系统、数据库)的过程。 缓存激活是当需要使用时,将一个对象从数据存储中恢复到内存缓存的过程。在这两种情况下,用配置的缓存加载器读出和写入数据存储。

并发

JBoss Cache 是个线程安全的缓存接口,并且使用它自己控制并发的有效机制。 为了实现树结构中的每个节点对应一个锁。这些锁的隔离级别和数据库实施的隔离级别相同,允许多用户同时读取数据。

高效的目的,缺省情况下它使用悲观锁方案。

事务 通过配置,JBoss Cache 可以使用并参与 JTA 兼容的事务。

缓存中的数据结构:

一个 Cache 由一组 Node 的实例组成, 这些 Node 按树型结构组织起来。 每个 Node 包含一个用于缓存数据对象的 Map。 需要重点关注的是,这个结构是一个数学树而不是图; 每个

Node有且仅有一个父节点, 而根节点则固定不变地被命名为 Fqn.ROOT。像这样组织节点的原

因是,可以提高数据的并发访问,并能在更细粒度上实现复制和持久化。

由于缓存本质上就是节点的集合,因此对于整个缓存或其中的单个节点的调用, 就集中在

对节点的集群、持久化、驱逐等方面。

关于Fqn的使用说明:

Fqn 是Fully qualified name(完全限定名)的缩写。 1. Set up the Fqns you need. create 3 Fqn variables:

childFqn1 = Fqn.fromString("/child1"); childFqn2 = Fqn.fromString("/child2"); childFqn3 = Fqn.fromString("/child2/child3");

2. Create child nodes under the root node.

child1 = root.addChild(childFqn1); child2 = root.addChild(childFqn2); child3 = root.addChild(childFqn3);

3. Query the nodes.

root.hasChild(childFqn1); // should return true

child2.hasChild(childFqn3.getLastElement()); // should return true child3.getParent(); // should return child2 child2.getParent(); // should return roo

4. Put some data in the nodes. By selecting the nodes in the tree view, you should see the contents of each node.

child1.put("key1", "value1"); child1.put("key2", "value2"); child2.put("key3", "value3"); child2.put("key4", "value4"); child3.put("key5", "value5"); child3.put("key6", "value6");

5. Query some of the data.

child1.getKeys(); child2.getData();

6. Remove some data in the nodes.

child1.remove("key1"); child2.remove("key3"); child3.clearData();

7. Delete nodes

root.removeChild(childFqn1); // will also remove any data held under child1 root.removeChild(childFqn2); // will recursively remove child3 as well.

JBossCache环境搭建与配置:

在 AS 5 的 server/all/ 中,有着关于集群及JBossCache 缓存配置的全部相关文件。

若想要准备多个环境,可以拷贝多份,并重新命名。配置文件则不需要另外准备,目录中有默认的设置。

部署JBoss Cache 及 操作 JBoss Cache

通过 CacheManager 服务部署。

在将你的缓存配置加到CacheManager之后,下一步则是为你的应用提供一个CacheManager有三种方式可以达到这个目的: 1、 依赖注入

前提是你的应用使用了JBoss Microcontainer 去配置 2、 JNDI查找

它绑定在java:CacheManager下 3、 CacheManagerLocator

的引用。

一旦获取到CacheManager的引用,使用起来则十分的简便。访问一个缓存通过传递一个你渴望的配置名。

配置名信息可以在JBOSS_HOME/server/all/deploy/cluster/jbosscache-manager.sar. 中

找到。其中有对应的缓存配置的详细信息。

已“JNDI 查找”方式为例:

Context ctx = new InitialContext();

CacheManager cacheManager = (CacheManager) ctx.lookup("java:CacheManager");

cacheManager.start();

cache = cacheManager.getCache("mvcc-entity", true); cache.start();

if(cache.getCacheStatus().allowInvocations() ) { }

Node rootNode = cache.getRoot();

Fqn peterGriffinFqn = Fqn.fromString("/griffin/peter"); Node peterGriffin = rootNode.addChild(peterGriffinFqn); peterGriffin.put("isCartoonCharacter", Boolean.TRUE);

cache.start();

如此操作JBossCache.。

在实际工作中的应用

看了上面的说明,是不是对Jboss Cache有了一定的了解了哪?

在数据库缓存的实际应用中,Jboss Cache一般用来缓存两种类型的数据,一种是频繁变化的数据,比如说证券业的行情,1秒钟更新一次,要读取N多次,放到数据库中根本不可行。

一种是不太变化的数据,比说如用户,组织,权限的数据,不会经常变化,但是会经常check用户的权限,这类表也适合放入到缓存中保存。

2 JbossCache的用法

1 下载JbossCache的包

2 配置JbossCache.xml文件,例子如下:

<?xml version="1.0" encoding="UTF-8"?>

<jbosscache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:jboss:jbosscache-core:config:3.0">

<!--

isolation levels supported: READ_COMMITTED and REPEATABLE_READ

nodeLockingSchemes: mvcc, pessimistic (deprecated), optimistic (deprecated)

-->

<locking

isolationLevel="REPEATABLE_READ"

lockParentForChildInsertRemove="false"

lockAcquisitionTimeout="20000"

nodeLockingScheme="mvcc"

writeSkewCheck="false"

concurrencyLevel="500"/>

<!--

Used to register a transaction manager and participate in ongoing transactions.

-->

<!--  <transaction

transactionManagerLookupClass="org.jboss.cache.transaction.GenericTransactionManagerLookup"

syncRollbackPhase="false"

syncCommitPhase="false"/>

-->

<!--

Used to register JMX statistics in any available MBean server

-->

<jmxStatistics

enabled="false"/>

<!--

If region based marshalling is used, defines whether new regions are inactive on startup.

-->

<startup

regionsInactiveOnStartup="true"/>

<!--

Used to register JVM shutdown hooks.

hookBehavior: DEFAULT, REGISTER, DONT_REGISTER

-->

<shutdown

hookBehavior="DEFAULT"/>

<!--

Used to define async listener notification thread pool size

-->

<listeners

asyncPoolSize="1"

asyncQueueSize="1000000"/>

<!--

Used to enable invocation batching and allow the use of Cache.startBatch()/endBatch() methods.

-->

<invocationBatching

enabled="true"/>

</jbosscache>

3 在启动时加载JbossCache,可以放到Listener中启动,示例程序如下:

/**

*loadtheConsttabletomemorywhenappserverstart

*/

privatevoid initConstTableToMemory() {

// init the jboss cache

CacheFactory factory = new DefaultCacheFactory();

Cache cache = factory.createCache("JBossCache.xml");

cache.create();

cache.start();

WebContextHolder.getInstence().setJbossCache(cache);

RefreshConstToMemory memory = new RefreshConstToMemory();

memory. refreshPdmmthdToMemory ();

}

4        RefreshConstToMemory是存放Jboss Cache数据的例子:

publicvoid refreshPdmmthdToMemory() {

Cache cache = WebContextHolder.getInstence().getJbossCache();

Node rootNode = cache.getRoot();

Node node = null;

Fqn fqn = null;

//从数据库中取出pdmmthd表的内容,放到Jboss Cache中。

PdmmthdDAO pdmmthdDAO = (PdmmthdDAO) BeanUtil.getBean("pdmmthdDAO");

List<Pdmmthd> pdmmthdList = pdmmthdDAO.getAllMethodFromDatabase();

node = cache.getNode("/pdmmthd");

if (node == null) {

fqn = Fqn.fromString("/pdmmthd");

node = rootNode.addChild(fqn);

}

node.put("/pdmmthd", pdmmthdList);

for (Pdmmthd pdmmthd : pdmmthdList) {

node.put(pdmmthd.getMtcode(), pdmmthd);

}

}

在数据库第一次启动,在数据更新以后,都需要手工调用上述的refreshALLMemory()方法。

为了保险起见,对于不支持Jboss Cache的情况,或者Jboss Cache出现故障,我们可以在查询时增加出错处理,示例程序如下:

public List<Pdmmthd> getAllMethodFromMemory() {

// try the Exception in case of can't find 'method' in memory

try {

Cache cache = WebContextHolder.getInstence().getJbossCache();

Node node = cache.getNode("/pdmmthd");

List list = (List) node.get("/pdmmthd");

// return a new List,cause the user need change the list.

// For example,It will add "All" method to the list.

List dest = new ArrayList();

dest.addAll(list);

return dest;

} catch (Exception e) {

return getAllMethodFromDatabase();

}

}

jbosscache的更多相关文章

  1. JBoss 系列二十一:JBossCache核心API

    内容简介 本处介绍JBossCache相关的主要API,我们目的通过本部分描述,读者可以使用JBossCache API,在自己的应用中使用JBossCache. Cache接口 Cache 接口是和 ...

  2. SSH面试题(struts2+Spring+hibernate)

    struts2 + Spring +hibernate Hibernate工作原理及为什么要用?   原理:   1.读取并解析配置文件   2.读取并解析映射信息,创建SessionFactory ...

  3. Hibernate+EhCache配置二级缓存

    步骤: 第一步:加入ehcache.jar 第二步: 在src目录下新建一个文件,名为:ehcache.xml 第三步:在hibernate配置文件的<session-factory>下配 ...

  4. hibernate缓存机制(转)

    原文出处:http://www.cnblogs.com/wean/archive/2012/05/16/2502724.html 一.why(为什么要用Hibernate缓存?) Hibernate是 ...

  5. 分布式session的实现

    一.分布式Session的几种实现方式 1.基于数据库的Session共享 2.基于NFS共享文件系统3.基于memcached 的session,如何保证 memcached 本身的高可用性?4. ...

  6. Ehcache 缓存使用

    在开发高并发量,高性能的网站应用系统时,缓存Cache起到了非常重要的作用.本文主要介绍EHCache的使用,以及使用EHCache的实践经验. 笔者使用过多种基于Java的开源Cache组件,其中包 ...

  7. Hibernate 二级缓存的配置及使用_EhCache

    大多数的应用程序中都会添加缓存模块,以减少数据库访问次数,同时增加响应速度.下面介绍一下hibernate的二级缓存.默认情况下hibernate的二级缓存是不开启的,我们需要手动配置并启用. 注: ...

  8. java系统高并发解决方案-转

    转载博客地址:http://blog.csdn.net/zxl333/article/details/8685157 一个小型的网站,比如个人网站,可以使用最简单的html静态页面就实现了,配合一些图 ...

  9. java SSH框架详解(面试和学习都是最好的收藏资料)

    Java—SSH(MVC)1. 谈谈你mvc的理解MVC是Model—View—Controler的简称.即模型—视图—控制器.MVC是一种设计模式,它强制性的把应用程序的输入.处理和输出分开.MVC ...

随机推荐

  1. wordpress获取文章所属分类

    1.获取全部分类 <?php foreach((get_the_category()) as $category){ echo $category->cat_name; } ?> 2 ...

  2. linux centos挂载数据盘教程

    一.备份/home/liying目录数据前提条件:电脑重启下,保证服务关闭,以免进程影响操作 a.新建backup目录#cd /#mkdir backup b.把/home/liying/目录下的数据 ...

  3. jar包运行main程序

    当把java项目打包成jar后,如何运行main函数呢? 第一种:指定运行main类: 1 java -cp test.jar com.hk.app.Application 第二种:在MANIFEST ...

  4. WPF中一个控件绑定另一个控件的属性

    如同一个Grid中的一个按钮根据另一个按钮的显示与否作出不同的响应: 绑定的时候通过ElementName来指定控件 <Grid Margin="50,130"> &l ...

  5. 当语音识别搭配AI之后,我的语音助手更懂我的心了

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由腾讯云AI中心发表于云+社区专栏 我今天演讲主要分四个部分,第一个是分享语音识别概述,然后是深度神经网络的基础:接下来就是深度学习在语 ...

  6. let‘s encrypt之nginx-https没有小锁

    1.使用let's encrypt 加密后的nginx,访问的时候,发现没有小锁,chrome中: 火狐浏览器上: 会看到如上信息,这是因为css.图片或javascript任然通过http提供,可以 ...

  7. Java subList、toArray、asList 注意点

    1. ArrayList的subList 结果不可以强转成ArrayList,否则抛出ClassCastException异常,原因是subList返回的是ArrayList的内部类SubList,并 ...

  8. Rectangles(第七届ACM省赛原题+最长上升子序列)

    题目链接: http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=1255 描述 Given N (4 <= N <= 100)  rec ...

  9. Array.prototype.map()和Array.prototypefilter()

    ES5 => 筛选功能  Array.prototypefilter(): 代码: var words = ['spray', 'limit', 'elite', 'exuberant', 'd ...

  10. 我进行jvm内存调优的一些记录

    jvm内存调优的一些记录 java内存调优的方法和过程 可以使用 jmap -heap pid号 查看,例如pid是9300,执行的结果可能是这样的. root@ubuntu:~# jmap -hea ...