ElasticSearch 클러스터 설정 톺아보기

2024. 12. 30. 16:33·ElasticSearch

ElasticSearch 기본 환경 설정

클러스터의 환경 설정은 `elasticsearch.yml` 파일로 할 수 있습니다.

Cluster 영역

클러스터 내의 모든 노드들은 동일한 클러스터의 이름을 사용하는데, 그 이름을 설정합니다.

설정하면 클러스터 전체에 적용됩니다.

cluster.name: myCluserName

- 아무 값도 설정하지 않으면 `elasticsearch`라는 이름으로 설정됩니다.

Node 영역

해당 노드에만 적용되는 설정입니다.

node.name: myNode1
  • 노드의 이름은 클러스터 내에서 유니크해야 합니다.
  • 7.x 버전부터 기본값으로 `${HOSTNAME}`을 사용합니다.

Path 영역

데이터와 로그를 저장하는 위치를 설정할 수 있습니다.

이 위치 설정 값이 없으면 ElasticSearch가 실행되지 않습니다.

path.data: /var/lib/elasticsearch  # 세그먼트 파일이 저장되는 경로
path.log: /var/log/elasticsearch   # elasticsearch에서 발생하는 로그가 저장되는 경로

# 여러 경로를 지정하는 방법
path.data: /var/lib/elasticsearch/path1, /var/lib/elasticsearch/path2

`,`를 사용하면 여러 경로를 지정할 수 있고, RAID를 사용한다면 분산 저장되어 성능이 좋아질 수 있습니다.

하지만 지정한 경로 중 하나에 문제가 발생하면 어떤 문서(Document)들에 영향을 주는지 파악하기 어려워집니다.

Memory 영역

ElasticSearch는 스왑 메모리 영역을 사용하지 않는 것을 권고하고 있는데, 스왑 메모리를 사용하지 않도록 설정할 수 있는 영역입니다.

bootstrap.memory_lock: true  # true: 스왑 메모리를 사용하지 않음

`true`로 설정 시 스왑 메모리를 사용하지 않도록 할 수 있습니다.

 

추가로 OS의 리소스 제한 설정도 추가로 해야 실제로 적용이 됩니다.

`/etc/security/limits.conf` 파일에 아래 내용을 추가합니다.

# 아래 설정을 추가
elasticsearch soft memlock unlimited  # 새로운 프로세스 실행 시 적용되는 기본 한도를 무제한으로
elasticsearch hard memlock unlimited  # 프로세스에 할당하는 메모리의 최대 한도를 무제한으로

스왑 메모리 영역을 사용하지 않으면 성능은 보장되지만 시스템 전체 메모리가 부족하면 OutOfMemory로 이어질 수 있습니다.

ElasticSearch는 JVM 위에서 동작하므로 JVM Heap 영역이 시스템 전체 메모리의 절반 이상이 되면 OOM(OutOfMemory)가 발생해 노드의 장애로 이어지기 때문에 주의해서 사용해야 합니다.

Network 영역

ElasticSearch가 외부 클라이언트 또는 내부 노드 간 통신할 때 사용할 수 있는 설정 영역입니다.

network.host: 192.168.0.1  # ElasticSearch가 사용하는 IP 주소
http.port: 9200  # ElasticSearch가 사용하는 Port 번호

network.host는 두 개의 설정으로 나눌 수 있는데, `network.bind_host`와 `network.publish_host`가 있습니다.

  • `network.bind_host`: 노드 간 통신할 때 사용하는 IP 주소
  • `network.publish_host`: 외부와 통신할 때 사용하는 IP 주소

`network.host: 0.0.0.0`으로 설정하면 `network.publish_host: 0.0.0.0`와 `network.bind_host: 0.0.0.0` 두 개를 설정한 것과 동일한 것입니다.

 

하지만 일반적으로 클러스터를 구축할 땐 `network.host: 0.0.0.0` 이런 식으로 단일 값으로 설정하지 않고 두 개의 설정으로 나눠서 사용합니다. 그 이유는 아래 그럼처럼 두 개 이상의 노드가 있을 때 노드 간 통신 시 `0.0.0.0`으로 통신으로 시도하기 때문에 충돌이 발생하기 때문입니다.

두 노드가 같은 주소인 0.0.0.0을 사용할 수 없다

 

따라서 아래 그림처럼 외부 통신을 위해 `network.publish_host: 0.0.0.0`으로 설정하고, `network.bind_host: 노드 자신의 IP`를 사용해야 합니다.

두 노드가 상대의 IP로 통신할 수 있다

DIscovery 영역

노드 간 클러스터링에 사용되는 설정입니다.

아래 옵션은 7.x 버전 기준입니다.

