【问题标题】:Lucene IndexWriter thread safetyLucene IndexWriter 线程安全
【发布时间】:2011-05-05 14:52:03
【问题描述】:

Lucene 鼓励在多个线程中重用 IndexWriter。

考虑到两个线程可能有对 IndexWriter 的引用,如果线程 A 调用关闭写入器,线程 B 将留下一个无用的写入器。但据我了解,lucene 不知何故知道另一个线程使用同一个作者并推迟了它的关闭。

真的是这样吗? lucene 如何跟踪另一个线程使用 writer?

编辑 从答案来看,关闭 IndexWriter 是不正确的。但这带来了一个新问题:如果一个 IndexWriter 保持打开状态,基本上会阻止另一个 JVM 对该索引的访问(例如,在集群的情况下,或许多应用程序之间的共享索引)。

【问题讨论】:

    标签: java lucene


    【解决方案1】:

    如果一个线程关闭 IndexWriter 而其他线程仍在使用它,您将得到不可预知的结果。我们尝试让其他线程命中 AlreadyClosedException,但这只是尽力而为(不能保证)。例如,您也可以轻松地点击 NullPointerException。因此,您必须在外部进行同步,以确保您不会这样做。

    最近(现在只在 Lucene 的主干中,最终是 4.0)IndexWriter 内部的一个大线程瓶颈得到了修复,允许段刷新同时运行(以前它们是单线程的)。在并发硬件上运行许多索引线程的应用程序上,这可以大大提高索引吞吐量。详情请见http://blog.mikemccandless.com/2011/05/265-indexing-speedup-with-lucenes.html

    【讨论】:

      【解决方案2】:

      IndexWriter 的线程安全性和重用性意味着您可以有多个线程都使用该实例来创建/更新/删除文档。但是,如果您在一个线程中关闭索引编写器,它确实会弄乱其他所有人。

      【讨论】:

        【解决方案3】:

        您指的是IndexWriter.close() 方法上的waitForMerges 标志吗?

        在等待或不等待当前运行的合并完成的情况下关闭索引。这仅在使用在后台线程中运行合并的 MergeScheduler 时才有意义。

        Lucene 通常使用后台线程来整合跨多个线程发生的碎片写入 - 写入本身会立即发生,但整合是异步发生的。

        关闭 writer 时,应允许其完成合并过程,否则:

        总是调用 close(false) 是很危险的,尤其是当 IndexWriter 长时间没有打开时,因为这可能导致“合并饥饿”,从而长时间的合并将永远没有机会完成。随着时间的推移,这将导致索引中的段过多。

        所以作者并不“知道”你的线程,就你的意思而言。

        【讨论】:

        • 那么,如果两个线程正在使用同一个写入器,一个线程关闭它,那么另一个线程确实留下了一个无用的写入器?
        • @yannisf:嗯,是的,我想是这样,但这对于任何可变的共享对象都是一样的——一个线程可以使共享对象变得无用。这似乎不是特例。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多