Hibernate Search(基于version3.4)--第三章Configuration

Configuration

 

3.1激活Hiberate Search与自动indexing功能

3.1.1激活Hibernate Search

Hibernate Core会自动探测是否应用激活Hibernate Search。如果想禁用Hibernate Search,把hibernate.search.autoregister_listeners配置为false。当然,即使hibernate.search.autoregister_listeners配置为true,但是没有任何一个实体被注解为@Indexed,Hibernate Search也不会运行任何东西。

 

3.1.2激活自动indexing

默认情况下,每次一个持久对象被插入,更新,删除通过hibernate,Hibernate Search都会更新index。当index是只读或批量更新index的时候,你可能想要禁用该功能。

 

禁用基于事件的indexing:

hibernate.search.indexing_strategy = manual

Note :在大多数情况下,JMS后端提供了最好解决方案,一个轻量级的基于事件系统保持跟踪index的所有的改变,和重量级的indexing处理由独立的机器完成。

 

3.2Directory的配置

在配置Directory之前,你需要明白每一个indexed实体对应着一个Lucene index(除了多个indexed实体对应相同的index)。index的名称由@Indexed注解中的index属性指定,如果没有index属性,默认为类的全限定名。

 

根据index的名称,使用前缀hibernate.search.<indexname>. 可以为每个index配置不同的DirectoryProvider和配置其他不同的属性。另外hibernate.search.default. 是保留名,用于定义所有index的默认属性。Example 3.2, “Configuring directory providers” 展示了怎么样使用hibernate.search.default.directory_provider去设置默认的directory provider为filesystem,设置hibernate.search.default.indexBase为默认的index基本目录。Rule的index使用了in-memory directory,因为默认的DirectoryProvider被hibernate.search.Rules.directory_provider覆盖了。

 

Example 3.1. Specifying the index name

package org.hibernate.example;
@Indexed
public class Status { ... }
@Indexed(index="Rules")
public class Rule { ... }
@Indexed(index="Actions")
public class Action { ... }

 Example 3.2. Configuring directory providers

hibernate.search.default.directory_provider filesystem
hibernate.search.default.indexBase=/usr/lucene/indexes
hibernate.search.Rules.directory_provider ram
hibernate.search.Actions.directory_provider com.acme.hibernate.CustomDirectoryProvider

 Tip :通过这种配置规则,可以很容易的为每个不同的index配置属性。

 

Table 3.1. List of built-in DirectoryProviders

Class or shortcut nameDescriptionProperties
ramDirectory基于缓存,该Directory只能应用于唯一的index名称。也就是说该Directory不能在同一应用中使用两次none
filesystem基于文件系统的Directory,index所在地址为<indexBase>/< indexName >

indexBase:index所在目录

indexName:覆盖@Indexed.index属性

locking_strategy:可选(看3.11)

filesystem_access_type:可以精确地指定DirectoryProvider所使用的FSDirectory的实现类。可选值为:auto,simple(SimpleFSDirectory),nio(NIOFSDirectory),mmap(MMapDirectory)

 filesystem-master

类似于filesystem,但它还定期地复制index到source directory。

 

refresh的推荐值为150%的复制index的时间。

 

复制操作是在原来index副本的基础上复制的,因此可以减少复制的时间。

 

DirectoryProvider一般用在JMS后端的master节点

indexBase:同filesystem

indexName:同filesystem

sourceBase:Source (copy) base directory

source:source directory的尾缀,默认是@Indexed.index,实际的source directory为<sourceBase>/<source>

refresh:定义副本隔多长时间复制一次,默认为3600s

buffer_size_on_copy:用于复制副本所用的缓存。默认为16MB

locking_strategy:同filesystem

filesystem_access_type:同filesystem

filesystem-slave

类似于filesystem,但定期地复制master端的source,为了避免锁和不一致性,在本地保留2份copy。

 

retry_marker_lookup:定义在失败前访问source directory中的marker file的次数,每次访问间隔是5秒。default是0。

retry_initialize_period:设置间隔去重试初始化index。

其他属性与filesystem-master一样

infinispan

基于infinispan的directory。保存index在一个分布式的网格,使得集群中的所有机器可以很快的看到index的改变。

