Java Amazon上的Hibernate搜索问题

Java Amazon上的Hibernate搜索问题,java,hibernate,lucene,hibernate-search,Java,Hibernate,Lucene,Hibernate Search,技术版本: Hibernate 3.6.5 Hibernate Search 3.4.0 Lucene (lucene-core-*.jar) 3.1.0 Spring 3.1.0.M2 <prop key="hibernate.search.default.indexBase">/some/dir</prop> <prop key="hibernate.search.default.directory_provider">org.hibernate.sear

技术版本:

Hibernate 3.6.5
Hibernate Search 3.4.0
Lucene (lucene-core-*.jar) 3.1.0
Spring 3.1.0.M2
<prop key="hibernate.search.default.indexBase">/some/dir</prop>
<prop key="hibernate.search.default.directory_provider">org.hibernate.search.store.FSDirectoryProvider</prop>
<prop key="hibernate.search.default.locking_strategy">native</prop>
<prop key="hibernate.search.default.exclusive_index_use">false</prop>
Hibernate 3.6.5
Hibernate搜索3.4.0
Lucene(Lucene core-*.jar)3.1.0
弹簧3.1.0.M2 休眠(搜索)配置:

Hibernate 3.6.5
Hibernate Search 3.4.0
Lucene (lucene-core-*.jar) 3.1.0
Spring 3.1.0.M2
<prop key="hibernate.search.default.indexBase">/some/dir</prop>
<prop key="hibernate.search.default.directory_provider">org.hibernate.search.store.FSDirectoryProvider</prop>
<prop key="hibernate.search.default.locking_strategy">native</prop>
<prop key="hibernate.search.default.exclusive_index_use">false</prop>
/some/dir
org.hibernate.search.store.FSDirectoryProvider
本地的
假的
问题:
我们的应用程序部署在Amazon(AWS云)中,但我们在本地集群中也遇到了这个问题:

应用程序的设计是这样的:在主(Web)应用程序中产生了一个
线程
,我们需要从该线程更新索引实体。基本上,它就像一个状态监视器线程,它读取一个.status文件并每隔30秒左右更新一次数据库。这种情况平均持续10分钟到1/2小时。 我们看到的问题是:每隔几天,我们就需要重新生成索引,因为Hibernate搜索停止返回有关实体(上面讨论的实体)的任何内容

我浏览了几个论坛,似乎只有一个线程应该更新Lucene索引。但也有人认为索引写入是线程安全的。因此,即使多个线程正在写入同一个索引,我仍然希望它不会导致问题(搜索中不会返回任何内容)。也就是说,我可能会得到相关实体的陈旧状态,但仍然应该返回一些内容

我们使用Hibernate搜索的默认IndexReader/Writer实现


任何帮助都将不胜感激。谢谢。

这里有一些想法

我浏览了几个论坛,似乎只有一个 线程应该正在更新Lucene索引

这通常不是真的。Lucene和Hibernate Search允许多个索引编写器,但必须通过Lucene的org.apache.Lucene.store.LockFactory正确同步对索引的访问。锁工厂是可配置的,您通过属性*hibernate.search.default.locking_strategy*使用本机工厂。问题可能在于此策略是基于文件的。我不太了解Amazon的分布式文件系统内部工作原理,但我可以想象,在这种情况下,文件锁是不起作用的。您可能需要实现自定义锁定策略

但也有人认为索引写入是线程安全的。因此,即使有多个线程 写同一个索引,我仍然认为它不应该引起问题

正确,只要锁起作用


另一种方法是不使用锁(将*hibernate.search.default.locking_strategy*设置为none),前提是您可以保证只有更新线程会写入索引。是否启用了更新线程自动索引?如果是这样,请尝试将其关闭(允许您的用例允许您)。

好的,对于那些来到这里寻找解决方案的人来说——以下是我们最后所做的,似乎已经解决了这个问题(我们已经在AWS上对这个修复进行了负载测试,到目前为止还没有任何问题):

我们基于Lucene的
NativeFSLockFactory
编写了锁工厂的实现。我们修改了
获取
方法,以便在放弃之前重试几次获取锁。我们在重试之间添加了一个短延迟(
sleep
),以处理
NFS
延迟

我们使用Lucene的LockVerifyServer测试了此修复程序,并观察到在高负载下,即使一些锁获取请求必须等待获取锁,但最终每个锁获取请求都会被处理。在实时情况下,这意味着索引文件的成功更新

感谢您为我们指明道路。:)


更新:昨天,我们不得不将重试次数增加到一个更高的数字~30,因为之前的值为3,我们面临索引更新延迟。此后情况似乎很好。

你说得对,这似乎是Amazon上的文件锁定问题。为了验证,我对它执行了Lucene的LockStress测试(w/LockVerfifyServer)——并观察到在高负载下,锁获取会多次失败。不幸的是,我还没有找到解决方案。如果你在问题中只提到NFS,我会立即告诉你Lucene很麻烦。这就是为什么我们创建了,它现在作为集成在Hibernate搜索中。您应该在问题中指出您在哪里使用NFS,Hibernate搜索参考手册明确禁止使用NFS,因为存在锁定问题。如果需要实时更新,请使用Infinispan目录,或者按照文档中的说明设置JMS主/从方法。您也可以使用Amazon队列服务编写后端。