2011-05-05 103 views
10

Lucene鼓勵重複使用來自多個線程的IndexWriter。Lucene IndexWriter線程安全

鑑於兩個線程可能對IndexWriter有引用,如果線程A在寫入器上調用close,那麼線程B將留下一個無用的寫入器。但就我的理解,lucene以某種方式知道另一個線程使用相同的作者並推遲其關閉。

這的確是這樣嗎? lucene如何跟蹤另一個線程使用該作者?

編輯 從答案來看,關閉IndexWriter是不正確的。但是這帶來了一個新問題:如果一個人保持打開IndexWriter,基本上阻止從另一個JVM訪問此索引(例如,在集羣或許多應用程序之間的共享索引中)。

回答

6

如果一個線程關閉了IndexWriter而其他線程仍在使用它,您將得到不可預知的結果。我們嘗試讓其他線程碰到AlreadyClosedException,但這只是盡力而爲(不保證)。 EG,你也可以很容易地遇到NullPointerException。所以你必須同步外部,以確保你不這樣做。最近(現在只有在Lucene的trunk中,最終爲4.0),IndexWriter內部的一個大的線程瓶頸被修正了,允許段沖刷同時運行(以前它們是單線程的)。在併發硬件上運行多個索引線程的應用程序中,這可以大大提高索引吞吐量。詳情請參閱http://blog.mikemccandless.com/2011/05/265-indexing-speedup-with-lucenes.html

0

您是指IndexWriter.close()方法中的waitForMerges標誌?

關閉索引,無論是否等待當前正在運行的合併完成。這僅在使用在後臺線程中運行合併的MergeScheduler時纔有意義。

Lucene通常使用後臺線程來合併跨多個線程發生的分段寫入 - 寫入本身立即發生,但整合發生異步。

當關閉作家,你應該允許它完成整合過程,否則:

是很危險的總是調用close(假的),尤其是當IndexWriter類未打開,很長,因爲這可能導致「合併飢餓」,從而長期合併永遠不會有機會完成。隨着時間的推移,這會導致索引中的部分太多。

所以作者並不「知道」你的話題,就你的意思而言。

+0

因此,如果兩個線程正在使用同一個編寫器並且一個線程關閉它,那麼另一個線程確實留下了一個無用的編寫器? – yannisf 2011-05-05 15:00:20

+1

@yannisf:好的,我想是的,但對於任何可變的共享對象來說,這是一樣的 - 一個線程可以使共享對象無用。這似乎並不是特例。 – skaffman 2011-05-05 15:01:25

1

IndexWriter的線程安全和重用意味着您可以有多個線程使用該實例來創建/更新/刪除文檔。如果你在一個線程中關閉了編輯器,它確實會讓其他人感到困惑。