elasticsearch 는 워낙 유명하고 안정적으로 성장한 오픈소스라 공식 문서, 커뮤니티, 블로그, 소스코드 등 참고할 자료들이 넘쳐난다. 굳이 그 넘쳐나는 자료에 한 숟가락을 더 얹을 필요가 있겠냐마는, 프로덕션 환경에 elasticsearch 를 처음 도입하려는 사람에게 찾는 수고를 덜 수 있는 best practice 를 제공하는 것이 이 문서의 목적이므로 누군가에게는 도움이 될 것으로 생각한다. elk 스택이나 관리용 플러그인, 키바나 사용법 등은 필자가 잘 모르기도 하고 워낙 좋은 문서가 많기 때문에 다른 문서를 참조하는 편이 낫다. 이 문서는 elasticsearch cluster 를 구성할 때 참고할 만한 사항들을 정리하였다.
ECK(Elastic Cloud on k8s)
ECK는 k8s 에 거부감이 없다면 elasticsearch 운영환경으로 선택할 수 있는 좋은 옵션으로, elasticsearch 개발사인 Elastic 에서 공식 배포하는 k8s operator pattern 이다. k8s 환경에 빠르게 적용할 수 있으며, elasticsearch 특성을 고려한 리소스 / lifecycle 관리가 가능하다.
Operator pattern이란?
k8s에서 기본 제공하는 방식으로 서비스 운영하기엔 도메인 특성이 적합하지 않아 반복적인 설정/변경작업이 잦을 경우 직접 custom resource 를 작성할 수 있는데, 이 custom resource 를 관리하는 확장 인터페이스가 operator 이며, 이렇게 custom resource 와 opertor를 제작하여 k8s 를 사용하는 패턴을 operator pattern 이라 한다.
elasticsearch 적정 메모리
elasticsearch 는 메모리의 크기가 매우 중요하다. 다큐먼트로부터 인덱스를 생성할 때에도 메모리를 사용하고, 검색 속도 향상을 위한 캐시에도 메모리를 사용하기 때문에 elasticsearch 가 빠른 성능을 내기 위해선 메모리 리소스가 넉넉해야 한다. 그럼 그 넉넉한 메모리의 적정 규모는 얼마일까?
jvm compressed oop
대부분 elasticsearch 와 적정 메모리 관련 문서를 찾아보면 jvm heap 에 32Gbytes 이상 할당하지 말라는 내용이 많을 것이다. compressed oop 라는 기능으로 메모리를 효율적으로 쓸 수 있는 최대치가 32Gbytes 이기 때문이다. 절반은 맞고 절반은 틀렸다.

64bit 주소를 사용하면 메모리 공간 내에서 데이터 저장영역이 그만큼 줄어들기 때문에 효율성 측면에서 heap size는 32Gbytes를 넘지 않는 편이 좋았다. 과거에는 말이다.
zgc
zgc는 java11 부터 사용할 수 있는 신규 gc 이다. 벤치마크를 확인해 보면 성능이 매우 뛰어남을 알 수 있다. 허나 zgc를 사용하려면 compressed oop 를 쓰면 안된다. 0으로 채워지는 padding 영역을 zgc에서 사용하기 때문이다.

compressed oop 는 32Gbytes 제약이 있으나 32bit 주소체계이기 때문에 메모리 공간을 효율적으로 사용할 수 있다. 반면 zgc는 64bit 주소체계이기 때문에 메모리 공간 사용률이 효율적이지 않지만 gc 성능이 빠르다. 그럼 둘 중에 어느 것이 효율적일까? 정해진 답은 없으나 heap size 가 32Gbytes 이하라면 compressed oop, 그 이상으로 heap을 크게 써야 한다면 zgc를 사용하는 편이 이득일 것으로 보인다.
lucene mmaped io
elasticsearch에 메모리를 할당할 때 주의할 점이 하나 더 있는데, 서버의 모든 메모리 리소스를 jvm에 할당하면 오히려 성능상 불리해질 수 있다. lucene은 memory mapped io 를 사용하는데, virtual memory 의 원활한 paging 을 위해 시스템 영역에 충분한 메모리를 남겨두어야 한다.
Maximum shards in node
elasticsearch 를 default 설정으로 사용하였을 때, index 하나 당 shard 갯수는 5개, node 당 maximum shard 갯수는 1000개이다. 필자는 이걸 모르고 index를 많이 만들었다가 shard 갯수가 1000 개를 초과하여 더이상 index를 생성하지 못하는 문제를 겪었다. node 당 shard 갯수는 설정으로 조절이 가능하므로 shard 를 늘리고 싶다면 클러스터 설정을 바꾸면 된다.
그렇다면 node 하나 당 적절한 shard 갯수는 얼마일까? elasticsearch 공식 블로그에 따르면 적절한 heap 1Gbyte 당 shard 20개가 적절하다고 하니 참고하길 바란다. (https://www.elastic.co/kr/blog/how-many-shards-should-i-have-in-my-elasticsearch-cluster)
Hot-Warm architecture
elasticsearch 는 저장 비용이 큰 편이다. 주어진 리소스가 데이터 양에 비해 충분히 넉넉하다면 별 문제가 없겠으나, 리소스를 효율적으로 사용하려면 아키텍처를 적절히 구성하여야 할 것이다. 일반적으로 최근 데이터는 검색을 자주하는 반면 오래된 데이터는 그렇지 않은 경우가 많은데, hot-warm 모델은 index 를 고성능 data node(hot) -> 저성능 data node(warm) -> 삭제 의 순서로 이동시키며 lifecycle을 관리하는 아키텍처이다.

opendistro ISM
opendistro의 ISM(Index State Management) 기능을 사용하면 Hot-Warm architecture 의 index lifecycle 을 쉽게 관리할 수 있다. opendistro에는 다른 여러 부가기능들이 있으므로 관심있으면 공식 문서를 참조 바란다.
좋을 글 감사합니다. 많은 도움이 되었습니다.
좋아요좋아요
부족한 글 읽어주셔서 감사합니다.
좋아요좋아요