Section 3.8, “Infinispan Directory configuration” 有一些额外的要求和配置。

locking_cachename: name of the Infinispan cache to use to store locks.

data_cachename : name of the Infinispan cache to use to store the largest data chunks; this area will contain the largest objects, use replication if you have enough memory or switch to distribution.

metadata_cachename: name of the Infinispan cache to use to store the metadata relating to the index; this data is rather small and read very often,it's recommended to have this cache setup using replication.

chunk_size: large files of the index are split in smaller chunks, you might want to set the highest value efficiently handled by your network.Networking tuning might be useful.

 

 

 

 

3.3分割索引(Sharding Indexes)

当遇到下面两种情形的时候,你可能需要分割索引

  • 当索引文件比较巨大,而导致在索引文件更新的时候使应用变慢。
  • 当只需要搜索索引文件的一个子集的时候,比如索引文件按用户,地区等来划分成不同的片段。

Warning :一般情况下,不推荐使用分割索引,因为在搜索时,应用需要为每个片段打开一个Search。

 

默认情况下,分割索引是不可用的,除非配置了属性 hibernate.search.<indexName>.sharding_strategy.nbr_of_shards 。如Example 3.3, “Enabling index sharding”所示:

 

Example 3.3. Enabling index sharding

hibernate.search.<indexName>.sharding_strategy.nbr_of_shards=5
 

负责分割索引的接口是IndexShardingStrategy。默认的sharding strategy是根据id字符串的哈希值(由FieldBridge生成)来分割的。你也可以实现自己的IndexShardingStrategy来覆盖默认的sharding strategy。如Example 3.4. Specifying a custom sharding strategy所示配置自定义IndexShardingStrategy。

hibernate.search.<indexName>.sharding_strategy=my.shardingstrategy.Implementation

IndexShardingStrategy可以通过过滤索引片段来优化搜索。通过激活一个过滤器 (see Section 5.3.1, “Using filters in a sharded environment”),sharding strategy可以选择一个索引片段子集来完成搜索从而加快搜索速度。

 

因此,每个索引片段都可以有一个独立的directory provider的配置。假设有一个index名称是Animal,那么分割该index成5个片段后,每个片段的名字就为Animal.0 to Animal.4。如下例Example 3.5, “Sharding configuration for entity Animal”

 

Example 3.5. Sharding configuration for entity Animal

hibernate.search.default.indexBase=/usr/lucene/indexes
hibernate.search.Animal.sharding_strategy.nbr_of_shards=5
hibernate.search.Animal.directory_provider=filesystem
hibernate.search.Animal.0.indexName=Animal00
hibernate.search.Animal.3.indexBase=/usr/lucene/sharded
hibernate.search.Animal.3.indexName=Animal03

 

在Example 3.5中,配置使用默认的id字符串哈希值分割策略把Animal索引分割成5个索引片段,所有的片段的DirectoryProvider都是filesystem。每个片段保存在如下所示的路径下:

  • 片段0:/usr/lucene/indexes/Animal00(默认的indexBase,覆盖默认的indexName)
  • 片段1: /usr/lucene/indexes/Animal.1(默认的indexBase,默认的indexName)
  • 片段2: /usr/lucene/indexes/Animal.2(默认的indexBase,默认的indexName)
  • 片段3:/usr/lucene/shared/Animal03(覆盖默认的indexBase,默认的indexName)
  • 片段4: /usr/lucene/indexes/Animal.4(默认的indexBase,默认的indexName)

 

3.4共享索引(Sharing indexes)

Sharing indexes可以把不同的实体索引合并到一个单独的Lucene Index文件中。有两种方式达到这个目的:

  • 配置DirectoryProvider指向相同的物理目录,然后配置实体索引的indexName为索引文件的名称。如
    hibernate.search.org.hibernate.search.test.shards.Furniture.indexName = Animal
    hibernate.search.org.hibernate.search.test.shards.Animal.indexName = Animal
     
  • 设置@Indexed的index属性为索引文件的名称。如希望Furniture和Animal实体都合并到名字为Animal的索引文件中,那么只需要在Furniture和Animal的类级别上添加注解@Indexed(index="Animal")

Note :Sharing indexes并没有太多的好处,只是一种可选的方式来管理索引文件。

 

 

