jbosscache
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的更多相关文章
- JBoss 系列二十一:JBossCache核心API
内容简介 本处介绍JBossCache相关的主要API,我们目的通过本部分描述,读者可以使用JBossCache API,在自己的应用中使用JBossCache. Cache接口 Cache 接口是和 ...
- SSH面试题(struts2+Spring+hibernate)
struts2 + Spring +hibernate Hibernate工作原理及为什么要用? 原理: 1.读取并解析配置文件 2.读取并解析映射信息,创建SessionFactory ...
- Hibernate+EhCache配置二级缓存
步骤: 第一步:加入ehcache.jar 第二步: 在src目录下新建一个文件,名为:ehcache.xml 第三步:在hibernate配置文件的<session-factory>下配 ...
- hibernate缓存机制(转)
原文出处:http://www.cnblogs.com/wean/archive/2012/05/16/2502724.html 一.why(为什么要用Hibernate缓存?) Hibernate是 ...
- 分布式session的实现
一.分布式Session的几种实现方式 1.基于数据库的Session共享 2.基于NFS共享文件系统3.基于memcached 的session,如何保证 memcached 本身的高可用性?4. ...
- Ehcache 缓存使用
在开发高并发量,高性能的网站应用系统时,缓存Cache起到了非常重要的作用.本文主要介绍EHCache的使用,以及使用EHCache的实践经验. 笔者使用过多种基于Java的开源Cache组件,其中包 ...
- Hibernate 二级缓存的配置及使用_EhCache
大多数的应用程序中都会添加缓存模块,以减少数据库访问次数,同时增加响应速度.下面介绍一下hibernate的二级缓存.默认情况下hibernate的二级缓存是不开启的,我们需要手动配置并启用. 注: ...
- java系统高并发解决方案-转
转载博客地址:http://blog.csdn.net/zxl333/article/details/8685157 一个小型的网站,比如个人网站,可以使用最简单的html静态页面就实现了,配合一些图 ...
- java SSH框架详解(面试和学习都是最好的收藏资料)
Java—SSH(MVC)1. 谈谈你mvc的理解MVC是Model—View—Controler的简称.即模型—视图—控制器.MVC是一种设计模式,它强制性的把应用程序的输入.处理和输出分开.MVC ...
随机推荐
- 三:理解Page类的运行机制(例:在render方法中生成静态文件)
我这里只写几个常用的事件1.OnPreInit:此事件后将加载个性化信息和主题2.OnInit:初始化页面中服务器控件的默认值但控件的状态没有加载,没有创建控件树3.OnPreLoad:控件完成状态和 ...
- TensorFlow的梯度裁剪
在较深的网络,如多层CNN或者非常长的RNN,由于求导的链式法则,有可能会出现梯度消失(Gradient Vanishing)或梯度爆炸(Gradient Exploding )的问题. 原理 问题: ...
- php实现请求分流
一个请求,同时分发到多个服务器, 正常的是: A ============> B 现在想实现的是: --------------> C A ======> B ----- ...
- Async异步编程入门示例
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- 制作openstack使用的Ubuntu镜像
一.环境准备 OS:Ubuntu-14.04 制作镜像版本:Ubuntu-14.04.4-server-amd64.iso 查看是否支持虚拟化(有输出代表支持,否则在BIOS页面中设置即可): egr ...
- console 调试技巧
前言 如果统计一番前端最常用的方法,那么 console.log 一定位列其中.无论你写的是原生 JS 亦或者是 JQuery.Vue等等,调试之时,都离不开 console.log 方法.但是,co ...
- WCF 学习总结1 -- 简单实例
从VS2005推出WCF以来,WCF逐步取代了Remoting, WebService成为.NET上分布式程序的主要技术.WCF统一的模型整合了以往的 WebService.Remoting.MSMQ ...
- WCF 获取客户端IP
public class Service2 : IService2 { public User DoWork() { Console.WriteLine(ClientIpAndPort()); }; ...
- C#编译和运行过程图例
一张图,描述C#编译和运行过程,比较容易记忆理解
- 设计模式之工厂方法(FactoryMethod)模式
在五大设计原则的基础上经过GOF(四人组)的总结,得出了23种经典设计模式,其中分为三大类:创建型(5种).结构型(7种).行为型(11种).今天对创建型中的工厂方法(FactoryMethod)模式 ...