[关闭]
@liyuj 2017-04-12T22:57:13.000000Z 字数 6408 阅读 2590

Apache-Ignite-1.9.0-中文开发手册

8.Hibernate

8.1.Hibernate二级缓存

8.1.1.摘要

Ignite可以用做Hibernate的二级缓存,它可以显著地提升应用持久化层的性能。
Hibernate是著名的、应用广泛的对象关系映射框架(ORM),在与SQL数据库紧密互动的同时,他通过对查询结果集的缓存来最小化昂贵的数据库请求。

Hibernate数据库映射对象的所有工作都是在一个会话中完成的,通常绑定到一个worker线程或者Web会话。默认的话,Hibernate只会使用Session级的缓存(L1),因此,缓存在一个会话中的对象,对于另一个会话是不可见的。然而,如果用一个全局的二级缓存的话,他缓存的所有对象对于用同一个缓存配置的所有会话都是可见的。这通常会带来性能的显著提升,因为每一个新创建的会话都可以利用L2缓存(他比任何会话级L1缓存都要长寿)中已有的数据的好处。
L1缓存是一直启用的而且是由Hibernate内部实现的,而L2缓存是可选的而且有很多的可插拔的实现。Ignite可以作为L2缓存的实现非常容易地嵌入,而且可以用于所有的访问模式(READ_ONLY,READ_WRITE,NONSTRICT_READ_WRITETRANSACTIONAL),支持广泛的相关特性:

如果要将Ignite作为Hibernate的二级缓存,需要简单的三个步骤:

本章节的后面会详细介绍这些步骤的细节。

8.1.2.二级缓存配置

要将Ignite配置为Hibernate的二级缓存,不需要修改已有的Hibernate代码,只需要:

应用中可能会用到的部分Hibernate类需要设置一个特定的BinaryTypeConfiguration,比如,org.hibernate.cache.spi.CacheKey已经添加了该配置,大致如下:

  1. BinaryConfiguration bCfg = new BinaryConfiguration();
  2. // Setting specific binary configuration for a Hibernate class.
  3. BinaryTypeConfiguration btCfg = new BinaryTypeConfiguration();
  4. // Setting the class name.
  5. btCfg.setTypeName(org.hibernate.cache.spi.CacheKey.class.getName());
  6. // Setting special binary identity resolver.
  7. btCfg.setIdentityResolver(new BinaryAbstractIdentityResolver() {
  8. @Override protected int hashCode0(BinaryObject obj) {
  9. return return obj.field("key").hashCode();
  10. }
  11. @Override protected boolean equals0(BinaryObject o1, BinaryObject o2) {
  12. Object obj0 = o1.field("key");
  13. Object obj1 = o2.field("key");
  14. return Objects.equals(obj0, obj1);
  15. }
  16. });
  17. // Applying the configuration.
  18. bCfg.setTypeConfigurations(Collections.singleton(btCfg));
  19. IgniteConfiguration igniteConfiguration = new IgniteConfiguration()
  20. .setBinaryConfiguration(bCfg);

Maven配置

Maven依赖
为了开启Ignite的hibernate集成,需要在工程里面添加ignite-hibernate的依赖,或者在从命令行启动之前,从libs/optional中将ignite-hibernate模块拷贝到libs文件夹。

要在项目中添加Ignite-hibernate集成,需要将下面的依赖加入POM文件:

  1. <dependency>
  2. <groupId>org.apache.ignite</groupId>
  3. <artifactId>ignite-hibernate</artifactId>
  4. <version>RELEASE</version>
  5. </dependency>

Hibernate配置示例
一个用Ignite配置Hibernate二级缓存的典型例子看上去像下面这样:

  1. <hibernate-configuration>
  2. <session-factory>
  3. ...
  4. <!-- Enable L2 cache. -->
  5. <property name="cache.use_second_level_cache">true</property>
  6. <!-- Generate L2 cache statistics. -->
  7. <property name="generate_statistics">true</property>
  8. <!-- Specify Ignite as L2 cache provider. -->
  9. <property name="cache.region.factory_class">org.apache.ignite.cache.hibernate.HibernateRegionFactory</property>
  10. <!-- Specify the name of the grid, that will be used for second level caching. -->
  11. <property name="org.apache.ignite.hibernate.grid_name">hibernate-grid</property>
  12. <!-- Set default L2 cache access type. -->
  13. <property name="org.apache.ignite.hibernate.default_access_type">READ_ONLY</property>
  14. <!-- Specify the entity classes for mapping. -->
  15. <mapping class="com.mycompany.MyEntity1"/>
  16. <mapping class="com.mycompany.MyEntity2"/>
  17. <!-- Per-class L2 cache settings. -->
  18. <class-cache class="com.mycompany.MyEntity1" usage="read-only"/>
  19. <class-cache class="com.mycompany.MyEntity2" usage="read-only"/>
  20. <collection-cache collection="com.mycompany.MyEntity1.children" usage="read-only"/>
  21. ...
  22. </session-factory>
  23. </hibernate-configuration>