3.5工作者配置(Worker configuration)

通过Worker configuration可以调整Hibernate Search与Lucene的交互。这里有有个Worker接口,Worker接口的实现负责获取所有实体的改变,把这些改变排成队列,并在上下文结束的时候应用这些改变。大多数的上下文范围,特别是ORM的连接方式,都是事务的。基于这个原因,Hibernate Search默认使用 TransactionalWorker去限定改变的范围为每一个事务处理。但也可能有这样的情景,上下文依赖于实体改变的数量或其他一些应用的生命周期事件。Worker的实现可以参考Table 3.2, “Scope configuration”.来配置。

 

Table 3.2. Scope configuration

PropertyDescription
hibernate.search.worker.scopeWorker实现类的全限定名。默认TransactionalWorker
hibernate.search.worker.*Worker实现类的属性配置。*为具体的属性名。
hibernate.search.worker.batch_size定义每个上下文indexing操作数的最大值。不管上下文是否结束,只要操作数大于这个值,将会触发indexing  work。这个属性只有在Worker的实现类委托queue  work给BatchedQueueingProcessor(TransactionalWorker就是这样的一个Worker)

 

 

 

当上下文结束,就会把实体类的改变应用到index中去。这个过程可以是同步的,也可以是通过新线程来异步处理。同步更新方式的好处是可以保证index与数据库在任何时刻保持一致,但响应时间相对异步更新方式较长。异步更新方式的优点是响应时间非常的短,但并不能保证数据库与index的一致性。Table 3.3,“Execution configuration”展示了有关运行方式的配置选项。

 

Table 3.3. Execution configuration

PropertyDescription
hibernate.search.worker.execution

sync:同步运行方式(默认)

async:异步运行方式

hibernate.search.worker.thread_pool.size定义在异步运行方式下,线程池中的线程数量
hibernate.search.worker.buffer_queue.max只在异步运行方式下有效。定义work queue的最大值。默认是infinite。如果达到上限,work会由主线程完成

 

 

 

到目前为止,不管使用哪种运行方式,所有的work都是由相同的,单独的Virtual Machine (VM)完成。幸运的是有一种更好的方法——委托。这个方法通过配置hibernate.search.worker.backend属性,把indexing work委托给另一个server完成。 see Table 3.4, “Backend configuration”.

 

Table 3.4. Backend configuration

PropertyDescription
hibernate.search.worker.backend

lucene:默认的backend。运行indexing work在同一个VM。

 

jms:JMS backend。index update的操作命令发送给JMS queue,indexing master根据JMS queue的命令更新index。See  Table 3.5, “JMS backend configuration” for additional configuration options and  Section 3.6, “JMS Master/Slave configuration” for a more detailed descripton of this setup.

 

