创建索引器时文件系统锁定
FileSystem lock while creating Indexer
我使用了 hibernate-search,其中我用 @Indexed
、@Field
等注释域。
我的项目基于多个微服务,例如
- 搜索服务 - 启动时从数据库读取数据并创建索引。 (下面已经提到代码):
@Transactional(readOnly = true)
public void initializeHibernateSearch() {
try {
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(centityManager);
fullTextEntityManager.createIndexer().startAndWait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
- 微服务 1 - 在插入或更新任何域时更新索引。
我面临的问题是,当 Search Service
启动并创建索引时,它会锁定索引文件并且永远不会释放锁定。
当微服务 1 尝试在插入或更新时更新索引时,它会抛出如下异常
org.apache.lucene.store.LockObtainFailedException: Lock held by another program: /root/data/index/default/Event/write.lock
at org.apache.lucene.store.NativeFSLockFactory.obtainFSLock(NativeFSLockFactory.java:118)
at org.apache.lucene.store.FSLockFactory.obtainLock(FSLockFactory.java:41)
at org.apache.lucene.store.BaseDirectory.obtainLock(BaseDirectory.java:45)
at org.apache.lucene.index.IndexWriter.(IndexWriter.java:776)
at org.hibernate.search.backend.impl.lucene.IndexWriterHolder.createNewIndexWriter(IndexWriterHolder.java:126)
at org.hibernate.search.backend.impl.lucene.IndexWriterHolder.getIndexWriter(IndexWriterHolder.java:92)
at org.hibernate.search.backend.impl.lucene.AbstractWorkspaceImpl.getIndexWriter(AbstractWorkspaceImpl.java:117)
at org.hibernate.search.backend.impl.lucene.AbstractWorkspaceImpl.getIndexWriterDelegate(AbstractWorkspaceImpl.java:203)
at org.hibernate.search.backend.impl.lucene.LuceneBackendQueueTask.applyUpdates(LuceneBackendQueueTask.java:81)
at org.hibernate.search.backend.impl.lucene.LuceneBackendQueueTask.run(LuceneBackendQueueTask.java:46)
at org.hibernate.search.backend.impl.lucene.SyncWorkProcessor$Consumer.applyChangesets(SyncWorkProcessor.java:166)
at org.hibernate.search.backend.impl.lucene.SyncWorkProcessor$Consumer.run(SyncWorkProcessor.java:152)
at java.lang.Thread.run(Thread.java:748)
能否请您告诉我在微服务架构中使用 hibernate-search 的正确方法是什么。
有几个选项。我推荐第一个,因为它最符合微服务的架构精神。
- 每个微服务都有独立的索引:不要共享索引目录。
- 使用 in the docs 描述的 master/slave 架构,因此要让单个服务写入索引 - 其他服务必须委托给单个写入器。可以通过基于网络的文件系统或使用 Infinispan 复制索引。
- 禁用exclusive_index_use,配置属性(也在文档中描述)。我列出这个是为了完整性,但这通常是个坏主意;它会慢得多,并且您有责任确保一项忙于写入的服务不会使另一项需要写入的服务超时。
我使用了 hibernate-search,其中我用 @Indexed
、@Field
等注释域。
我的项目基于多个微服务,例如
- 搜索服务 - 启动时从数据库读取数据并创建索引。 (下面已经提到代码):
@Transactional(readOnly = true)
public void initializeHibernateSearch() {
try {
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(centityManager);
fullTextEntityManager.createIndexer().startAndWait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
- 微服务 1 - 在插入或更新任何域时更新索引。
我面临的问题是,当 Search Service
启动并创建索引时,它会锁定索引文件并且永远不会释放锁定。
当微服务 1 尝试在插入或更新时更新索引时,它会抛出如下异常
org.apache.lucene.store.LockObtainFailedException: Lock held by another program: /root/data/index/default/Event/write.lock at org.apache.lucene.store.NativeFSLockFactory.obtainFSLock(NativeFSLockFactory.java:118) at org.apache.lucene.store.FSLockFactory.obtainLock(FSLockFactory.java:41) at org.apache.lucene.store.BaseDirectory.obtainLock(BaseDirectory.java:45) at org.apache.lucene.index.IndexWriter.(IndexWriter.java:776) at org.hibernate.search.backend.impl.lucene.IndexWriterHolder.createNewIndexWriter(IndexWriterHolder.java:126) at org.hibernate.search.backend.impl.lucene.IndexWriterHolder.getIndexWriter(IndexWriterHolder.java:92) at org.hibernate.search.backend.impl.lucene.AbstractWorkspaceImpl.getIndexWriter(AbstractWorkspaceImpl.java:117) at org.hibernate.search.backend.impl.lucene.AbstractWorkspaceImpl.getIndexWriterDelegate(AbstractWorkspaceImpl.java:203) at org.hibernate.search.backend.impl.lucene.LuceneBackendQueueTask.applyUpdates(LuceneBackendQueueTask.java:81) at org.hibernate.search.backend.impl.lucene.LuceneBackendQueueTask.run(LuceneBackendQueueTask.java:46) at org.hibernate.search.backend.impl.lucene.SyncWorkProcessor$Consumer.applyChangesets(SyncWorkProcessor.java:166) at org.hibernate.search.backend.impl.lucene.SyncWorkProcessor$Consumer.run(SyncWorkProcessor.java:152) at java.lang.Thread.run(Thread.java:748)
能否请您告诉我在微服务架构中使用 hibernate-search 的正确方法是什么。
有几个选项。我推荐第一个,因为它最符合微服务的架构精神。
- 每个微服务都有独立的索引:不要共享索引目录。
- 使用 in the docs 描述的 master/slave 架构,因此要让单个服务写入索引 - 其他服务必须委托给单个写入器。可以通过基于网络的文件系统或使用 Infinispan 复制索引。
- 禁用exclusive_index_use,配置属性(也在文档中描述)。我列出这个是为了完整性,但这通常是个坏主意;它会慢得多,并且您有责任确保一项忙于写入的服务不会使另一项需要写入的服务超时。