2011-08-05 5 views
2

변경된 문서를 업데이트하고 변경되지 않은 다른 문서를 그대로 유지하는 점진적 모드에서 Lucene 색인을 새로 고치려고합니다.Lucene 색인에서 문서를 업데이트 할 때 OutOfMemoryErrors를 피하는 방법은 무엇입니까?

변경된 문서를 업데이트하려면 IndexWriter.deleteDocuments(Query)을 사용하여 해당 문서를 삭제 한 다음 IndexWriter.addDocument()을 사용하여 업데이트 된 문서를 추가합니다.

IndexWriter.deleteDocuments에 사용 된 Query 개체는 약 12-15 개의 용어를 포함합니다. 인덱스를 새로 고치는 과정에서 때때로 IndexWriter.deleteDocuments을 사용하여 모든 문서를 삭제 한 다음 새 문서를 추가하여 FULL 새로 고침을 수행해야합니다.

문제는 약 100000 개의 문서 삭제 후 IndexWriter.flush()을 호출하면 실행하는 데 오랜 시간이 걸리고 OutOfMemoryError을 던집니다. 플러싱을 사용 중지하면 색인 생성이 빠르게 진행되어 2000000 개의 문서를 삭제 한 다음 OutOfMemoryError을 던집니다. 메모리 부족 오류를 피하기 위해 IndexWriter.setRAMBufferSizeMB을 500으로 설정하려고했지만 운이 없었습니다. 색인 크기는 1.8GB입니다.

답변

0

Lucene 색인에서 모든 문서를 지우려면 IndexWriter를 닫고 색인 파일을 직접 삭제 한 다음 기본적으로 새로운 색인을 시작하는 것이 훨씬 더 효율적이라는 것을 발견했습니다. 이 작업은 시간이 거의 들지 않으며 색인이 원래 상태 (다소 비어있는 경우)로 유지됩니다.

1

처음으로. RAM 버퍼를 늘리는 것이 해결책이 아닙니다. 내가 아는 한 그것은 캐시이고 오히려 그것이 당신의 문제를 증가시키고 있다고 주장 할 것입니다. OutOfMemoryError는 Lucene의 문제가 아닌 JVM 문제입니다. RAM 버퍼를 1TB로 설정할 수 있습니다. VM에 메모리가 충분하지 않은 경우 문제가 발생합니다. 따라서 JVM 메모리를 늘리거나 소비를 줄이는 두 가지 작업을 수행 할 수 있습니다.

제 2의. 이미 힙 메모리 설정이 증가하는 것을 고려 했습니까? 플러시가 영원히 필요한 이유는 시스템이 메모리가 부족 해지 직전에 많은 가비지 콜렉션을 수행하고 있기 때문입니다. 이것은 전형적인 증상입니다. jvisualvm과 같은 도구를 사용하여 확인할 수 있습니다. 당신은 세부 먼저 플러그인 GC를 설치해야하지만, 당신은 선택하고 미친에서 OutOfMemory 응용 프로그램을 모니터링 할 수 있습니다. 다시, 내가 사용하는 것,

자바 -Xmx512M MyLuceneApp (또는 그러나 당신은 당신의 루씬 응용 프로그램을 시작)

을하지만 : 당신이 당신의 메모리 문제에 대해 배운 경우 같은 최대 힙 공간을 늘릴 수 있습니다 도구를 사용하여 메모리 소비 프로필 및 가비지 수집 동작을 먼저 확인하십시오. 가비지 수집으로 인해 성능 저하없이 응용 프로그램 속도가 느려지므로 메모리가 부족한 상태를 피하는 것이 목표입니다.

제 3의. 이제 힙을 늘리면 네이티브 메모리가 충분한 지 확인해야합니다. 그렇게하지 않으면 (리눅스에 top 같은 도구로 확인)하기 때문에 시스템이 디스크로 스와핑 시작이뿐만 아니라 미친 듯이 루씬 성능에 타격을 줄 것으로 예상된다. Lucene은 순차적 디스크 읽기에 최적화되어 있기 때문에 시스템이 스왑을 시작하면 하드 디스크는 순차적 읽기보다 2 배 이상 느린 디스크 탐색을 수행합니다. 그래서 더 나빠질 것입니다.

넷째. 충분한 메모리가없는 경우 배치 삭제를 고려하십시오. 1,000 개 또는 10,000 개의 문서가 플러시를 한 후, 계속해서 반복합니다.이 OutOfMemoryError의 이유는 Lucene이 플러시를 수행 할 때까지 모든 것을 메모리에 유지해야하기 때문입니다. 따라서 향후 문제를 피하기에 너무 큰 배치를 플러시하지 않는 것이 좋습니다.

+0

JVM 최대 메모리 힙 크기를 12G로 설정합니다. 나는 또한'IndexWriter.expungeDeletes (boolean)'호출을 시도해 보았다. flush 호출 후 삭제 된 documents.But과 관련된 인덱스의 사용되지 않는 모든 데이터가 제거되었다.하지만 여전히 OOM이 발생한다. 나는 왜 1.8 GB 색인 문서 삭제가 12 GB 메모리를 모두 소비하는지에 놀랐다. – JP10

+0

들여다 보았습니까? 그것은 실제로 그 모든 기억을 소비합니까? ... 나는 그것을 의심한다. jvisualvm을 사용하고, 수동 GC를 수행하고 남아있는 것을 확인하십시오. –

+0

추가 : 메모리에 문제가 없으면 내 답변이 더 이상 필요하지 않습니다. 그런 다음 삭제할 수 있습니다. 어쨌든 나는 Lucene이 100k 문서를 삭제하는 것이 왜 문제가되는지 이해하는 데 어려움이있다. Lucene 친구들은 내가 그와 같은 것을 물어 보면 엄청나게 작은 숫자라고 말할 것입니다 : -/ –

0

IndexWriter에 대해 더 작은 RamBufferedSize를 사용해보십시오.

버퍼가 가득 차거나 (문서 수가 특정 수준에 도달하면) IndexWriter가 플러시됩니다. 버퍼 크기를 큰 수로 설정하면 암시 적으로 flush를 호출하는 것을 연기하므로 메모리에 너무 많은 문서가 포함될 수 있습니다.

관련 문제