본문 바로가기

Lucene

[lucene] IndexReader reopen.


루씬에서 IndexReader와 IndexSearcher 그리고 IndexWriter는 보통 하나의 인덱스 파일을 바라보며

작업을 합니다.

그리고 서로가 인덱스파일의 상태를 공유하지 못 합니다.

기본적으로 읽기/쓰기 등에 대해서 한꺼번에 작업이 일어나지 못 하도록

Lock 기능을 보유하고 있긴 하지만

IndexWriter가 인덱스 파일에 Document를 추가하고 commit을 시켰다고 해서

그 내용이 바로 IndexReader나 IndexSearcher에게 영향을 미치지 못 합니다.

하지만 검색 서비스를 위해서는 항상 일명 전체색인만으로 서비스를 제공할 수 있는 경우는 거의 없습니다.

증분색인 혹은 실시간 색인을 통해 일정 주기마다 변경되는 사항을 인덱스 파일에 반영 할 필요가 있습니다.

이것은 IndexWriter나 IndexReader를 통해서 반영을 하면 되는데

그렇다면 이 반영된 내용을 IndexSearcher가 알 수 있도록 해야 할 것입니다.

단순히 IndexSearcher.reload(); 이런게 있으면 좋을텐데.. 없더라구요 -_-

루씬 doc 에서는 IndexReader를 reopen하기 위한 방법으로 아래와 같은 방법을 제시하고 있습니다.


 * IndexReader new = r.reopen();
  * if (new != reader) {
  *   ...     // reader was reopened
  *   reader.close();
  * }
  * reader = new;

위의 소스를 참고해서 제가 사용하는 방식입니다.

중간에 다른 처리를 넣어줘도 되겠지만 기본적으로는 저정도면 사용이 가능한 것 같습니다.
IndexSearcher를 새로운 Reader를 통해서 생성해줘야 하더라구요..

그리고 얼마전에 루씬 메일링 리스트에서 나왔던 내용인데.. 보통은 IndexSearcher 같은 것은 싱글턴으로 생성하던가
아니면 Map 같은 곳에 넣어놓고 Pool 개념으로 사용을 많이 하실 것입니다.

그래야 IndexSearcher의 필드 캐쉬도 충분히 이용 할 수 있고
속도같은 부분에서도 이득을 볼 수 있을테니까요..

어떤 사람이 이 IndexSearcher를 여러개 생성해서 List에 넣어두고 인덱스를 다시 열어야 할 때
List를 돌면서 Searcher를 다시 오픈하는 로직을 구현한 것이 있었습니다.

그런데 이렇게 다시 생성을 하고 list에 add를 해주었는데
이것을 사용해서 검색을 하려고 하면 이미 searcher가 close되었다는 메시지가 나온다는 것이었습니다.
처음에는 루씬의 버그가 아닌지 문의를 해왔던 모양인데..
문제는 다른 곳에 있었습니다.

리스트에서 IndexReader가 close된 searcher는 remove를 해주던가 하는 작업이
있어야 하는데 그러지 않고 새로운 IndexSearcher만 추가해줘서 나타났던 에러였습니다.

IndexReader에 대해서 쓰다보니 예전에 메일링 리스트에서 봤던 기억이 나서
한번 같이 적어보았습니다.

관련 mail - archive : http://www.mail-archive.com/java-user@lucene.apache.org/msg24550.html