@liyuj
2017-04-12T22:57:13.000000Z
字数 6408
阅读 2590
Apache-Ignite-1.9.0-中文开发手册
Ignite可以用做Hibernate的二级缓存,它可以显著地提升应用持久化层的性能。
Hibernate是著名的、应用广泛的对象关系映射框架(ORM),在与SQL数据库紧密互动的同时,他通过对查询结果集的缓存来最小化昂贵的数据库请求。
Hibernate数据库映射对象的所有工作都是在一个会话中完成的,通常绑定到一个worker线程或者Web会话。默认的话,Hibernate只会使用Session级的缓存(L1),因此,缓存在一个会话中的对象,对于另一个会话是不可见的。然而,如果用一个全局的二级缓存的话,他缓存的所有对象对于用同一个缓存配置的所有会话都是可见的。这通常会带来性能的显著提升,因为每一个新创建的会话都可以利用L2缓存(他比任何会话级L1缓存都要长寿)中已有的数据的好处。
L1缓存是一直启用的而且是由Hibernate内部实现的,而L2缓存是可选的而且有很多的可插拔的实现。Ignite可以作为L2缓存的实现非常容易地嵌入,而且可以用于所有的访问模式(READ_ONLY
,READ_WRITE
,NONSTRICT_READ_WRITE
和TRANSACTIONAL
),支持广泛的相关特性:
复制
和分区
如果要将Ignite作为Hibernate的二级缓存,需要简单的三个步骤:
本章节的后面会详细介绍这些步骤的细节。
要将Ignite配置为Hibernate的二级缓存,不需要修改已有的Hibernate代码,只需要:
应用中可能会用到的部分Hibernate类需要设置一个特定的BinaryTypeConfiguration
,比如,org.hibernate.cache.spi.CacheKey
已经添加了该配置,大致如下:
BinaryConfiguration bCfg = new BinaryConfiguration();
// Setting specific binary configuration for a Hibernate class.
BinaryTypeConfiguration btCfg = new BinaryTypeConfiguration();
// Setting the class name.
btCfg.setTypeName(org.hibernate.cache.spi.CacheKey.class.getName());
// Setting special binary identity resolver.
btCfg.setIdentityResolver(new BinaryAbstractIdentityResolver() {
@Override protected int hashCode0(BinaryObject obj) {
return return obj.field("key").hashCode();
}
@Override protected boolean equals0(BinaryObject o1, BinaryObject o2) {
Object obj0 = o1.field("key");
Object obj1 = o2.field("key");
return Objects.equals(obj0, obj1);
}
});
// Applying the configuration.
bCfg.setTypeConfigurations(Collections.singleton(btCfg));
IgniteConfiguration igniteConfiguration = new IgniteConfiguration()
.setBinaryConfiguration(bCfg);
Maven配置
Maven依赖
为了开启Ignite的hibernate集成,需要在工程里面添加ignite-hibernate的依赖,或者在从命令行启动之前,从libs/optional中将ignite-hibernate模块拷贝到libs文件夹。
要在项目中添加Ignite-hibernate集成,需要将下面的依赖加入POM文件:
<dependency>
<groupId>org.apache.ignite</groupId>
<artifactId>ignite-hibernate</artifactId>
<version>RELEASE</version>
</dependency>
Hibernate配置示例
一个用Ignite配置Hibernate二级缓存的典型例子看上去像下面这样:
<hibernate-configuration>
<session-factory>
...
<!-- Enable L2 cache. -->
<property name="cache.use_second_level_cache">true</property>
<!-- Generate L2 cache statistics. -->
<property name="generate_statistics">true</property>
<!-- Specify Ignite as L2 cache provider. -->
<property name="cache.region.factory_class">org.apache.ignite.cache.hibernate.HibernateRegionFactory</property>
<!-- Specify the name of the grid, that will be used for second level caching. -->
<property name="org.apache.ignite.hibernate.grid_name">hibernate-grid</property>
<!-- Set default L2 cache access type. -->
<property name="org.apache.ignite.hibernate.default_access_type">READ_ONLY</property>
<!-- Specify the entity classes for mapping. -->
<mapping class="com.mycompany.MyEntity1"/>
<mapping class="com.mycompany.MyEntity2"/>
<!-- Per-class L2 cache settings. -->
<class-cache class="com.mycompany.MyEntity1" usage="read-only"/>
<class-cache class="com.mycompany.MyEntity2" usage="read-only"/>
<collection-cache collection="com.mycompany.MyEntity1.children" usage="read-only"/>
...
</session-factory>
</hibernate-configuration>
这里,我们做了如下工作:
Ignite配置示例
一个典型的支持Hibernate二级缓存的Ignite配置,像下面这样:
<!-- Basic configuration for atomic cache. -->
<bean id="atomic-cache" class="org.apache.ignite.configuration.CacheConfiguration" abstract="true">
<property name="cacheMode" value="PARTITIONED"/>
<property name="atomicityMode" value="ATOMIC"/>
<property name="writeSynchronizationMode" value="FULL_SYNC"/>
</bean>
<!-- Basic configuration for transactional cache. -->
<bean id="transactional-cache" class="org.apache.ignite.configuration.CacheConfiguration" abstract="true">
<property name="cacheMode" value="PARTITIONED"/>
<property name="atomicityMode" value="TRANSACTIONAL"/>
<property name="writeSynchronizationMode" value="FULL_SYNC"/>
</bean>
<bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
<!--
Specify the name of the caching grid (should correspond to the
one in Hibernate configuration).
-->
<property name="gridName" value="hibernate-grid"/>
...
<!--
Specify cache configuration for each L2 cache region (which corresponds
to a full class name or a full association name).
-->
<property name="cacheConfiguration">
<list>
<!--
Configurations for entity caches.
-->
<bean parent="transactional-cache">
<property name="name" value="com.mycompany.MyEntity1"/>
</bean>
<bean parent="transactional-cache">
<property name="name" value="com.mycompany.MyEntity2"/>
</bean>
<bean parent="transactional-cache">
<property name="name" value="com.mycompany.MyEntity1.children"/>
</bean>
<!-- Configuration for update timestamps cache. -->
<bean parent="atomic-cache">
<property name="name" value="org.hibernate.cache.spi.UpdateTimestampsCache"/>
</bean>
<!-- Configuration for query result cache. -->
<bean parent="atomic-cache">
<property name="name" value="org.hibernate.cache.internal.StandardQueryCache"/>
</bean>
</list>
</property>
...
</bean>
上面的代码为每个二级缓存区域指定了缓存的配置:
分区
缓存在缓存节点间拆分数据,其他的策略也可以选择复制
模式,这样的话就在所有缓存节点上复制完整的数据集,可以参照相关的章节以了解更多的信息。事务
原子化模式来利用缓存事务的优势FULL_SYNC
模式保持备份节点的完全同步另外,指定了一个缓存来更新时间戳,它可以是原子化
的,因为性能好。
配置完Ignite缓存节点后,可以通过如下方式在节点内启动他:
Ignition.start("my-config-folder/my-ignite-configuration.xml");
上述代码执行完毕后,内部的节点就启动了然后准备缓存数据,也可以从控制台执行如下命令来启动额外的独立的节点:
$IGNITE_HOME/bin/ignite.sh my-config-folder/my-ignite-configuration.xml
对于Windows,可以执行同一文件夹下的.bat
脚本。
节点也可以在其他主机上启动,以形成一个分布式的缓存集群,一定要确保在配置文件中指定正确的网络参数。
除了二级缓存,Hibernate还提供了查询缓存,这个缓存存储了通过指定参数集进行查询的结果(或者是HQL或者是Criteria),因此,当重复用同样的参数集进行查询时,他会命中缓存而不会去访问数据库。
查询缓存对于反复用同样的参数集进行查询时是有用的。像二级缓存的场景一样,Hibernate依赖于一个第三方的缓存实现,Ignite也可以这样用。
要考虑Ignite中对于基于SQL的内存内查询的支持,他会比通过Hibernate性能更好。
上面的配置信息完全适用于查询缓存,但是额外的配置和代码变更还是必要的。
Hibernate配置
要在Hibernate种启用查询缓存,只需要在配置文件中添加额外的一行:
<!-- Enable query cache. -->
<property name="cache.use_query_cache">true</property>
然后,需要对代码做出修改,对于要缓存的每一个查询,都需要通过调用setCacheable(true)
来开启cacheable
标志。
Session ses = ...;
// Create Criteria query.
Criteria criteria = ses.createCriteria(cls);
// Enable cacheable flag.
criteria.setCacheable(true);
...
这个完成之后,查询结果就会被缓存了。
Ignite配置
要在Ignite中开启Hibernate查询缓存,需要指定一个额外的缓存配置:
<property name="cacheConfiguration">
<list>
...
<!-- Query cache (refers to atomic cache defined in above example). -->
<bean parent="atomic-cache">
<property name="name" value="org.hibernate.cache.internal.StandardQueryCache"/>
</bean>
</list>
</property>
注意为了更好的性能缓存配置为原子化
的。