인프런 커뮤니티 질문&답변

강민주님의 프로필 이미지
강민주

작성한 질문수

ElasticSearch Essential

xlsx 파일 색인 중 CircuitBreakingException 발생

작성

·

57

0

안녕하세요. Elasticsearch Essential 강의 수강 후 실무에서 Elasticsearch를 사용하는 중 질문이 생겨 문의드립니다.

Java 17 기반 G1GC 사용 중(Elasticsearch 7.10 버전), Apache Tika를 이용해 각종 확장자 파일에서 텍스트를 추출하여 indexing 합니다.

그런데 doc, txt, pdf, ppt, xlsx 파일 중 유독 xlsx 파일 색인(text 타입, fielddata=false)할 때만 CircuitBreakingException이 발생합니다. Full GC 를 강제로 발생시켜도 Heap이 비워지지 않고 하한값을 높이다가 Circuit Breaker 임계치까지 도달합니다.

xlsx의 시트 내에 숫자 cell이 많은데 edgengram (min_gram = 1) 토큰화 결과, 너무 많은 역색인 트리 구조가 발생한 것이 원인일까요?

 

답변 1

0

강진우님의 프로필 이미지
강진우
지식공유자

정확하게 어떤 요소들이 힙 메모리를 채우고 있는지 확인하려면 꽤 복잡한 분석 과정을 거쳐야 합니다. VisualGC 등을 이용해서 힙 메모리를 시각화 하는 것도 필요하죠.

지금같은 경우 그렇게 복잡하게 분석 과정을 거치기 어렵다면 다음과 같은 방법들을 사용해 볼 수 있습니다.

  1. 엑셀 파일을 일정한 크기로 잘라서 나눠 색인 해보기 -> 이렇게 해서 문제가 발생하지 않는다면 파일 용량에 따른 이슈로 판단하고 엑셀 파일을 잘라서 색인해 볼 수 있겠죠.

  2. 기본 애널라이저로 설정해서 색인 해보기 -> 이렇게 해서 문제가 발생하지 않는다면 애널라이저에 따른 이슈로 판단하고 min_gram 값을 변경하거나 등의 다양한 색인 방법을 고민해 볼 수 있겠죠.

  3. 힙 메모리를 늘려서 색인 해보기 -> 이렇게 해서 문제가 발생하지 않는다면 힙 메모리 부족으로 생각하고 늘려서 대응할 수 있겠죠.

이렇게 몇가지 가설을 세워 놓고 각 가설에 따른 테스트 결과를 바탕으로 원인을 파악하고 해결하는 것도 좋은 방법 입니다. 시간은 조금 더 걸리겠지만 테스트를 진행하면서 조금 더 동작 원리를 이해할 수 있는 계기가 될 수도 있습니다.

강민주님의 프로필 이미지
강민주
질문자

답변 감사합니다. VisualGC를 통한 힙메모리 분석은 Linux에서는 힘들것 같고, MacOS 또는 Windows에 Elasticsearch를 직접 띄워서 해야겠군요..

1의 경우 현재 문서를 10MB만 색인하고 있고, 3의 경우 heap size를 31GB -> 64GB로 늘렸을 때 목숨이 연장될 뿐 CircuitBreaker 발동은 피할 수 없었습니다. 말씀주신 2로 테스트하여 standard vs Edgengram(gram:1~10)을 비교해보는게 지금으로서는 가장 좋은 테스트 같습니다 ㅎㅎ

제가 아직 Heap Dump를 떠본적은 없지만, [Lucene in Action]을 살펴보면 아래와 같이 색인하게 되는데 아무래도 Field 객체나 Document 객체보다는 String 타입의 객체가 무수히 많이 생기는 것을 의심하고 있습니다.

final Settings settings = newAnalysisSettingsBuilder()
        .put("min_gram", 2)
        .put("max_gram", 3)
        .putList("token_chars", "letter", "custom")
        .put("custom_token_chars", "_-")
        .build();
Tokenizer tokenizer = new EdgeNGramTokenizerFactory(
        IndexSettingsModule.newIndexSettings(index, indexSettings),
        null,
        name,
        settings
).create(); 
tokenizer.setReader(new StringReader("Abc -gh _jk =lm"));
assertTokenStreamContents(tokenizer, new String[] { "Ab", "Abc", "-g", "-gh", "_j", "_jk", "lm" });

 

이번 기회에 왜 ES(Java) 프로세스 내에서 Mixed/Full GC가 발생함에도 객체 참조가 해제되지 않아 Heap을 꽉 채우는지(객체의 Reachability 관점에서) 확실히 조사해보고 싶은데 쉽지 않네요..

강진우님의 프로필 이미지
강진우
지식공유자

도움이 될지 모르겠지만, 비슷한 질문이 있었는데 https://www.inflearn.com/community/questions/1204799/compressed-oop-%EC%A1%B0%EA%B1%B4%EC%97%90-%EB%94%B0%EB%A5%B8-es-heap-size-%EC%A0%9C%EC%95%BD 이 내용을 한 번 참고 하시면 좋을 것 같습니다.

저도 ElasticSearch 클러스터를 운영한지는 꽤 되어서 지금 당장 도움이 될 만한 방안들을 고민해 보기가 쉽지 않네요. (__)

강민주님의 프로필 이미지
강민주

작성한 질문수

질문하기