cluster.initial_master_nodes: ["master-1.es.com:9300", "master-2.es.com:9300"]
discovery.seed_hosts: ["master-1.es.com:9300", "master-2.es.com:9300"]
  • `cluster.initial_master_nodes`
    • 최초로 클러스터가 시작될 때 마스터 역할을 할 노드들을 지정할 때 사용합니다.
    • split brain 현상을 방지하기 위해 이곳에 작성된 마스터 노드의 개수를 기반으로 클러스터를 구축하기 위한 최소한의 마스터 노드 대수를 계산하고 그 값을 설정합니다. (값은 마스터 노드의 대수가 과반수가 되도록 계산됩니다.)
      • 예를 들어, 마스터 노드 개수가 3대면 (3 / 2) + 1 = 2로, 최소 2대의 마스터 노드가 있어야 클러스터를 구축할 수 있습니다.
      • 마스터 노드가 3대일 때 최소 마스터 노드 대수는 2대이므로, 데이터 노드가 합류할 때 마스터 노드가 2대 이상이면 클러스터에 합류할 수 있습니다.
    • 이 설정은 마스터 노드 역할을 하는 서버에만 설정하면 됩니다.
  • `discovery.seed_hosts`
    • 새로운 노드가 클러스터에 합류할 때 클러스터의 전체 메타데이터를 가져올 노드를 지정합니다.
    • 이 설정은 모든 노드에 설정돼야 하며, 변경이 적은 마스터 노드로 설정하는 것이 좋습니다.

Gateway 영역

클러스터의 복구 관련 설정입니다.

gateway.recover_after_nodes: 3  # 정상적인 노드의 개수가 3개일 때 인덱스 복구 시작

# 또는 아래 두 값을 사용
gateway.recover_after_master_nodes: 2  # 마스터 노드 2대가 정상일 때 인덱스 복구 시작
gateway.recover_after_data_nodes: 3    # 데이터 노드 3대가 정상일 때 인덱스 복구 시작

예를 들어, ElasticSearch 버전 업그레이드를 위해 클러스터 내에 노드를 전부 재시작할 때(Full Cluster Restart) 재시작한 노드들은 인덱스를 복구해야 합니다.

이때 사용되는 설정값으로, 이 값이 3이라면 최소 3대의 노드가 정상적인 상태(green) 일 때 인덱스 복구를 시작합니다.

Various 영역

클러스터의 인덱스 관련 설정입니다.

`_all`이나 `와일드카드 표현식`으로 인덱스를 삭제할 수 없도록 하는 설정입니다. 이 값이 `true` 이면 인덱스 삭제 시 실수로 한 번에 인덱스가 삭제되지 않도록 막습니다.

action.destructive_requires_name: true

노드의 역할을 정하기

node.master: true  # 기본값
node.data: true    # 기본값
node.ingest: true  # 기본값
# 코디네이트 노드는 기본값 true

 

만약 마스터 노드로만 사용하려면 아래 설정으로 합니다.

node.master: true   # 기본값
node.data: false    # 기본값
node.ingest: false  # 기본값

 

데이터 노드로만 사용하려면 아래 설정으로 합니다.

node.master: false  # 기본값
node.data: true     # 기본값
node.ingest: false  # 기본값

 

인제스트 노드로만 사용하려면 아래 설정으로 합니다.

node.master: false  # 기본값
node.data: false    # 기본값
node.ingest: true   # 기본값

 

코디네이트 노드로만 사용하려면 아래 설정으로 합니다.

node.master: false  # 기본값
node.data: false    # 기본값
node.ingest: false  # 기본값

데이터 노드가 코디네이트 노드 역할을 함께하면 노드의 부하가 높아지기 때문에 이를 방지하기 위해 코디네이트 노드로만 사용할 수 있습니다.

JVM 옵션 설정

ElasticSearch는 JVM 위에서 동작하기 때문에 JVM 관련 옵션도 중요합니다.

Heap 영역 사이즈 관련 설정

-Xms1g  # 최소 Heap Size. 초기 JVM 실행 시 Heap Size를 1GB로 설정
-Xmx1g  # 최대 Heap Size. 최대 Size를 1GB로 설정. 보통 초기 사이즈와 동일한 값을 사용한다.
  • `-Xms`: Heap 영역의 최솟값
  • `-Xmx`: Heap 영역의 최댓값
  • ElasticSearch는 성능을 위해 두 값을 동일하게 설정하도록 권고합니다.
    그렇지 않으면 초기에는 최솟값으로 할당했다가 Heap 영역이 부족해지면 최댓값까지 Heap 영역을 늘리기 때문에 중간에 성능이 떨어집니다.

GC 관련 설정

-XX:+UseConcMarkSweepGC                # 1
-XX:CMSInitiatingOccupancyFraction=75  # 2
-XX:+UseCMSInitiatingOccupancyOnly     # 3
  • `-XX:+UseConcMarkSweepGC`: CMS라는 GC를 사용한다는 설정입니다.
  • `-XX:CMSInitiatingOccupancyFraction=75`: old GC를 수행할 Heap 사용량(%)입니다. 75%(기본값)가 되면 old GC가 발생합니다.
  • `-XX:+UseCMSInitiatingOccupancyOnly`: old GC를 수행할 때 GC 통계치가 아닌 위의 설정값으로만 수행한다는 의미입니다.