jgroupsMaster or  jgroupsSlave:backend使用JGroups[http://www.jgroups.org/]作为通信层。See  Table 3.6, “JGroups backend configuration” for additional configuration options and Section 3.7,“JGroups Master/Slave configuration” for a more detailed description of this setup

 

blackhole:主要用在测试/开发阶段,可以忽略所有indexing work。

 

也可以指定一个实现了BackendQueueProcessorFactory的类(全限定名)。通过这种方式实现了自己的通信层。这个实现的责任是返回一个能完成indexing work的Runnable实例。

 

 

Table 3.5. JMS backend configuration

PropertyDescription
hibernate.search.worker.jndi.*定义JNDI属性来初始化InitialContext(如果有必要的话)。JNDI只在JMS有用。
hibernate.search.worker.jms.connection_factoryrequired。定义JNDI名称查找JMS connection factory。默认“/ConnectionFactory”如JBoss AS所说一样。
hibernate.search.worker.jms.queuerequired。定义JNDI名称查找JMS queue。该queue用于发送work messages。

 

 

Table 3.6. JGroups backend configuration

PropertyDescription
hibernate.search.worker.jgroups.clusterNameOptional for JGroups back end. Defines the
name of JGroups channel.
hibernate.search.worker.jgroups.configurationFileOptional JGroups network stack configuration.
Defines the name of a JGroups configuration
file, which must exist on classpath
hibernate.search.worker.jgroups.configurationXmlOptional JGroups network stack configuration.
Defines a String representing JGroups
configuration as XML.
hibernate.search.worker.jgroups.configurationStringOptional JGroups network stack configuration.
Provides JGroups configuration in plain text.

 

Warning :你可以看到,上面配置的属性有些相互间是有关联的,因此有些属性的组合是毫无意义的。这就要求你去掉那些无用的属性配置。另外,在写自定义的BackendQueueProcessorFactory之前,务必先学习已有实现类的源码。

 

3.6. JMS Master/Slave configuration

这一节会更详细地介绍怎么样去配置主/从结构的Hibernate Search architecture。

JMS back end configuration.

 

3.6.1.从节点的配置(Slave nodes)

每次index更新操作都会发送给JMS queue。搜索操作是基于本地的index copy。

 

Example 3.6. JMS Slave configuration

### slave configuration

## DirectoryProvider
# (remote) master location
hibernate.search.default.sourceBase = /mnt/mastervolume/lucenedirs/mastercopy

# local copy location
hibernate.search.default.indexBase = /Users/prod/lucenedirs

# refresh every half hour
hibernate.search.default.refresh = 1800

# appropriate directory provider
hibernate.search.default.directory_provider = filesystem-slave

## Backend configuration
hibernate.search.worker.backend = jms
hibernate.search.worker.jms.connection_factory = /ConnectionFactory
hibernate.search.worker.jms.queue = queue/hibernatesearch
#optional jndi configuration (check your JMS provider for more information)

## Optional asynchronous execution strategy
# hibernate.search.worker.execution = async
# hibernate.search.worker.thread_pool.size = 2
# hibernate.search.worker.buffer_queue.max = 50
 

 

Tip :推荐在从节点本地保存一份index copy来提高Search性能。

 

Tip :刷新间隔应该长于复制的时间。

 

3.6.2. 主节点配置(Master node)

主节点从JMS queue获取index update操作命令并更新index。主节点的index会定期地被复制一个副本。

 

Example 3.7. JMS Master configuration

### master configuration

## DirectoryProvider
# (remote) master location where information is copied to
hibernate.search.default.sourceBase = /mnt/mastervolume/lucenedirs/mastercopy

# local master location
hibernate.search.default.indexBase = /Users/prod/lucenedirs

# refresh every half hour
hibernate.search.default.refresh = 1800

# appropriate directory provider
hibernate.search.default.directory_provider = filesystem-master

## Backend configuration
#Backend is the default lucene one
 

除了Hibernate Search framework的配置之外,还需要写一个Message Driven Bean,并由他来处理来自JMS的indexing work queue。

 

Example 3.8. Message Driven Bean processing the indexing queue

 

@MessageDriven(activationConfig = {
      @ActivationConfigProperty(propertyName="destinationType", 
                                propertyValue="javax.jms.Queue"),
      @ActivationConfigProperty(propertyName="destination", 
                                propertyValue="queue/hibernatesearch"),
      @ActivationConfigProperty(propertyName="DLQMaxResent", propertyValue="1")
   } )
public class MDBSearchController extends AbstractJMSHibernateSearchController 
                                 implements MessageListener {
    @PersistenceContext EntityManager em;
    
    //method retrieving the appropriate session
    protected Session getSession() {
        return (Session) em.getDelegate();
    }

    //potentially close the session opened in #getSession(), not needed here
    protected void cleanSessionIfNeeded(Session session) 
    }
}
 

 

这个的例子的MDBSearchController继承了Hibernate Search的 AbstractJMSHibernateSearchController(一个抽象的JMS控制类,该类还实现了JavaEE 5 MDB)。该实现只是一个样例,它还可以调整成不需要用到JavaEE MDB(更多信息请看AbstractJMSHibernateSearchController的javadoc关于getSession() 和cleanSessionIfNeeded()方法的说明)

 

3.7.JGroups的主/从 结构的配置(JGroups Master/Slave configuration)

本节将介绍怎样去配置JGroups的 主/从 结构backend。本节的配置与3.6节 “JMS Master/Slave configuration”的配置是一样的,唯一的不同是hibernate.search.worker.backend属性的配置

 

3.7.1.从节点配置(Slave nodes)

