簡體   English   中英

更新Lucene索引中的文檔時如何避免OutOfMemoryErrors?

[英]How can I avoid OutOfMemoryErrors when updating documents in a Lucene index?

我正在嘗試以增量方式刷新Lucene索引,該索引用於更新已更改的文檔並保持其他未更改的文檔不變。

為了更新更改的文檔,我使用IndexWriter.deleteDocuments(Query)刪除這些文檔,然后使用IndexWriter.addDocument()添加更新的文檔。

IndexWriter.deleteDocuments中使用的Query對象包含大約12-15個術語。 在刷新索引的過程中,有時我還需要執行完全刷新,方法是使用IndexWriter.deleteDocuments刪除所有文檔,然后添加新文檔。

問題是當我說刪除大約100000個文檔后調用IndexWriter.flush()時,執行時間很長,並拋出OutOfMemoryError 如果我禁用刷新功能,索引會快速上升到說2000000 docs刪除,然后拋出OutOfMemoryError 我試圖將IndexWriter.setRAMBufferSizeMB設置為500,以避免出現內存不足錯誤,但是沒有運氣。 索引大小為1.8 GB。

第一 增加RAM緩沖區不是您的解決方案。 據我了解,這是一個緩存,我寧願說這正在加劇您的問題。 OutOfMemoryError是JVM問題,不是Lucene問題。 您可以將RAM緩沖區設置為1TB-如果您的VM沒有足夠的內存,則仍然存在問題。 因此,您可以做兩件事:增加JVM內存或減少消耗。

第二 您是否已經考慮過增加堆內存設置? 永久清除的原因是系統在內存耗盡之前不久就進行了大量垃圾回收。 這是典型症狀。 您可以使用jvisualvm類的工具進行jvisualvm 您需要先安裝GC詳細信息插件,然后才能選擇並監視瘋狂的OutOfMemory應用程序。 如果您了解內存問題,則可以增加最大堆空間,如下所示:

java -Xmx512M MyLuceneApp(或者,但是您啟動Lucene應用程序)

但是,再次,我將使用工具來首先檢查您的內存消耗配置文件和垃圾回收行為。 您的目標應該是避免內存不足,因為這會導致垃圾回收將您的應用程序減慢到無性能的狀態。

第三 現在,如果增加堆,則必須確保還具有足夠的本機內存。 因為如果您不這樣做(請使用Linux上的top工具),您的系統將開始交換到磁盤,這也會瘋狂影響Lucene的性能。 因為Lucene針對順序磁盤讀取進行了優化,並且如果系統開始交換,則硬盤將執行大量磁盤搜索,這比順序讀取慢2個數量級。 因此,情況將會更糟。

第四 如果沒有足夠的內存,請考慮分批刪除。 在沖洗1,000或10,000個文檔后,請一次又一次沖洗。 發生OutOfMemoryError的原因是,Lucene必須將所有內容保留在內存中,直到執行刷新為止。 因此,無論如何不要讓太大的批處理沖洗掉,以避免將來出現問題,這可能是一個好主意。

嘗試為您的IndexWriter使用較小的RamBufferedSize。

如果緩沖區已滿(或文檔數達到一定水平),IndexWriter將刷新刷新。 通過將緩沖區大小設置為一個較大的數字,您將隱式推遲調用flush,這可能導致內存中的文檔過多。

在極少數的情況下,我想擦除Lucene索引中的所有文檔,我發現關閉IndexWriter,直接刪除索引文件,然后基本上開始創建新索引的效率更高。 該操作只需要很少的時間,並且可以保證將索引保持原始狀態(如果有些空的話)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM