Logging

[책 리뷰] 기초부터 다지는 ElasticSearch 운영 노하우 #1

토마스.dev 2024. 1. 9. 07:08

예전에 전 회사에서 로깅시스템을 관리할 때 강진우님의 블로그를 많이 참고 했었는데, 최근 다시 로깅시스템을 자세히 봐야하는 상황이 됐고 그 사이에 책을 내셨다는걸 알았다.

 

책에 담긴 내용은 역시나 매우 유용한 정보였고(7버전 정도까지만 언급한다는 점이 살짝 아쉽지만, 21년도 판이니..), 책에 대해서 간단히 리뷰해보고자 한다.

 

말이 리뷰지, 모든 내용을 담아도 문제고, 나같은 초보자가 평가를 할수도 없기에 업무하면서 참고할만한 내용들을 간단히 정리하고자 한다.

 

노드 타입

- 마스터: 클러스터 상태 관리. 매우 중요

- 데이터: 데이터 저장 담당

- 인제스트(ingest): 데이터 인입 전담

- 코디네이트(coordinate): 모든 서버 기본값이며 검색 요청 담당

그 밖에도 세부적으로 나뉘기도 하는거 같다.

https://www.elastic.co/guide/en/elasticsearch/reference/7.17/modules-node.html#modules-node

노드 타입은 설정파일에 기술하면된다.

샤드와 세그먼트

샤드: 인덱스에 색인되는 문서들이 저장되는 논리적인 공간

세그먼트: 샤드 데이터들이 실제 물리적으로 저장되는 파일

샤드:세그먼트=1:N 관계이다.

 

세그먼트는 Apache Lucene 의 개념이다. 샤드는 루씬 인스턴스라고 한다.

즉, ElasticSearch는 여러개의 인덱스를 가지고 있으며, 이 인덱스는 다시 여러개의 샤드를 가지는데, 샤드는 루씬 인스턴스이고, 이를 물리적으로 저장하는 파일이 세그먼트이다. 세그먼트는 필요에 따라(혹은 자동적으로) Compaction 과정을 거쳐서 여러개의 세그먼트가 하나로 머지될수 있으며 이때 최적화 과정이 이루어진다.

 

프라이머리 샤드와 레플리카 샤드

HA를 위해서 Replica를 사용해야한다. kafka랑은 다르게 replica 설정하는 값은 순수 복제 샤드개수를 의미한다(kafka는 primary를 포함한 값. 원래 ES에서 설정하는 개념이 맞는거 같은데?). 보통 같은 데이터를 가진 레플리카 샤드는 프라이머리 샤드와 같은 노드에 배치되지 않는다.

 

프라이머리 개수 설정은 동적으로 변경되는게 아니다.

레플리카 개수 설정은 동적으로 가능하다.

 

매핑

정적 설정을 하지 않으면, 동적으로 설정된다. 동적인 경우 텍스트는 모두 text (with keyword)타입이 되고, 숫자인 경우 정수형은 long, 소수점은 double이 된다고 한다.

 

클러스터 설정 파일

메모리: 스왑을 사용하지 않도록 해야한다. JVM은 최대 32G만을 사용하도록 하고(Compressed OOP), 전체 시스템에서 절반정도만 할당한다. 그러므로 1개 노드의 최대 사이즈는 64G정도로 본다. 절반을 할당하는 이유는 세그먼트 저장시 I/O가 발생하며 이때 OS에서는 보통 페이지캐시 기법을 사용하기 때문에 이를 위한거라고 생각하면 된다.

 

- 마스터의 개수는 정족수 개념으로 개수를 설정해야한다. 3,5 (아마도 7 이상은 성능 문제로 잘 안쓸듯하다) active-standby 형태이다.

- 클러스터내 노드를 전부 재시작할때 최소 몇개 노드가 정상일때 복구를 시작할지도 설정할 수 있다.

- _all 이나 와일드카드로 삭제를 방지하는 설정도 있다.

 

버전 업그레이드

버전 업그레이드에는 클러스터를 중지하고 한꺼번에 올리는거랑, 무중단으로 하는 롤링 업데이트가 있는데, 롤링 업데이트에 대해서만 얘기하면, 노드를 하나씩 올려야하므로 해당 노드를 비활성화 시키고 해야한다.

 

1. 샤드 할당 기능 비활성화: 해당 노드에 배치가 되면 안되므로

2. 프라이머리 샤드와 레플리카 샤드 데이터 동기화

3. 노드 한대 업그레이드한 후 다시 클러스터 조인

4. 샤드 할당 기능 활성화 -> 클러스터 "그린" 상태 확인 후 1번부터 계속 반복

 

ES는 5부터 8까지 급격한 버전 변화를 겪었고, 인터페이스가 많이 바뀌는 편이다. 그렇기에 5 -> 7 또는 8로 바로 되는게 아니고 중간에 거쳐야한다. 5는 보통 6.8버전을 거쳐서 7.8 버전으로 업글해야 한다.

 

5~5.5 > 5.6~6.7 > 6.8~7.7 > 7.8 

 

샤드 배치 방식 변경

원래 자동으로 배치하지만 장애나, 업글로 수동으로 배치해야할 경우도 있다.

- reroute: 하나하나 수동으로 특정 노드에 배치할때 사용

- allocation: 자동으로 배치할때 어떤 방식으로 할지를 결정

  - all: 프라이머리/레플리카 샤드 전부 배치 허용

  - primaries: 프라이머리 샤드만 배치 허용

  - new_primaries: 새롭게 생성되는 인덱스에 한해 프라이머리 샤드만 배치 허용

  - none: 모든 샤드의 배치 작업을 비활성화(업글할때 사용)

  - null: 초기값으로 리셋

- rebalance: 재배치할때 방식

  - allocation은 노드 추가나 이탈 되어있을때 동작과 관계가 있고, rebalance는 특정 노드에 샤드가 몰려있다던지 하는 불균형 상태일때의 동작과 관련. 디스크 임계치 등의 값에 의해 재배치가 동작할때의 설정이라고 보면된다. 전체 노드가 임계치를 넘어섰다면 인덱스가 read only 모드로 변경된다고 한다. 버전 7 이상에서는 임계치 이하로 내려가면 read only 모드가 해제된다고 한다.

- filtering: 특정 조건에 해당되는 샤드들을 특정 노드에 배치할때

 

클러스터와 인덱스 설정 변경

- 설정 우선 순위: 임시(transient) > 영구(persistent) > 파일(yaml) 로 임시가 가장 높다.

- 인덱스 복구시 사용가능한 최대 네트워크도 임시적으로 설정 가능

 

인덱스 API

- alias API: 여러개의 인덱스를 하나의 논리적인 인덱스 별칭으로 사용할 수 있다. 날짜별로 분리되는 로그 인덱스를 계속 같은 이름의 인덱스로 사용하고 싶을때 사용할 수 있다. 반대로, 날짜별로 로그데이터가 크지 않아 인덱스를 분리하고 싶지 않을때 1개의 샤드를 날짜별로 별칭을 부여해서 사용할 수도 있다.

- rollover API: 위에 alias API와 더불어서 인덱스에 특정 조건을 설정하여 해당 조건을 만족하면 인덱스를 새로 만들고, 새로 만든 인덱스로 요청을 받게하는 API. 조건에는 시간,문서수,사이즈수 등을 지정할 수 있다.

- forcemerge API: 수동으로 세그먼트 병합머지 API

- reindex API: 인덱스를 복사하는 API.