
문서 색인 요청
루씬은 문서를 분석해서 메모리 버퍼에 역색인을 생성한다.
문서 색인, 업데이트, 삭제 등의 작업이 수행되면 루씬은 메모리에 변경된 데이터를 들고 있다가 주기적으로 디스크에 flush한다.
루씬은 색인한 정보를 파일로 저장한다.
루씬에서 검색하기 위해서는 먼저 파일을 열어야 한다.
DirectoryReader 클래스를 이용해 파일을 연다.IndexReader 객체를 얻는다.DirectoryReader.openIfChanged를 호출해 변경 사항이 적용된 새 IndexReader를 열고 기존 IndexReader를 안전하게 닫는다.🤔 매번 refresh해도 괜찮을까?
루씬 flush는 시스템의 페이지 캐시에 데이터를 넘겨주는 것까지만 보장한다.
디스크에 파일이 실제로 안전하게 기록되는 것은 루씬 commit이 보장한다.
fsync 시스템 콜을 통해 주기적으로 커널 시스템의 페이지 캐시 내용과 실제로 디스크에 기록된 내용의 싱크를 맞춤으로써 디스크에 파일을 기록한다.
엘라스틱서치의 flush = 루씬 flush + 루씬 commit
즉, 엘라스틱서치 flush는 엘라스틱서치 refresh보다 훨씬 비용이 많이 든다.
적절한 주기로 수행된다는 점과 명시적으로 수행할 수 있다는 점은 같다.
fsync
루씬은 하드웨어 실패가 나는 상황까지 데이터 정합성을 보장하지는 않는다.
디스크에 기록된 파일들이 모이면 세그먼트라는 단위가 된다.
루씬의 검색 대상은 바로 이 세그먼트이다.
세그먼트는 불변이다
🤔 그럼 세그먼트의 개수가 무한대로 증식하지 않을까?
루씬은 중간중간 세그먼트를 병합한다.
세그먼트가 병합될 때 삭제 플래그가 표시된 데이터를 실제로 삭제한다.
세그먼트 병합은 비용이 많이 들지만, 병합 이후에 검색 성능이 향상된다. (당연함)
forcemerge API를 통해 명시적인 병합 수행도 가능하다.
루씬 세그먼트 < 루씬 인덱스 < 엘라스틱서치 샤드 < 엘라스틱서치 인덱스
여러 세그먼트가 모이면 하나의 루씬 인덱스가 된다.
엘라스틱서치 샤드는 이 루씬 인덱스 하나를 래핑한 단위다.
여러 엘라스틱서치 샤드가 모이면 하나의 엘라스틱서치 인덱스가 된다.
엘라스틱서치 레벨에서 여러 샤드에 있는 문서를 모두 검색할 수 있다.
루씬 레벨에서 불가능한 분산 검색을 엘라스틱서치 레벨에서 가능하게 한다.
어쩌지?
엘라스틱서치에 색인된 문서는 루씬 commit이 완료되어야 디스크에 기록된다.
문서에 변경사항이 있을 때마다 루씬 commit을 수행하면 비용이 많이 든다.
변경사항을 모아서 commit하기에는 장애 발생 시 데이터가 유실될 수 있다.
💡 엘라스틱서치 샤드는 모든 작업마다 translog라는 이름의 작업 로그를 남긴다.
샤드 복구 시간이 오래 걸린다!
translog의 크기를 적절하게 유지하여 이를 방지하자.
엘라스틱서치 flush가 백그라운드에서 주기적으로 수행되면서 translog의 크기를 적절하게 유지한다.
엘라스틱서치 flush = 루씬 commit + 새 translog 생성