每一次的index update操作会经由JGroups channel发送给主节点。搜索操作是基于本地的index copy上进行的。

 

Example 3.9. JGroups Slave configuration

### slave configuration
hibernate.search.worker.backend = jgroupsSlave 
 

3.7.2. 主节点配置(Master node)

主节点从JGroups channel获取index update操作命令并更新index。主节点的index会定期复制一份副本。

 

Example 3.10. JGroups Master configuration

### master configuration
hibernate.search.worker.backend = jgroupsMaster
 

 

3.7.3. JGroups channel的配置(JGroups channel configuration)

JGroups传输协议配置是可选的,并且channel name可以被定义和应用到主/从节点。有三种方式定义JGroups传输协议:

  • 设置hibernate.search.worker.backend.jgroups.configurationFile属性并指定一个文件包含有JGroups传输协议配置。
  • 通过hibernate.search.worker.backend.jgroups.configurationXml属性直接嵌入JGroups传输协议的xml配置到Hibernate configuration file
  • 通过hibernate.search.worker.backend.jgroups.configurationString属性直接嵌入JGroups传输协议的字符串配置到Hibernate configuration file

Tip :如果没有任何的JGroups传输协议配置被指定,默认使用 flush-udp.xml配置文件。

 

Example 3.11. JGroups transport protocol configuration

## JGroups configuration options
# OPTION 1 - udp.xml file needs to be located in the classpath
hibernate.search.worker.backend.jgroups.configurationFile = udp.xml

# OPTION 2 - protocol stack configuration provided in XML format
hibernate.search.worker.backend.jgroups.configurationXml =
<config xmlns="urn:org:jgroups"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:org:jgroups file:schema/JGroups-2.8.xsd">
<UDP
mcast_addr="${jgroups.udp.mcast_addr:228.10.10.10}"
mcast_port="${jgroups.udp.mcast_port:45588}"
tos="8"
thread_naming_pattern="pl"
thread_pool.enabled="true"
thread_pool.min_threads="2"
thread_pool.max_threads="8"
thread_pool.keep_alive_time="5000"
thread_pool.queue_enabled="false"
thread_pool.queue_max_size="100"
thread_pool.rejection_policy="Run"/>
<PING timeout="1000" num_initial_members="3"/>
<MERGE2 max_interval="30000" min_interval="10000"/>
<FD_SOCK/>
<FD timeout="3000" max_tries="3"/>
<VERIFY_SUSPECT timeout="1500"/>
<pbcast.STREAMING_STATE_TRANSFER/>
<pbcast.FLUSH timeout="0"/>
</config>

# OPTION 3 - protocol stack configuration provided in "old style" jgroups format
hibernate.search.worker.backend.jgroups.configurationString =

UDP(mcast_addr=228.1.2.3;mcast_port=45566;ip_ttl=32):PING(timeout=3000;
num_initial_members=6):FD(timeout=5000):VERIFY_SUSPECT(timeout=1500):
pbcast.NAKACK(gc_lag=10;retransmit_timeout=3000):UNICAST(timeout=5000):
FRAG:pbcast.GMS(join_timeout=3000;shun=false;print_local_addr=true)
 

JGroups的主/从节点是通过JGroups channel通信的。默认的channel name是HSearchCluster。也可以像Example 3.12,“JGroups channel name configuration”.一样修改。

 

Example 3.12. JGroups channel name configuration

hibernate.search.worker.backend.jgroups.clusterName = Hibernate-Search-Cluster 
 

3.8.Infinispan Directory配置(Infinispan Directory configuration)

Infinispan是一个分布式的,规模可变的(scalable),高度可用的数据网格平台,它支持自动检测平等节点。当把Infinispan与Hibernate Search组合起来,这样就可以在分布式环境下保存Lucene index并且各个节点的index更新得很快。

 

本节会更详细地介绍怎样在Hibernate Search上应用Infinispan Directory。

 

使用Infinispan Directory时,index是保存在内存中,并与各个节点共享这个index。可以看作是所有节点所共有的一个单独的Directory。如果一个节点更新了index,其他的节点的index也已经被更新了,所以在一个节点上的所有更新,集群中的其他节点也会搜索到这些更新。

 