Heap 영역의 크기와 관련해서

ElasticSearch는 Heap 영역의 크기가 32GB가 넘지 않게 설정할 것을 권고합니다. 또한, 시스템 전체 메모리의 50% 정도를 Heap 메모리로 사용할 것을 권고합니다.

 

왜 32GB가 넘지 않도록 권고하나?

Heap 크기를 32GB 아래로 설정해야 하는 이유는 32비트 방식의 아키텍처를 지원하기 때문입니다.

32비트로 표현하는 주소 공간은 4GB까지 표현할 수 있고, 64비트로 표현하는 주소 공간은 16EB(엑사바이트, 160억 GB)까지 가능합니다. 64비트로 주소를 표현하면 더 많은 연산과 더 많은 메모리 공간이 필요해 성능이 더 떨어집니다.

 

ElasticSearch는 Compressed OOP(Ordinary Object Pointer)를 통해 32비트 주소 공간에 8배까지 표현할 수 있기 때문에 4GB * 8 = 32GB까지 주소 공간을 표시할 수 있습니다. 그래서 32GB 아래로 설정하면 32비트 기반의 OOP를 사용할 수 있게 되어 성능 저하를 피할 수 있게 됩니다.

 

왜 시스템 메모리의 절반을 할당하도록 권고하나?

I/O 작업은 (SSD라 하더라도) 디스크 작업이 느립니다. 운영체제는 파일 시스템을 통해 `페이지 캐시` 기법으로 메모리에 데이터를 모았다 한 번에 I/O 작업을 수행합니다.

 

그런데 ElasticSearch는 백그라운드 스레드에서 세그먼트(디스크에 저장되는 파일)들을 자주 병합(merging)합니다.

즉, I/O 작업이 빈번하게 발생합니다. 빈번한 I/O 작업을 위해 운영체제가 사용하는 `페이지 캐시`를 최대한 활용할 수 있도록 해야 하는데 Heap 영역이 너무 크면 활용할 수 있는 메모리 영역이 부족해 `페이지 캐시`를 제대로 활용하지 못할 수 있습니다.

 

따라서 ElasticSearch 프로세스 자체가 사용하는 Heap 영역을 시스템 전체 메모리의 절반이 넘지 않는 것을 권고하고 있습니다.

참고

  • 기초부터 다지는 ElasticSearch 운영 노하우
  • OS 리소스 제한 - https://wasking.tistory.com/92

'ElasticSearch' 카테고리의 다른 글

ElasticSearch 역 인덱스(Inverted Index)  (0) 2025.01.10
ElasticSearch Cluester API & Index API - 클러스터 설정과 인덱스 설정 변경하기  (0) 2025.01.10
ElasticSearch 샤드 배치 방식 변경하기  (2) 2025.01.03
ElasticSearch 기본 개념  (0) 2024.12.29
bulk API 수행 시 'Malformed content, found extra data after parsing: START_OBJECT' 에러 해결하는 방법  (2) 2024.12.26
'ElasticSearch' 카테고리의 다른 글
  • ElasticSearch Cluester API & Index API - 클러스터 설정과 인덱스 설정 변경하기
  • ElasticSearch 샤드 배치 방식 변경하기
  • ElasticSearch 기본 개념
  • bulk API 수행 시 'Malformed content, found extra data after parsing: START_OBJECT' 에러 해결하는 방법
옐리yelly
옐리yelly
전시회에서 도슨트를 따라다니며 작품 해설을 들으면 더 재밌었던 기억들이 있습니다. 글로 더 재밌는 개발이 되도록 노력하고 있습니다.
  • 옐리yelly
    개발 갤러리
    옐리yelly
  • 전체
    오늘
    어제
    • 모든 글 보기 (82)
      • Project (22)
      • Java (4)
      • Spring (6)
      • Kubernetes (6)
      • Docker (2)
      • JPA (2)
      • Querydsl (2)
      • MySQL (8)
      • ElasticSearch (7)
      • DevOps (4)
      • Message Broker (3)
      • Git & GitHub (2)
      • Svelte (1)
      • Python (8)
        • Python Distilled (4)
        • Anaconda (1)
        • Django (0)
        • pandas (3)
      • Algorithm (1)
      • Computer Science (0)
      • 내 생각 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    argocd
    예약 시스템
    k8s
    Project
    docker
    포텐데이
    프로젝트
    리팩토링
    커넥션 풀
    pymysql
    Spring
    MySQL
    Python
    svelte
    blue-green 배포
    OOP
    Message Broker
    nks
    JPA
    devops
    elasticsearch
    pandas
    성능 테스트
    querydsl
    데드락
    ncloud
    RabbitMQ
    gitops
    dataframe
    비사이드
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
옐리yelly
ElasticSearch 클러스터 설정 톺아보기
상단으로

티스토리툴바