这里,我们做了如下工作:

Ignite配置示例
一个典型的支持Hibernate二级缓存的Ignite配置,像下面这样:

  1. <!-- Basic configuration for atomic cache. -->
  2. <bean id="atomic-cache" class="org.apache.ignite.configuration.CacheConfiguration" abstract="true">
  3. <property name="cacheMode" value="PARTITIONED"/>
  4. <property name="atomicityMode" value="ATOMIC"/>
  5. <property name="writeSynchronizationMode" value="FULL_SYNC"/>
  6. </bean>
  7. <!-- Basic configuration for transactional cache. -->
  8. <bean id="transactional-cache" class="org.apache.ignite.configuration.CacheConfiguration" abstract="true">
  9. <property name="cacheMode" value="PARTITIONED"/>
  10. <property name="atomicityMode" value="TRANSACTIONAL"/>
  11. <property name="writeSynchronizationMode" value="FULL_SYNC"/>
  12. </bean>
  13. <bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
  14. <!--
  15. Specify the name of the caching grid (should correspond to the
  16. one in Hibernate configuration).
  17. -->
  18. <property name="gridName" value="hibernate-grid"/>
  19. ...
  20. <!--
  21. Specify cache configuration for each L2 cache region (which corresponds
  22. to a full class name or a full association name).
  23. -->
  24. <property name="cacheConfiguration">
  25. <list>
  26. <!--
  27. Configurations for entity caches.
  28. -->
  29. <bean parent="transactional-cache">
  30. <property name="name" value="com.mycompany.MyEntity1"/>
  31. </bean>
  32. <bean parent="transactional-cache">
  33. <property name="name" value="com.mycompany.MyEntity2"/>
  34. </bean>
  35. <bean parent="transactional-cache">
  36. <property name="name" value="com.mycompany.MyEntity1.children"/>
  37. </bean>
  38. <!-- Configuration for update timestamps cache. -->
  39. <bean parent="atomic-cache">
  40. <property name="name" value="org.hibernate.cache.spi.UpdateTimestampsCache"/>
  41. </bean>
  42. <!-- Configuration for query result cache. -->
  43. <bean parent="atomic-cache">
  44. <property name="name" value="org.hibernate.cache.internal.StandardQueryCache"/>
  45. </bean>
  46. </list>
  47. </property>
  48. ...
  49. </bean>

上面的代码为每个二级缓存区域指定了缓存的配置:

另外,指定了一个缓存来更新时间戳,它可以是原子化的,因为性能好。
配置完Ignite缓存节点后,可以通过如下方式在节点内启动他:

  1. Ignition.start("my-config-folder/my-ignite-configuration.xml");

上述代码执行完毕后,内部的节点就启动了然后准备缓存数据,也可以从控制台执行如下命令来启动额外的独立的节点:

  1. $IGNITE_HOME/bin/ignite.sh my-config-folder/my-ignite-configuration.xml

对于Windows,可以执行同一文件夹下的.bat脚本。

节点也可以在其他主机上启动,以形成一个分布式的缓存集群,一定要确保在配置文件中指定正确的网络参数。

8.1.3.查询缓存

除了二级缓存,Hibernate还提供了查询缓存,这个缓存存储了通过指定参数集进行查询的结果(或者是HQL或者是Criteria),因此,当重复用同样的参数集进行查询时,他会命中缓存而不会去访问数据库。
查询缓存对于反复用同样的参数集进行查询时是有用的。像二级缓存的场景一样,Hibernate依赖于一个第三方的缓存实现,Ignite也可以这样用。

要考虑Ignite中对于基于SQL的内存内查询的支持,他会比通过Hibernate性能更好。

8.1.4.查询缓存配置

上面的配置信息完全适用于查询缓存,但是额外的配置和代码变更还是必要的。
Hibernate配置
要在Hibernate种启用查询缓存,只需要在配置文件中添加额外的一行:

  1. <!-- Enable query cache. -->
  2. <property name="cache.use_query_cache">true</property>

然后,需要对代码做出修改,对于要缓存的每一个查询,都需要通过调用setCacheable(true)来开启cacheable标志。

  1. Session ses = ...;
  2. // Create Criteria query.
  3. Criteria criteria = ses.createCriteria(cls);
  4. // Enable cacheable flag.
  5. criteria.setCacheable(true);
  6. ...

这个完成之后,查询结果就会被缓存了。
Ignite配置
要在Ignite中开启Hibernate查询缓存,需要指定一个额外的缓存配置:

  1. <property name="cacheConfiguration">
  2. <list>
  3. ...
  4. <!-- Query cache (refers to atomic cache defined in above example). -->
  5. <bean parent="atomic-cache">
  6. <property name="name" value="org.hibernate.cache.internal.StandardQueryCache"/>
  7. </bean>
  8. </list>
  9. </property>

注意为了更好的性能缓存配置为原子化的。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注