默认的配置是把所有的index数据复制到各个节点上,这无疑要消耗大量的内存。对于体积大的index来说,它应该使用数据分布式结构,由集群中的各个成员保存index的一部分数据。

 

也可以释放一部分的数据到CacheStore,像普通的文件系统,Amazon S3, Cassandra, Berkley DB或关系型数据库。你可以在每个节点上配置一个CacheStore,或集中到一个单独的CacheStore由所有的节点共享。

 

要查看更详细的配置信息请查看Infinispan文档[http://www.jboss.org/infinispan/]

 

3.8.1. 要求(Requirements)

Infinispan要求使用java6和最新版的JGroups。要应用Infinispan directory需要在Maven上添加以下依赖。

 

Example 3.13. Maven dependencies for Hibernate Search

<dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-search</artifactId>
   <version>3.4.0.Final</version>
</dependency>
<dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-search-infinispan</artifactId>
   <version>3.4.0.Final</version>
</dependency>
 

对于非Maven的用户来说,添加hibernate-search-infinispan.jar,  infinispan-lucene-directory.jar和infinispan-core.jar到应用的classpath。后面两个jar文件是由Infinispan[http://sourceforge.net/projects/infinispan/files/]发布的。同样也需要updated JGroups版本满足Infinispan的需要。

 

3.8.2. Architecture

即使使用了Infinispan directory,但还是推荐使用JMS Master/Slave或JGroups backend,因为所有的节点会使用同一个index,这样的话每个节点的IndexWriter都会尝试去获取同一个index的锁。因此通过发送更新操作给JMS queue或JGroups channel,代替直接应用更新到index,从而可以用其中一个从节点代表所有的节点来更新index。

 

并不是强制要求配置一个非默认的backend,但可以改善应用的性能,因为只有一个节点需要进行写操作。

 

配置JMS从节点只需要修改backend并把DirectoryProvider设为infinispan。在主节点也应设为infinispan,这样主/从节点间就不再需要安排复制的工作也能连接起来。使用JGroups backend也是一样,把DirectoryProvider配置为infinispan和backend的配置组织起来就可以了。

 

 

3.8.3. Infinispan Configuration

该配置很简单,只需要激活backend:

hibernate.search.default.directory_provider=infinispan

 配置了上面的属性就可以得到了一个集群复制(cluster-replicated)的index,但默认的配置并不到保证index的持久性。要解决这个问题还需要一个infinispan的配置文件。

 

要使用infinispan,Hibernate Search需要一个CacheManager,它可以通过JNDI查找和重用一个已经存在的CacheManager,或新建和管理一个新的CacheManager。在后一种情况,CacheManager由Hibernate Search管理它的开始和结束(当SessionFactory关闭的时候关闭)

 

通过JNDI使用已存在的 CacheManager(可选的):

hibernate.search.infinispan.cachemanager_jndiname = [jndiname]

通过一个配置文件开启一个新的CacheManager(可选的):

hibernate.search.infinispan.configuration_resourcename = [infinispan configuration filename]
 

如果两个属性都有配置的话,会优先使用JNDI的配置。如果两个属性都没有配置,Hibernate Search会使用保存在hibernate-search-infinispan.jar中的默认的Infinispan配置。默认配置能满足大部分的需要,但不能保存index在持久的cache store。

 

如Table 3.1, “List of built-in DirectoryProviders”提到的,每个index有三种不同的存储区,需要为hibernate-search-infinispan.jar中的hibernatesearch-infinispan.xml配置这三种不同的存储区。多个不同的index可以共用同一个存储区。

 

Warning :在Infinispan中使用JGroups,要求JVM属性java.net.preferIPv4Stack设置为true。即-Djava.net.preferIPv4Stack=true

 

3.9. Reader strategy配置(Reader strategy configuration)

在2.3节中已经介绍过两种不同的reader strategy:

  • shared:多次查询共用相同的IndexReader。这种策略是高效的。
  • not-shared:每次查询都会打开一个新的IndexReader。

默认的reader strategy是shared。它也可以通过下面的属性修改:

hibernate.search.reader.strategy = not-shared

 

或使用一个自定义的reader strategy:

#my.corp.myapp.CustomReaderProvider是一个自定义的reader strategy实现。
hibernate.search.reader.strategy = my.corp.myapp.CustomReaderProvider
 

 

3.10. 调整Lucene的indexing性能(Tuning Lucene indexing performance)

Hibernate Search可以通过指定一系列的参数来调整Lucene的indexing性能,实际上,是把这些参数赋值到底层的Lucene IndexWriter,比如参数 mergeFactor,maxMergeDocs和maxBufferedDocs。你可以配置所有index的默认参数,或具体index的参数,甚至是具体的index shard。

 

根据实际情况而定,有两个集合的参数用于不同的性能设置:

  • 如果indexing操作是由数据库的修改来触发的,参数由关键字transaction分组。如
    hibernate.search.[default|<indexname>].indexwriter.transaction.<parameter_name>
     
  • 如果indexing操作发生在FullTextSession.index()或MassIndexer(see Section 6.3,“Rebuilding the whole index”),参数由关键字batch分组
    hibernate.search.[default|<indexname>].indexwriter.batch.<parameter_name>
     

如果没有index shard的配置,Hibernate Search就会应用index的配置,如果也没有对应的index配置,便应用default配置。

 

Example 3.14. Example performance option configuration

hibernate.search.Animals.2.indexwriter.transaction.max_merge_docs=10
hibernate.search.Animals.2.indexwriter.transaction.merge_factor=20
hibernate.search.default.indexwriter.batch.max_merge_docs=100

上面的例子中,Animal的第二个index shard的实际配置如下:

  • transaction.max_merge_docs = 10
  • batch.max_merge_docs = 100
  • transaction.merge_factor = 20
  • 其它使用Lucene里设定的默认值

 Table 3.7,“List of indexing performance and behavior properties”展示了各种调整参数,但这些参数依赖于lucene版本。表中所示的参数对应Lucene2.4

PropertyDescriptionDefault Value
hibernate.search.[default|<indexname>].exclusive_index_use如果此index没有其他线程的并发写操作,应设为true,这样Hibernate Search对该index运行在exclusive mode模式,从而改善indexing update的性能。false
hibernate.search.[default|<indexname>].max_queue_length每个index有一个独自的“pipeline”,pipeline包含了要应用到index的所有更新。当该queue到达了最大长度,就变成了阻塞操作。一般配置这个参数没有太大的意义,除非worker.execution配置为async。1000
hibernate.search.[default|<indexname>].indexwriter.[transaction|batch].max_buffered_delete_terms决定在刷新缓存中的delete terms所需要的delete terms的最小值。如果同时有documents在缓存中,它们会被整合和创建一个新的segment。Disabled (flushes by RAM usage)
hibernate.search.[default|<indexname>].indexwriter.[transaction|batch].max_buffered_docs控制在indexing期间缓存document的数量。值越大,内存消耗越大。Disabled (flushes by RAM usage)
hibernate.search.[default|<indexname>].indexwriter.[transaction|batch].max_merge_docs定义一个segment允许包含document的最大值。值越大有利于batched indexing和提高搜索速度。值越小对transaction indexing越有利。Unlimited
(Integer.MAX_VALUE)
hibernate.search.[default|<indexname>].indexwriter.[transaction|batch].merge_factor控制segment merge的频率和大小。定义了当发生插入操作,多久一次segment indexes整合。值越小,在indexing时消耗的内在越小,搜索会更快,但indexing的速度会慢些。值越大则相反。值>10有利于batch index的创建,值<10是交互式维护(interactively maintained)。该值必须大于2。10
hibernate.search.[default|<indexname>].indexwriter.[transaction|batch].ram_buffer_size定义用于缓存document的内存的使用量。如果也同时配置了max_buffered_docs,会优先使用max_buffered_docs刷新缓存。一般来说,为了有更好的indexing性能,一般使用ram_buffer_size配置而不是max_buffered_docs,如果可以的话提高ram_buffer_size也能提高一定的性能。16MB
hibernate.search.[default|<indexname>].indexwriter.[transaction|
batch].term_index_interval
专家:定义term之间的间隔。值越大,可以减少IndexReader的内存消耗,但会降低随机访问term的速度。值越小,则相反。128
hibernate.search.[default|<indexname>].indexwriter.[transaction|
batch].use_compound_file
使用组合文件格式的好处是减少描述文件。缺点是indexing将花费更长的时间和临时硬盘空间。true
hibernate.search.enable_dirty_check并不是所有的实体改变都要更新index。如果所有的修改过的实体属性(脏属性)并没有实际上的改变,Hibernate Search将跳过reindexing work。如果你使用了自定义的FieldBridge,应该禁用该参数,因为FieldBridge是在每次更新时被调用即使FieldBridge没有改变。该参数也不能应用于带@ClassBridge或@DynamicBoost注解的类。true

 

 

Tip :如果应用结构允许的话,使用hibernate.search.default.exclusive_index_use=true将大幅度地提高index writing。

 

Tip :为了调试indexing速度,将从数据库提取对象与写对象到index相隔离显示非常有用。要达到这个目的,可以设置worker backend为blackhole并运行indexing程序。 blackhole backend并没有禁用Hibernate Search,它会生成必需要的改变集(changesets)到index,但不会刷新缓存到index。相对于设置hibernate.search.indexing_strategy=manual,使用blackhole可能会从数据库中导出更多的数据,因为相关联的实体也会reindexed。推荐的方法是先把焦点放在对象加载优化上(从数据库),然后再调节indexing。

 

Warning :blackhole不应该应用在产品阶段,它只是一个工具去鉴别indexing的瓶颈。

 

3.11. LockFactory配置(LockFactory configuration)

Lucene的Directory有默认的锁策略,这些策略在大多数情况下工作得很好。在Hibernate Search中,你可以为每个index指定LockFactory来管理锁。有些锁策略要求一个filesystem级别的锁,甚至可以用在基于内存的index,但这是不推荐的而且没有什么用途的。

 

通过hibernate.search.<index>.locking_strategy属性可以设置LockFactory,有4个开箱即用的选项:simple,  native,  single 或 none 。另外还可以设置org.hibernate.search.store.LockFactoryFactory的一个实现类的全限定名。

 

Table 3.8. List of available LockFactory implementations

nameClassDescription
simpleorg.apache.lucene.store.SimpleFSLockFactory

基于Java File API的安全实现,它创建一个标志文件来标识一个index已经在使用。

 

如果有需要的话,你可以删除这个锁文件。

 

filesystem,  filesystem-master和filesystem-slave这三个DirectoryProvider的默认锁就是simple。

nativeorg.apache.lucene.store.NativeFSLockFactory

像simple锁策略一样, 也是通过创建一个标志文件来标识一个index已经在使用。但该文件是使用本地OS文件,所有即使应用崩溃,锁也能被清除。

该锁在NFS中是有问题的。

singleorg.apache.lucene.store.SingleInstanceLockFactory

这个LockFactory不会使用一个标志文件,而是一个保存在内存中的Java锁对象,因此,这个LockFactory只用在单线程中。ram DirectoryProvider默认使用这个锁策略

noneorg.apache.lucene.store.NoLockFactory不应用任何的锁策略。

 

 

配置样例:

hibernate.search.default.locking_strategy=simple
hibernate.search.Animals.locking_strategy=native
hibernate.search.Books.locking_strategy=org.custom.components.MyLockingFactory
 

3.12. 异常管理配置(Exception Handling Configuration)

Hibernate Search允许配置怎么处理indexing过程中出现的异常。如果不提供任何的异常配置,异常会通过log记录并打印出来。也可以通过下面方式明确的声明logging机制:

hibernate.search.error_handler=log

 

默认的异常处理可以同时作用于同步或异步运行方式。Hibernate Search提供了一个简单的机制来重写默认的异常处理器。自定义异常处理器必须实现ErrorHandler接口,该接口要求实现handle(ErrorContext context)方法。ErrorContext提供了一个LuceneWork实例的引用,底层的异常和并发的LuceneWork实例是不可以被处理的。

 

public interface ErrorContext  {
   List<LuceneWork> getFailingOperations();
   LuceneWork getOperationAtFault();
   Throwable getThrowable();
   boolean hasErrors();
}
 

 

在Hibernate Search中注册异常处理器(全限定名):

hibernate.search.error_handler=CustomerErrorHandler
 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值