[엘라스틱서치] 메모리할당에 대해(엘라스틱 검색 속도가 느려요) - forewalk/elastic GitHub Wiki
Elasticsearch
튜닝
엘라스틱서치는 JVM 즉, 자바 버츄얼 머신 위에 올라가서 동작하도록 되어 있는, 자바 어플리케이션이다. jvm.options 에서는 여러 jvm 옵션들을 사용자가 설정할 수 있도록 파라미터들을 남겨놓았지만, 사실 Xms Xmx를 제외하면 거의 컨트롤할 부분이 없다. 이미 ES에서 최적의 옵션들을 적용하였기 때문이다.
Xms Xmx를 왜 같은 값으로 입력하는가?
일반적으로 자바매모리가 1.8 이전이었나, Xms와 Xmx가 메모리를 사용하고 반환하는 과정에서 버그가 있었다. 물론 지금은 해결되어 사용해도 상관없지만, 그럼에도 불구하고 같게하는 이유는 메모리 사이즈를 크게 요청하는 질의 들이 있어, Xms를 사용하다 Xmx 크기만큼 늘리려할 때, 순간 성능이 크게 저하되는 듯한 느낌을 받을 수 있다.
왜 32G 이하로 설정해야 하는가?
heap을 너무 적게 한다면 out of memory 메시지를 받을 수 있고, 그렇다고 너무 크게 한다면 ap에 프리징 되는 시간이 길어지기 떄문에, 사용하는 사용자 입장에선 ap가 멈추는 듯한 느낌을 받을 수 있다. 예전 ES 엔지니어(이기주)가 32기가 이상의 메모리 할당시 java object pointer(객체 메모리 번지 표현, 32비트를 사용한다.) 사용으로 인해 의미가 없고 오히려 성능면에서 안좋아질 수 있다고 했었던거 같은데, 그 말에 신빙성이 높다.
시스템의 절반을 메모리를 사용해야 하는 이유?
엘라스틱서치는 기본적으로 루씬에서 출발했다. 루씬의 세그먼트 생성 및 관리를 ES에서 하는 것이 아닌, 커널 시스템의 캐시를 많이 사용하는데, 시스템의 캐시란, OS의 메모리 공간으로 존재하게 된다. 즉, 시스템 메모리가 작다면, 세그먼트들의 활동 영역이 작아지고 세그먼트의 활동 영역이 작아진다는 의미는 검색속도의 저하를 의미한다. 그렇다고 무조껀 시스템의 절반 메모리 사용이 아니다. 32G의 물리서버가 베어메탈이라면, 16G잡으면 될것이다. 하지만, 그런 서버가 어디있겠는가? 보통 여러 apps가 함께 구동되기 마련이고(보안app이라도..), 그 부분을 모두 제외하고 계산하기를 바란다. 즉, 예를들어 ES Client를 위한 WAS가 같은 서버에 구동된다면 그 WAS가 사용하는 메모리가 약 2G정도라 예를 들고, 여러 다른 apps이 약 2G정도를 사용한다면 32-4G를 제외 하고 28G안에서 절반인 14G를 할당하기를 추천한다. OS의 남은 메모리가 작아지면 루씬 성능과 직결된다.