Hibernate Search(基于version3.4)--第二章Archetype

Archetype

 

2.1概述

Hibernate Search由建立索引和索引搜索两个组件组成,并且都是基于Apache Lucene。

 

每次一个实体从数据库中被插入,更新或移除,Hibernate Search会跟踪这些事件并维护index的更新。所有index更新工作都会由Hibernate Search完成而不需要你去使用Lucene API。

 

为了与Lucene的index交互,Hibernate Search有一个DirectoryProvider的概念。DirectoryProvider会管理Lucene中的Directory类型。你可以配置DirectoryProvider来调整Directory的类型。

 

Hibernate Search通过Lucene Index来搜索实体,返回持久化的实体列表,这样你就不需要花时间把对象映射到Lucene document的工作。另外,Hibernate和Hibernate Search之间持久化上下文是共享的。事实上,FullTextSession是基于Hibernate Session建立的,因此在应用中可以使用统一的org.hibernate.Query 或 javax.persistence.Query API,如通过HQL,JPAQL或本地查询。

 

为了得到更好性能,Hibernate Search捆绑了Lucene Index写操作。当前有两种的捆绑方式,第一种是没有事务处理的,index更新操作是在实际的数据库操作之后进行。另一种是在运行中的事务中,index的更新操作是在事务的提交阶段,当事务回滚时放弃更新。这个捆绑范围是基于事务。这有两处好处:

  • 性能更好:当操作是在捆绑中运行,Lucene的indexing能工作得更好。
  • ACID:工作的过程与数据库的事务捆绑在一起,仅当事务提交时工作才会被执行。严格来说,这并不是ACID,但ACID对于全文搜索来说并不是很有用的,因为index可以通过数据源重建。

你可以这样理解两种捆绑模式(no scope vs transactional),它们就好像是auto commit vs transactional的表现一样。从性能的角度来看,推荐使用基于事务的模式。no scope模式是透明,Hibernate Search会探测当前的事务并调整范围。

 

Tip:It is recommended - for both your database and Hibernate Search - to execute your operations in a transaction, be it JDBC or JTA.

 

Note:Hibernate Search works perfectly fine in the Hibernate / EntityManager long conversation pattern aka. atomic conversation.

 

Note:Depending on user demand, additional scoping will be considered, the pluggability mechanism being already in place.

 

2.2后端

Hibernate Search可以让批处理工作交给不同的后端来处理。Hibernate Search提供了三种开箱即用的后端,你可以选择去嵌入到你的实现中。

 

2.2.1后端类型

2.2.1.1 Lucene

在这种模式下,所有的index更新操作会应用到同一个index。这种模式的index是共享的并要小心地处理锁操作,可以应用于集群环境或非集群环境。这种模式的优点是简单并在查询时可以立即看到改变。

 

2.2.1.2 JMS

所有的index更新操作会把更新操作的命令发送到JMS队列。一个唯一的reader会处理JMS队列并更新主index。之后,主index将会被复制到各个从index。这就是众所周知的主/从模式。主方唯一的责任是维护index的更新,从方可以接受写和读的操作。然而从方只会对本地index进行读操作,而把写操作委托给主方。

这种模式面向的是集群环境,并有很高的吞吐量,而且可以接受index的延迟更新。可靠性由JMS provider和本地的index副本来确保。

 

2.2.1.3 JGroup

JGroups工作模式与JMS相似,也同样设计成主/从模式。不同的是,JGroup使用自身的工具包完成复制工作。当对响应时间要求比较严格时,考虑使用JGroup模式,不过不支持JNDI服务。

 

2.2.2建立索引工作的运行

indexing可以运行在事务提交的同步方式,或异步方式。

 

2.2.2.1同步方式

这是一种安全的,因为indexing与事务提交相一致。在高并发环境中,这会限制了应用的吞吐量(由于Lucene的锁机制),如果后端运行比事务处理更慢或有大量的IO操作的话,这将增加系统的响应时间。

 

2.2.2.2异步方式

这种方式后端委托indexing工作由不同的线程来完成。这样的话,吞吐量与响应时间将与后端的性能无关。该方式的缺点是在事务提交后,index更新操作会有一些延时,并要花一点开销来管理线程。

 

推荐先使用同步方式,当因为同步方式而出现性能问题时再应用异步方式。

 

2.3Reader strategy

当执行一个查询,Hibernate Search与Lucene index交互是通过reader strategy。选择怎么样的reader strategy依赖于应用的实际情况(经常更新,多数情况只读,异步方式更新index)。

 

2.3.1Shared策略

这种策略下,Hibernate Search将共享同一个IndexReader,不管是不同的查询(query)还是不同的线程,都会保持IndexReader up-to-date。IndexReader由多个SegmentReader组成。这种策略只会重新打开修改过的或新生成的segment,那些没修改过的segment将会重用。

 

2.3.2 Not-shared策略

每执行一次查询,便重新生成一次IndexReader,这种策略是低效的,因为打开一次IndexReader是相当大的资源消耗。

 

2.3.3 Custom

你自定义一个reader strategy通过实现org.hibernate.search.reader.ReaderProvider。这个实现必须是线程安全的。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2013-04-30 15:17  眉间尺之魂  阅读(264)  评论(0编辑  收藏  举报