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`으로 통신으로 시도하기 때문에 충돌이 발생하기 때문입니다.
따라서 아래 그림처럼 외부 통신을 위해 `network.publish_host: 0.0.0.0`으로 설정하고, `network.bind_host: 노드 자신의 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 샤드 배치 방식 변경하기 (0) | 2025.01.03 |
ElasticSearch 기본 개념 (0) | 2024.12.29 |
bulk API 수행 시 'Malformed content, found extra data after parsing: START_OBJECT' 에러 해결하는 방법 (1) | 2024.12.26 |