엘라스틱서치는 JVM 위에서 동작하는 자바 애플리케이션이다. 그렇기 때문에 엘라스틱서치는 JVM 튜닝옵션들을 제공한다. 하지만 수년간 엘라스틱서치의 경험으로 최적화된 JVM옵션을 거의 적용하고 있기 때문에 변경할 필요는 없다고 한다. 하지만 Heap Memory 사이즈 같은 경우는 실 운영환경에서는 기본으로 제공하는 1기가보다는 높혀서 사용할 필요성이 있다.

 

$ELASTIC_PATH/config/jvm.options 파일에 들어가면 Xms,Xmx 옵션으로 최소,최대 JVM 힙 메모리 사이즈 조정이 가능하며 기타 다른 JVM옵션 변경이 가능하다. 다시 한번 강조하자면 왠만하면 다른 옵션들은 디폴트 값으로 가져가 사용하는 것이 좋다.

 

그리고 보통 JVM에서 Xms 크기의 메모리를 사용하다가 메모리가 더 필요하면 Xmx 크기만큼 메모리를 늘려서 사용하게 된다. 하지만 이렇게 Xmx크기의 메모리를 사용하려면 그 순간 갑자기 성능이 나빠질 수 있다. 그렇기 때문에 왠만하면 Xms,Xmx의 크기를 같게 주는 것이 여러모로 유리하다. 그리고 힙사이즈를 너무 작게하면 OOM(Out Of Memory) 오류가 날 수 있고 그렇다고 힙사이즈를 너무 크게하면 FullGC 발생시 STW가(Stop The World) 발생해 애플리케이션이 프리징되는 시간이 길어지기 때문에 사용자에게 애플리케이션이 멈춰보이는 현상을 줄 수 있기에 무작정 큰 메모리 사이즈를 할당하는 것도 좋지 않다.(보통 엘라스틱서치의 힙사이즈는 데몬 서버당 32기가 이하로 설정하길 권장한다.)

 

 

운영체제가 사용할 메모리 공간을 확보

엘라스틱서치 샤드는 내부적으로 루씬을 가지고 있으며 루씬은 세그먼트 생성 및 관리를 위해 커널 시스템 캐시를 많이 사용한다. 하지만 이렇게 시스템 캐시는 운영체제가 가지고 있는 메모리 공간으로 커널 내부에 존재하게 된다. 즉, 운영체제가 사용할 메모리를 대략 전체 스펙에 50%정도를 남겨놔야 좋다.

 

자바 8 기반에서는 힙 크기를 32기가 이상 사용하지 않는 것이 좋다

예) 128기가의 물리 머신에서 64기가를 운영체제에게 나머지 64기가를 엘라스틱서치가 할당받는 다면 밑에 스펙중 무엇을 선택할것인가?

  • 1)64기가 운영체제, 64기가 엘라스틱서치 노드1개
  • 2)64기가 운영체제,32기가 엘라스틱서치 노드2개

위의 두가지중 엘라스틱서치에서 안내하는 권장사항을 따른다면 2번 스펙을 따를 것이다. 이 말은 엘라스틱서치 노드 데몬서버 하나당 힙메모리를 32기가이상 잡지 않는것이다. 엘라스틱서치에서 이러한 가이드를 제공하는 이유는 핫스팟(Hot-Spot) JVM의 Object Pointer 정책때문이다. 즉, 엘라스틱서치 뿐만 아니라 모든 자바 기반 애플리케이션에도 동일하게 32기가 이상 잡지 않는 것을 권장한다. Object Pointer는 간단히 객체의 메모리 번지를 표현하는 주소값이다. 그리고 32비트,64비트 JVM은 기본적으로 모두 32비트 주솟값을 가지고 동작한다. 이유는 기본적으로 JVM은 32비트 Object Pointer를 사용하고 있기 때문이다. 여기서 너무 자세한 내용을 설명하는 것은 주제와 맞지 않을 것같아서 간단히 이야기하면 64비트 주솟값을 사용하면 주솟값을 위해 낭비되는 메모리값이 너무 많아 진다. 그렇기 때문에 JVM은 기존 Object Pointer를 개선한 Compressed Ordinary Object Pointer를 사용하는데 이 포인터가 기본적으로 32비트 Object Pointer한다. 이렇게 64비트 환경의 서버에서 32비트의 주소값을 사용하여 메모리 낭비를 줄이며 효율적으로 사용되는데, 만약 JVM 힙메모리 옵션이 32기가 이상 넘어가게되면 COOP에서 일반적인 64비트 주소값을 사용하는 OOP로 바뀌도록 되어 있다. 이렇게 64비트 주솟값 OOP 사용하게 되면 주솟값을 위하여 낭비되는 메모리의 값이 동일하게 증가하기 때문에 효율성이 떨어지게 되는 것이다.

 

 

상황에 따른 엘라스틱서치 힙크기 설정하기

 

  • 1)적절한 성능의 서버 : 32기가 힙메모리를 할당하여 엘라스틱서치 노드를 사용한다.
  • 2)고성능 서버 : 적절히 엘라스틱서치 노드를 나누어서 32기가씩 할당하여 사용한다.
  • 3)전문(Full Text) 검색을 주목적으로 엘라스틱서치를 사용하는 경우 : 엘라스틱서치 힙에 32기가를 할당하고 나머지를 운영체제에 남겨둬서 루씬이 시스템 캐시를 통해 메모리를 최대한 사용할 수 있게 한다. 전문 검색의 경우 메모리 연산보다는 루씬의 역색인 구조를 이용하기 때문에 시스템 캐시를 많이 이용한다.
  • 4)Not Analyzed 필드의 정렬/집계 작업이 많이 수행되는 경우 : 분석되지 않은 필드들의 정렬/집계는 루씬의 DocValues(루씬 캐시,기본적으로 not analyzed한 필드들은 기본적으로 DocValues가 생성됨)를 사용하기 때문에 힙 공간을 거의 사용하지 않고 시스템캐시를 이용하기 때문에 루씬에게 메모리를 많이 할당 될 수 있게 한다.
  • 5)전문(Full Text) 필드에서 정렬/집계 작업을 많이 수행하는 경우 : 전문(analyzed fleld)같은 경우는 루씬의 DocValues를 이용하지 않기 때문에 fielddata라는 힙 기반의 캐시를 이용하기 때문에 전문 필드 정렬/집계가 많은 경우 32기가로 엘라스틱서치 노드를 나누어서 여러개 생성하는 방식이 효율적이다.

 

posted by 여성게
: