正是基于以上技术和特点,Coherence成为一个高可用性,高扩展性,高性能但使用非常简单的网格型(Data Grid)分布式缓存框架。
2. Quick start
2.1 安装
Coherence是纯Java的框架,不需要额外的安装。首先在Oracle网站上下载开发包,最新为3.4版,只有13M,可以说是很小很强大。
SDK解压即可,包含 bin, doc, example, lib 四个目录。Doc下包含了完整的user-guide,只是有点长,有350多页。
2.2 运行
Coherence集群是由Node构成的,每个Node既存储数据,又可以查询数据。
运行 bin/coherence.cmd 命令就能启动一个Node实例。
运行多次,就能启动多个实例,各Node能自动检测到网路内新启动的Node,并加入集群。
第一个节点启动信息大致为:
第二个节点启动信息大致为:
最后会出现命令行提示符,通过Coherence控制台命令就可以执行Cache的基本操作。
最常用命令有:
创建或切换到一个cache:
Put一个数据:
Get一个数据:
查看有哪些cache:
查看一个cache下的所有key:
你不必关心数据存在哪里,可以在Node1上 put一个数据,在Node2上get出来。
默认启动Node使用的是 Coherence.jar中的缓存配置文件 coherence-cache-config.xml ,使用的是DistributedCache 分区缓存。
3. 编程
正如第一节所说,使用Coherence进行数据管理的应用程序中的API调用非常简单,无论集群有多少个物理机器,多少个节点实例,客户端只逻辑上面对集群。
记得在你的应用中(例如:BOSS,CRM等)中包含 coherence.jar, tangosol.jar 等必要的类库文件。
4. 基本缓存类型及适用情况
Coherence 支持四种Cache类型(Cache Type),也可看作四种缓存系统架构:
4.1 复制缓存(Replicated Cache)
数据在集群成员中进行全复制,每个节点都有一个完整的数据拷贝。这种集群下,read性能最高( cache.get(key) 操作),容错性好,但cache.put(key,value) 操作性能较低。如果Node很多,每次put操作都要在所有成员上执行一次。
cache.get(key)
cache.put(key,value)
这是一种传统的集群技术,不是Coherence的亮点。
4.1 乐观缓存 (Optimistic Cache)
它类似于复制缓存,但不提供并发控制(Concurrency Control)。这种集群数据吞吐量最高,各节点容易出现数据不一致的情况。
4.1 分区缓存 (Distributed (Partitioned) Cache)
Coherence 的亮点。默认情况下,一份数据A只在两个节点上有拷贝,第二份作为备份数据(Backup),用于容错。
从整体上看,假设应用需要的Cache总内存为 M,该模式将数据分散到N个节点上,每个JVM只占用 M/N 的内存消耗,与复制缓存每节点消耗 M量的内存形成对比,它可以极大节省内存资源。
cache.get(key)
cache.put(key,value)
4.1 Near缓存 (NearCache)
分区缓存的改进版。分区缓存将数据全部存到Cache Node上,而Near缓存将缓存数据中使用频率最高的数据(热点数据Hotspot)放到应用的本地缓存(Local Cache)区域。由于本地内存访问的高效性,它可以有效提升分区缓存的read性能。
四种缓存类型的基本特点对比如下表所示:
几个重要因素:
JVM数量(N): 即启动的Node数量,每个节点为一个JVM进程;
数据大小(M):要缓存的数据总量的占用空间大小,如10M,120M等;
冗余度(R) :缓存的secondary备份个数。分区缓存默认为1,可以配置2,3,…
本地缓存大小(L):(仅对Near缓存而言)应用所在的本地缓存的空间大小字节数。
几种类型的对比
Coherence提供了四种Cache数据管理模式:
Read-Through,
Write-Through,
Refresh-Ahead
Write-Behind
数据管理模式体现在CacheStore 接口的功能上。
CacheStore负责直接和数据源交互,进行增删改查操作;并也负责和Coherence Cache交互,向其中写数据(put),读数据(get)和删除数据(remove)。CacheStore相当于 数据源和Cache间的桥梁。
对于不同的应用,由于数据源不同,如:DB,WebService ,FileSystem等, CacheStore有不同的实现。它一般作为应用的一部分。Coherence也为 Hibernate,Toplink等实现了一个CacheStore。
5.1 Read-Through
Read-Through 的基本特点是同步读取。步骤为:
1)应用调用 CacheStore 查询数据X;
2)CacheStore 去Cache中查询,未发现数据时,向数据库执行查询操作,并将查询结果放到 Cache中, 并将结果返回给应用;
3)如果发现Cache中有数据,则直接从Cache读取,并返回给应用。
其特点体现在第二步,CacheStore调用 cache.get(X) 到 CacheStore 给应用返回数据,是同步操作。 也就是要在一个同步过程中先等待数据查询,Cache被填充,才能获得数据。 这种模式的性能比较低,不及 Refresh-Ahead。
5.2 Write-Through
Write-Through 对应于数据修改操作,如 update,也具有同步的特点。
1)应用调用 CacheStore update数据X;
2)CacheStore 先update Cache中的数据,然后再向数据库执行update操作;
这种模式在一个同步过程中,先改Cache,再改数据库。因此性能也不是最理想的。
5.2 Refresh-Ahead
与Read-Through相对,它是异步的。
Coherence在Cache数据过期前,有CacheStore自动重新从数据库加载数据。而前台应用在查询数据时,CacheStore 仅调用Cache.get(X)。因此这种模式的效率明显高于read-through。 自动重载数据的时间可以设定。
5.2 Write-behind
与write-through相对,它是异步的。
应用调用CacheStore进行update时,CacheStore不去操作数据库,直接返回结果。而Coherence集群自动对操作进行排队 (queue),在间隔一段时间后(interval), CacheStore在执行队列中的 update 操作。 这样,减少的同步操作数据库的时间被节省,修改类功能的性能就能得到大幅提高。这也是Coherence的一大特色。
Oracle Coherence 是一个面向企业级应用的分布式缓存框架,看过它的简单介绍后,感觉是:很好很强大。
Hibernate 封装了统一的 Cache接口 CacheProvider ,可以方便的集成实现该接口的第三方Cache框架。
本文就不详细介绍 Coherence 的特点和优势了,感兴趣或要使用的直接到Oracle网站去查询。 http://www.oracle.com/products/middleware/coherence/index.html
如何与Hibenate进行集成, Coherence的userguide只简单说了一下原理性的东东,没有具体实例。我仔细做了一个从头到尾的过程,直到Hibernate应用跑起来, 并观察日志,确认Coherence缓存起作用为止。 以下是我记录下来的配置运行过程,供需要的同学参考。
1. 运行前的说明
本 demo 客户端是Hibernate的数据操作代码,无外乎 session.update(),query.list() 等等。
测试准备两台物理机器 M1, M2 。M1 上跑Hibernate应用, 和1个Node; M2上准备跑 2 个Coherence 缓存节点(Node). 这里3个Node分散到两个 机器,主要是演示Coherence集群的自管理的强大功能。
[img]/upload/attachment/42720/e4c427b3-1651-3092-a207-fe6da4f102bf.jpg" alt="[/img]
原理简要说明:M2上的Node启动后,将自动加入Coherence 缓存集群(Cluster); 客户端Hibernate应用启动,执行后,由于也使用了Coherence, 它的查询操作将到 集群 上的三个Node的Cache中去取数据;只是第一次query会从数据库取数据,并放到Node的缓存中,以后各次query,findByPk 等操作,都会到Node的缓存中取。
2. Cache服务端配置
2.1) 启动Node bat文件准备
Coherence开发包的目录很简单,只有 bin,doc,lib,examples 四个目录,原以为只要启动 coherence/bin/coherence.cmd 就可以了,后来发现没那么简单。
要让M2上的Node缓存Hibernate应用的数据,需要 org.hibernate.cache.QueryKey 等类,因此需要将 hibernate3.jar 加入classpath;
要缓存hibernate应用中的 com.xxx.system.perm.PermVO 等VO类,还必须将自己应用的 jar包也放到classpath中。
其他还需要一些相关的jar,如:dom4j,common-logging 等,最终编写了一个 runCache.bat 文件,做好必要的初始化工作:
runCache.bat
我的coherence工作目录是
其中在我的工作目录下专门建了一个 lib 目录,存放需要的新的jar包,并将配置文件从 coherence-hibernate.jar/config 目录下移到工作目录下,目录结构是:
[img]/upload/attachment/42577/11dfaeba-8a74-39e3-9c3d-d60cb47dd2b8.jpg" alt="[/img]
这要,运行 runCache.bat 就可以启动一个 Coherence Node实例。本文在M2机器上开2个 cmd 窗口,启动2个实例, 在 M1 上启动一个 Node 实例。启动后的结果大致如:
[img]/upload/attachment/42575/57ba5d87-1175-38fb-ac4c-d7902d61bb9a.jpg" alt="" width="512" height="304[/img]
2.2) 缓存配置
hibernate-cache-config.xml 是一个必要的缓存配置,本例使用 HibernateReplicatedCache 复制模式。
通过
加入Java命令的启动参数中, coherence 会替换默认的配置。
还要修改 coherence 的缺省启动命令 coherence.cmd, 将java_opts 加入到原有的变量中,将
修改为
并将 coherence-hibernate.jar 加入classpath中, 将
修改为
3. Cache客户端配置:Hibernate配置
3.1) hibernate.cfg.xml
3.2) 启用查询缓存的代码
要确保代码中使用查询,即在创建 query 后,打开开关,并设置cacheRegion,本例中使用统一的 cacheRegion “HIBERNATE_QUERY_CACHE”
3.3) 启用实体L2缓存
在 hbm.xml 中配置 节点,为VO类启用实体缓存。
3.4) 客户端缓存配置
客户端要使用与服务端同样的缓存配置 hibernate-cache-config.xml, 否则可能无法进行存储。 本例将其复制过来,放到classpath 下的 config目录中,因此,客户端启动命令(如果是tomcat,weblogic,websphere,修改相应cmd或bat文件)中也要加java 参数:
4. 启动客户端Hibernate应用程序
执行数据查询操作,观察日志,以确定数据存储到了M2的三个节点中。
4.1) Coherence客户端启动日志
4.2) 观察Hibernate SQL输出
记得在log4j.xml 中打开相应的日志开关:
观察日志输出
第一次执行了sql,
后面sql都未执行,并且查询结果数为1,和第一次执行sql的结果相同。表明之后从Coherence中获取了数据, 缓存生效。
4.3) 查看M2 上的cache数据:
在M2上的节点控制台切换到 HIBERNATE_QUERY_CACHE cache下面,执行:
并执行Coherence命令
命令查看所有已在Cache中存储的数据。 下面的日志每个 sql:开头的就是一个对Query的缓存项。
OK, 大功告成,成功将Coherence与Hibernate集成,Hibernate通过Coherence进行实体数据,查询数据的缓存。
7.1 概述
Coherence支持集群JMX管理和监控,方便在多Node环境下的统一管理。
根据Coherence官方的推荐,一般一个集群中只设置一个JMX管理服务器(MBeanServer),并且管理服务器不存储数据(设置启动参数storage_enabled=false);其他Node为受管节点,存储数据。
7.2 启动参数
要为节点启用JMX管理,启动时只要加入必要的java property即可。一般可以JDK5+自带的JConsole工具做管理和监控。
JMX Server:
JMX Node:
7.3 JMX Server监控
通过JConsole连接Coherence JMX Server后的界面如下图所示:
图中,
Cluster代表整个集群
Node节点下代表各节点,图中有1,2 两个节点;
Cache目录代表当前集群中创建的的NamedCache,图中展示了集群中有一个分区缓存 cache1,存储在节点2 中。
其他还有Server,StorageManager,PointToPoint等管理项。
右侧列出了所选项目的详细属性,图中为Node 2 上数据存储的信息,比较有用的是
命中次数CacheHits,
失误次数CacheMisses,
缓存访问次数:TotalGets,通过 CacheHits/ TotalGets 就可得到命中率
缓存元素上限:HighUnits等。
通过观察各节点Cache的主要指标,就可以监控Coherence的运行情况,分析缓存的利用效率。见下图例:
图显示了在JOP号码资源应用下,号码资源VO的CacheHits变化情况,命中数在逐步提高,为2800,说明缓存有效发挥了其作用;当然命中率是反映Cache利用率更为直观的指标。
7.4 Node监控
通过连接不同Node,还可以监控各存储节点的内存变化等信息,为调优提供必要依据。
Coherence调优是很关键的一环,特别是对大型企业级应用,海量数据型应用,它将决定Coherence集群能否将效能最大化的发挥出来。
调优通常分三步:基础调优,运行前常规调优,运行后调优
8.1基础调优
包括操作系统调优,网络调优
操作系统的一些参数,对Coherence集群的数据传输有影响。
如:非Wins系统下Socket缓冲大小,应该至少增加到2M;Windows上的Datagram大小等,这些在官方指南中有详细的说明。
网络调优主要对交换机缓冲(Switch Buffer), Path MTU 等因素,比较常见的情况是,交换机缓存如果太小,Coherence在做Node通信时会发生延迟,Node日志一般为:
此时就需要增加交换机缓冲大小。
8.2运行前常规调优
指根据Coherence一般经验原则和最佳实践,在应用系统运行前分析缓存数据总量大小,计算Node个数,设置Node JVM内存等。
缓存数据总量大小(DataSize, M):根据应用规模,数据量规模,业务频度,预先估计应该纳入缓存的数据量的大小(总字节数)。对大型系统来说,可能是1G – xG。
计算节点个数:分区和Near缓存每节点只承担 M/N 的数据量,Coherence的原则是,尽量多节点,而不要将Node的内存设置过大,避免GC时间过长,一般不要超过 1G;因此,得到估计的数据总量大小M后,就可以估计需要配置的节点数,假设JVM mx为512M,则N=M/512,并据此推测需要的物理机器的数量。
JVM内存:Coherence默认为64M,每节点最大不要超过1G。并且最小和最大值设置为相同。当然可以根据项目情况,设置为 384m, 128m等。
例如:
GC 参数:一般应用Coherence的多为大型系统,多CPU;且缓存数据变化可能比较频繁。
8.3运行后调优
系统上线后,在运行过程中,可能会出现性能不如预期的情况,或者不定期出现缓慢情况。除了对JVM 垃圾回收问题进行分析,还可以对应用进行分析,对缓存配置进行优化。
JVM 垃圾回收问题:节点GC时,会导致Node间的传输暂停,需要重传,引起集群性能下降。可可以通过Node的日志观察到,类似于:
除了之前的优化交换机缓冲,还要考虑垃圾回收引起此问题的具体原因,可以通过打开垃圾回收日志进行观察,这通常可能会定位到程序代码的算法等问题。
应用分析:
如果为了简便,在Coherence配置中使用 * 配置NamedCache的存储属性,那么意味着,所有NamedCache或者说一部分Cache 使用了相同的设置,如元素个数,超时时间,清除策略,前端缓存大小等。
但不同业务功能其数据量大小,查询频率,查询条件的多样性,数据修改的频率都是不同的,如果配置相同,则Cache机制在不同业务上体现的性能是不同的,应该区别对待,例如:
1) 数据字典修改频率极低,可以只采用local cache, 超时时间设置长一些,例如12h 。
2) 鉴权操作频率很高,因此要求高性能。鉴权数据中权限点修改频率低,但角色授权数据修改频率略高,但比一般业务也低很多,可以将 front cache设置大一些,或者只采用local访问。
3) 在Hibernate中,低频修改数据缓存配置为 nonstrict-read-write 类型;只读数据采用 read-only 型。
4) 至于业务数据,情况比较复杂。
例如:手机号码表,数据量极大,并且服务于BOSS大部分业务,并且手机号码的用户资料变更较少,因此缓存可以设置大些, 超时时间设置长些。而类似的渠道数据,数据量略小一些,HighUnits可设置稍小一些。
而对于一些修改频繁,或新增频繁的数据,超时时间(Expiry Delay) 应当设置小一些。
此类分析应该跟踪生产环境的运行情况,业务频率,修改操作频率等,进行调整优化,并跟踪调优后的结果。
9. 结束
Oracle Coherence具有一般缓存框架的极不一样的强大特性,自管理,分区缓存,线性扩展等使得它能有效提升应用,特别是大型企业级应用的性能。Coherence也是一个网格计算方案,其线性扩展也体现了“另类”的系统架构,能发挥出强大的功能。
参考资料:
1. Oracle. Coherence User-guide.htm
2. http://www.oracle.com/technology/global/cn/products/coherence/index.html
3. iniu blog http://iniu.net/iwork/2008/02/oracle-coherence.html