노드 설정과 노드 역할
노드 역할
https://www.elastic.co/guide/en/elasticsearch/reference/7.17/modules-node.html
-master-eligible node
(마스터 후보 노드) : 마스터 후보 중에서 선거를 통해 마스터 노드가 선출된다. 클러스터 관리, 인덱스 생성/삭제, 어떤 샤드를 어떤 노드에 할당한 것인지 정한다.
-coordinating node
(조정 노드): 노드는 기본적으로 조정 역할을 수행한다. mode.roles:[]
를 empty 로 두면 조정 역할만 수행한다. (1단계 scatter: 요청을 데이터 노드로 분산시키고, 2단계 gather: 결과 모으기)
-remote_cluster_client
: 다른 클러스터에 클라이언트로 붙을 수 있는 노드. 클러스터 간 검색 기능도 가능하고 데이터 복제를 통한 동기화도 할 수 있다.
elasticsearch.yml
ES 7.10~
https://www.elastic.co/guide/en/elasticsearch/reference/current/important-settings.html
-discovery.seed_hosts
: 마스터 후보 노드 목록
-cluster.initial_master_nodes
: 클러스터 기동 시 첫 마스터 선거를 수행할 후보 노드 목록
-[network.host](https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-network.html#common-network-settings "https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-network.html#common-network-settings")
: ES 에 바인딩할 네트워크 주소. publish address 주소에도 적용된다. (기본값: _local_)
- 0.0.0.0: 모든 네트워크에서 접근 가능
-http.port
: 기본값: 9200-9300. 9200 부터 시작해서 선점 중이면 다음 포트를 사용한다.
ES 7 미만
discovery.zen
: discovery.seed_hosts
, cluster.initial_master_nodes
대신 사용한다.
[discovery.zen.minimum_master_nodes](https://esbook.kimjmin.net/03-cluster/3.3-master-and-data-nodes "https://esbook.kimjmin.net/03-cluster/3.3-master-and-data-nodes")
: 몇 대의 마스터 후보군이 살아있어야 마스터 선출을 수행할지 지정한다. 마스터 후보의 과반 이상으로 지정하지 않으면 split brain 이 일어날 수 있다. 값이 2이면 클러스터 네트워크가 단절됐을 때 마스터가 2개 이상인 클러스터만 살아남는다.- 7 버전 이상은 split brain 이 일어나지 않는 구조 (투표 도입으로)
힙 메모리 설정 가이드
힙 메모리 설정 위치
7.11 이상이면 config/jvm.options
보단 config/jvm.options.d/
밑에 heap-size.options
파일을 생성해서 관리하는게 편하다
-Xms32376m
-Xmx32376m
시스템 메모리 절반 이하로 지정하자
왜? 루씬이 커널 시스템 캐시 많이 쓰기 때문에 절반은 운영체제가 캐시로 쓰도록 놔두는 것이 좋다.
힙 크기를 32GB 아래로 지정하자
왜? JVM 이 Compressed OOPs 를 사용할 수 있게. 이게 성능에 영향이 크다.
💡 Compressed OOPs (Ordinary Object Pointers) 란?
https://velog.io/@koey_h/MemoryStructure
JVM 이 힙에 생성된 객체에 접근하기 위한 포인터를 OOP 라고 하는데, OOP 는 메모리 주소를 직접 가리킨다.
32bit 환경에선 포인터 1개가 32bit, 64bit 환경에선 포인터1개를 64bit 로 표현한다. 메모리 한 칸은 OS 상관없이 1 byte 를 가지므로 32bit 환경에서는
2^32 byte = (2^2)*(2^30) B = 4GB 까지 사용할 수 있다.그런데 Compressed OOPs 는 OOP 가 메모리 주소를 직접 가리키는게 아니라 객체의 상대적인 위치 차이만을 나타내는 방식으로, 8 byte 단위로 저장하는 자바 객체 주소를 1byte 로 표현할 수 있어 8배인 32GB 의 메모리를 사용할 수 있다.
= oops 가 object를 referencing 하는 대신 object의 offset을 referencing 한다.
아래 테스트를 통해 Compressed OOPs 가 true인 적용 범위안의 메모리로 설정한다.
hiseo@hiseo ~ % java -Xmx32G -XX:+PrintFlagsFinal 2> /dev/null | grep UseCompressedOops
bool UseCompressedOops = false {lp64_product}
hiseo@hiseo ~ % java -Xmx31G -XX:+PrintFlagsFinal 2> /dev/null | grep UseCompressedOops
bool UseCompressedOops := true {lp64_product}
1byte 로 인코딩된 주소를 디코딩하려면 3bit 시프트 연산 후 힙 영역이 시작되는 기본 주소를 더하는 작업이 필요한다.
zero-based 를 적용하면 기본 주소를 0으로 바꿔줘 더하는 과정이 없어져 성능 상 낫다. (항상 나은건 아니지만)
Compresseed OOPs 최대값 보다는 좀 더 낮은 값이다.
java -XX:+UnlockDiagnosticVMOptions -Xlog:gc+heap+coops=debug -Xmx31G -version
(error) Unrecognized option: -Xlog:gc+heap+coops=debug
-XX:+UnlockDiagnosticVMOptions
: 이 옵션은 진단 VM 옵션을 활성화하는 것으로, VM 내부 동작을 조사하고 분석하기 위한 디버깅 옵션을 사용할 수 있도록 합니다.-Xlog:gc+heap+coops=debug
: 이 옵션은 가비지 컬렉션(GC), 힙(heap), 및 COOPs (Compressed Oops)와 관련된 디버그 레벨의 로깅을 활성화합니다. 이렇게 하면 GC 동작 및 메모리 할당에 대한 자세한 정보를 얻을 수 있습니다.Xmx31G
: 이 옵션은 Java 프로세스의 최대 힙 크기를 31 기가바이트로 설정합니다. 이렇게 하면 애플리케이션이 사용할 수 있는 최대 힙 메모리 양을 제한합니다.
<결론>
- zero-based 를 적용하는게 더 나은지 안 나은지 테스트하기 어려운 상황이면 속편하게 zero-based 적용 선까지 메모리 최댓값을 낮추자.
- 최소 Compressed OOPs 는 까지는 적용되어야 한다.
서버 메모리가 128GB 이상이라면?
- keyword, log, date 등
doc_values
를 쓰는 타입에 대해 정렬, 집계가 많은 경우
→ 서버에 노드 1개만 32GB 로 띄워라. doc_values
는 파일 시스템 캐시를 많이 쓰니까 남는 메모리는 OS 가 쓰게 냅둔다.
- text 인
fielddata
타입에 대한 정렬, 집계가 많은 경우
→ fielddata
는 힙에 저장하니까 32GB 씩 2개 띄우는게 나을 수 있다.
=> 반드시 정답은 아니므로 성능 테스트 해보고 결정하자
스와핑은 완전히 끄는게 좋다
스와핑하면 ms 단위로 끝날 GC 를 분단위 까지 걸리게 만드므로 쓰지 않도록 강력히 권고한다. 스와핑하느니 운영체제가 노드를 kill 시키게 놔두는 것이 낫다고 한다.
vm.max_map_count
최대 몇 개까지 메모리 맵 영역을 가질 수 있는지 설정하는 값이다. 최대치를 규정하는 값이라 매우 높게 설정하더라도 메모리 사용량이나 성능상 손해는 없다고 알려져 있다.
ES 기동하려면 262144보다 높은 값을 설정해야 한다.
💡 메모리 맵 이란?
작성된 코드를 실행파일로 만들어 os 에서 실행할 때 각 데이터 영역을 메모리의 어디 지역을 쓸 것인지 분류별로 나눠 매핑한 지도
https://www.gimsesu.me/elasticsearch-change-vm-max-map-count
File descriptor
리눅스는 많은 파일을 다루기 때문에 최소 65534 이상으로 지정한다.
💡 파일 디스크립터 란?
파일을 관리하거나 접근할 때 쓰는 ID 같은 개념.
흔히 유닉스 시스템에서 모든 것을 파일이라고 한다. 일반적인 정규파일부터 디렉토리, 소켓, 파이프, 블록 디바이스, 케릭터 디바이스 등 모든 객체들을 파일로 관리한다.
유닉스 시스템에서 프로세스가 이 파일들을 접근할 때 파일 디스크립터라는 개념일 이용한다.
클러스터 구성 전략
마스터 후보 노드와 데이터 노드를 분리해야 하는 이유
① 만약 분리해 두지 않았다면..
- 상대적으로 데이터 노드가 죽는 경우가 많은데, 마스터 역할까지 없어져 버리면 클러스터 안정성이 매우 떨어지고 전체 장애 상황으로 이어질 수 있다.
분리해뒀다면
- 데이터노드가 죽으면 마스터노드가 레플리카를 프라이머리로 승격시키고 레플리카 새로 채우면서 클러스터 복구 했을 것이다. (=서비스 고가용성)
② 만약 분리해 두지 않았다면..
- 장애상황에서 불필요하게 데이터 노드가 재시작 되는 경우 → 샤드복구 과정이 수행됨 → 부하가 더 심각하게 장애 상황을 몰아갈 수도 있다.
- 장애상황에서 불필요하게 마스터 노드가 재시작 되는 경우 → 마스터 재선출 과정이 발생 → 네트워크나 GC 이슈 있으면 마스터를 잘 못찾을 수도 있다.
마스터 후보 노드 관리 가이드
-투표 구성원은 마스터 후보 노드의 일부 또는 전체로, 과반 이상 동의하면 마스터가 결정된다.
- 그래서 투표 구성원이 절반 이상 다운되면 투표 못하는 상황에 빠짐!
-마스터 후보 노드가 새로 들어오거나 나갈 때 투표 구성원을 자동 조정하기 때문에 넣고 뺄땐 천천히 하는게 좋다.
-투표 개념이 도입된 ES 7 이상부터 split brain 이 원천적으로 일어나지 않는다. 그래도 홀수대 마스터 후보를 준비하는 게 좋다.
- 과반 이상인 투표 형태 만들기 위해 어차피 하나는 투표 구성원에서 빼둠. 그래서 짝수로 하는게 노드가 하나씩 죽는 경우에는 스페어가 있으므로 안정성은 있지만 모두 한 번에 죽어버리면 소용 없으므로 홀수로 준비하는게 비용 대비 효용성이 좋다.
서버 자원이 많지 않을 때
적어도 마스터 후보 노드 3개, 데이터 노드 3개는 확보돼야 기본적인 고가용성이 제공된다.
최소 구성, 장비 3대
3대 모두 마스터 후보, 데이터 노드 겸임하는 방법밖에 없지 뭐
사양 낮은 장비 4~5대
3대: 마스터 후보, 데이터 노드 겸임
2대: 데이터 노드 전용
사양 높은 장비 4~5대
일단 같은 비용으로 사양 낮은 장비 3대랑 좀 더 높은 3~4대로 구성가능한지 알아보고
- 되면 사양 낮은 3개를 마스터에게 주기
- 안되면 똑같이 3대는 마스터, 데이터 노드 겸임하고 2대는 데이터 노드 전용
장비 6~7대
역할 분리 가능!
3대 마스터 후보 노드 전용, 나머지 데이터 노드 전용
서버 자원이 굉장히 많이 필요할 때
물리 서버가 200대 이상인 경우
-먼저 클러스터를 잘게 쪼갤 수 있는지 본다. 기본적으로 마스터는 클러스터 당 한 개이기 때문!
-그렇수 없다면 마스터 후보 노드 사양도 높은 서버로 준비한다. 그래도 언젠간 못 버티는 상황이 올 것.
-같은 데이터로 싱크 맞춘 클러스터를 여러 개 구성하고 로드 밸런싱 / 클러스터 별 샤딩 전략 / 클러스터 간 검색 도입 고려
사양이 크게 나는 서버일 때
데이터 티어 구조 도입 고려
- 성능 좋은 건
data_content
,data_hot
노드로, 낮은건data_warm
,data_cold
,data_frozen
노드로 - ILM 도입해 오래된 인덱스를 낮은 티어로 이동
하지만 단점도 있기 때문에 판단이 필요..!
- 가장 아래 티어가 가장 낮은 서버인데 아량의 오래된 데이터를 들고 있는 상태에서 계속 복제 받아야 하는 상황이라 퍼포먼스 떨어지면 클러스터 전체 안정성에 영향 미칠 수 있다.
data_hot
노드 인덱스를data_warm
으로 이동하는 작업에도 클러스터에 부하를 준다.
조정 전용 노드
-작업한 결과물을 모아서 돌려주는 작업은 생각보다 큰 부하 줄 수 있기 때문에 node.roles: []
를 지정해 조정 전용 노드를 두는 것이 좋다.
-특히 키바나는 직관적인 UI 를 갖고 있기 때문에 ES 동작 이해도가 없는 상태에서 조작하다보면 부하가 큰 요청을 날려 장애 발생시킬 수 있다.
- 키바나가 조정 전용 노드만 바라보게 설정하자
-읽기 담당 조정 노드와 쓰기 담당 조정 노드를 분리하는 것도 안정성을 높일 수 있다.
- 장애 발생 시 쓰기는 멈추더라도 읽기는 계속 제공해야 한다면 쓰기 노드를 내리고 샤드 복구 기다리면 된다. 샤드 복구는 프라이머리 내용과 레플리카 내용 비교해서 필요한 작업만 재처리 해주는데 데이터 업데이트가 계속 늘어나면 데이터 간 차이가 벌어져 복구 속도가 느려지기 때문이다.
- 반대로 쓰기 요청은 계속 받아야하는데 키바나 같은 거 때문에 과도한 읽기 요청이 온다면 읽기 노드만 내리면 된다.
-데이터 노드보다 낮은 사양으로 구성해도 되지만, 무거운 집계 작업이 주가 되는 클러스터면 좋은 사양으로 구성한다.
-ES 7부터 도입된 메모리 서킷 브레이커가, 조정 노드 메모리 사용량이 높아지면 차단해준다.
한 서버에 여러 프로세스 띄우기 가이드
-마스터 후보 노드는 여러 프로세스 대상으로 고려하지 않는다. 안정성이 크게 떨어지기 때문이다.
-여러 프로세스 대상은 데이터 노드여야 한다.
-cluster.name
은 같게, node.name
, http/transport port
, path.logs
, path.data
는 다르게
-cluster.routing.allocation.same_shard.host: true
로 설정. 같은 샤드의 프라이머리와 레플리카가 한 서버에 몰리지 않게 조정해준다.
-기본적으로 ES 는 CPU 코어 개수로 스레드 풀 크기를 조정하기 때문에 [node.processors](https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-threadpool.html#node.processors "https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-threadpool.html#node.processors")
에서 수동으로 지정해준다. (ex. 16 코어면 8로 설정)
보안 기능 적용
xpack.security.enabled: true
ES 8부터는 기본값 true로 변경됨
[[https 원리]] [[TLS (Transport Layer Security)]]
TLS 부트스트랩 체크
-노드 간 transport 통신에 TLS 적용하지 않으면 기동을 거부한다. (discovery.type:single-node
제외)
-근데 처음 보안 설정하려면 클러스터 기동한 상태에서 할 수 있다!?
→ 부트스트랩 우회해서 기동하고 설정하면됨!
이거 하나면 끝! 노드 추가나 키바나 기동할 때 한방에 되는 enrollment token 생성 및 사용하기
ES 8 ~
Start the Elastic Stack with security enabled automatically
Elasticsearch, Kibana, Beats, Logstash의 보안을 유지하기 위한 SSL, TLS, HTTPS 구성
enrollment 토큰 생성
클러스터 중 한 대 노드에 elasticsearch.yml
설정 후 데몬 말고 바로 기동
elasticsearch.yml
node.roles: [master, data]
discovery.type: "single-node"
...
-single-node
: TLS 부트스트랩 회피 목적
-cluster.initial_master_nodes
, xpack.security.enabled
는 추가하지 않는다.
콘솔에 출력된 enrollment 토큰 복붙해놓는다. 바로 종료해보면 certs 파일이 생기고 elasticsearch.yml 이 업데이트 되어 있을 것이다.끝.
enrollment 토큰으로 노드 추가하기
-elasticsearch.yml 에 cluster.initial_master_nodes
, xpack.security.enabled
, discovery.seed_hosts
, discovery.type
는 추가하지 않는다.
-마스터 후보 노드 먼저 elasticsearch -d --enrollment-token ...
커맨드를 실행하면 자동으로 합류되고 elasticsearch.yml 이 업데이트된다.
초기 비번 설정
클러스터 노드 아무데나에서 아래 커맨드 실행해 초기 비번 설정한다.
elasticsearch-reset-password --interactive -u lastic
enrollment 토큰으로 키바나 연동하기
-kibana.yml 에 elasticsearch.hosts
는 지정하지 않는다.
-연동 완료하면 kibana.yml 가 업데이트 된다.
※ 키바나와 브라우저 사이에 TLS 적용은 책 참고
※ 수동으로 TLS 적용하는 거도 책 참고
레퍼런스
엘라스틱서치 바이블 5장
'SearchDeveloper > 엘라스틱서치 바이블' 카테고리의 다른 글
[7] 운영 도중 발생하는 장애 대응 (0) | 2024.03.31 |
---|---|
[6] 클러스터 운영 (0) | 2024.03.31 |
[4] 데이터 다루기 (0) | 2024.03.31 |
[3] 인덱스 설계 (1) | 2024.01.14 |
[2] 엘라스틱서치 기본 동작과 구조 (0) | 2024.01.14 |