본 글은 인프런의 ElasticSearch 강의를 듣고 정리한 내용이다. 출처가 궁금하신 분들은 아래 링크를 참조하면 좋겠다.
https://www.inflearn.com/course/elasticsearch-essential/dashboard
ES 적용 전에 ES 가 무엇인지, 어떻게 동작하는지에 대해 정리하는 게 필요하다고 생각해서 듣게 된 강의인데 아무래도 ES를 이미 적용해서 사용하고 있는 분들이 들으면 좀 더 도움이 될 것 같았다. ( 트러블 슈팅에 관한 내용이 후반부에 나온다 ) 아예 내용을 모르니까 이해가 안 가는 부분이 있어서 직접 설치해서 실행해 보면서 보완했다.
그래도 전반적으로 기본적인 노드, 인덱스, 샤드 개념들을 알 수 있어서 좋았다.
ElasticSearch 란?
루씬 ( Lucene ) 기반의 오픈 소스 검색 엔진이다. 자바 기반의 라이브러리이며, json 형식 기반의 문서를 저장하고 검색할 수 있다.
ElasticSearch의 특징
- 준 실시간 검색 시스템
- 실시간이라고 생각될 만큼 색인된 데이터가 빠르게 검색이 됨 -> 색인이 되고 일초 이내로 검색이 됨
- 고가용성을 위해서 클러스터를 구성할 수 있음 -> 한대 이상의 노드로 클러스터를 구성하여 높은 수준의 안전성을 달성하고 부하 분산이 가능해짐
- 동적 스키마 생성 -> 입력될 데이터들에 대해 미리 스키마를 정의하지 않아도 동적으로 스키마 생성이 가능함
- RDBMS에서는 스키마를 미리 생성해야 입력 됐지만 ES에서는 미리 구현하지 않아도 사용할 수 있음
- restAPI 기반의 인터페이스를 제공함 -> restAPI 가 제공하는 기능을 충분하게 이용할 수 있음
여기서 클러스터를 구성할 수 있다는 의미를 이해하기 위해서는 먼저 클러스터가 무엇인지 알아야 한다.
- 클러스터란?
컴퓨터 클러스터는 여러 대의 컴퓨터들이 연결되어 하나의 시스템처럼 동작하는 컴퓨터들의 집합을 이야기한다.
즉, ES 도 여러 대의 노드들이 각자의 역할을 바탕으로 연결되어 하나의 시스템처럼 동작하게 되어 있다. 만약 클러스터의 성능이 부족하면 노드를 늘려서 대응할 수 있지만, 노드를 늘리는 게 성능을 늘리는 완벽한 대응책이 될 수는 없다.
단순하게 생각하면 처리하는 노드가 늘어나니 성능 개선이 당연하게 따라오는 게 아닌가 싶지만, 내부 동작과정을 알면 그렇지 않다는 걸 알 수 있다. 그전에, 노드의 종류가 무엇인지부터 차근차근 알아보자.
- 노드의 종류
노드의 종류는 마스터 노드, 데이터 노드, 코디네이팅 노드, 인제스트 노드로 구성된다.
종류 | 역할 |
마스터 노드 | 클러스터 상태 관리 및 메타 데이터 관리 |
데이터 노드 | 문서 색인 및 검색 요청 처리 |
코디네이팅 노드 | 검색 요청 처리 |
인제스트 노드 | 색인되는 문서의 데이터 전처리 |
여기서 마스터 노드는 마스터 노드와 마스터 후보 노드 ( mater-eligible)로 구분되는데, 마스터 노드가 죽으면 후보 노드 중에서 새로운 마스터 노드가 선택된다.
그렇다면 클라이언트의 요청은 어떤 노드가 처리하게 될까?
정답은 '어떤 노드에 요청해도 동일한 응답을 준다' 다.
예를 들어, 마스터 노드에 전달할 경우 요청을 처리할 수 있는 데이터 노드에 전달한다. 데이터 노드에 바로 전달한다면 데이터 노드가 바로 처리한다. 그렇지만 클라이언트에서 요청을 보낼 때는 일반적으로 노드들 앞단에 로드밸런스를 두고 처리하는 게 좋다.
로드밸런서가 있으면 어떤 데이터 노드가 처리할 일인지 확인하고 분배해 주는 역할을 하기 때문이다. ( 같은 의미에서 코디네이팅 노드 앞단에도 로드밸런서가 있는 구조가 좋다 )
이런 식으로 각각의 노드들이 자기의 역할에 최선을 다할 수 있도록 구성하는 것이 핵심이다.
인덱스(index)와 샤드(Shard) 이해하기
일반적으로 RDBMS의 경우, database를 만들고, 스키마를 정의하고, row를 삽입하여 데이터를 정의하는 과정을 거친다.
여기서 database 가 index, mapping 이 schema, document 가 row에 해당한다. 이 내용을 기억하고 있으면 ES의 동작 방식을 이해하기 훨씬 쉽다.
ES | RDBMS |
index | database |
mapping | schema |
document | row |
아, 그런데 강의를 듣고 관련 정보를 찾던 도중 7.0 이상 버전부터 mapping type 삭제 이슈가 있어서 가져와봤다.
https://www.elastic.co/guide/en/elasticsearch/reference/7.17/removal-of-types.html
기존에 RDBMS에서 table에 mappingtype을 비교했는데, table 은 동일한 column 명을 가져도 데이터가 table 단위로 독립적으로 구분되지만, ES에서는 다른 table에서 동일한 column 명을 가지게 되면 같이 묶여서 처리되는 게 문제가 됐다는 내용이다. 즉 같은 index 안에 mappingtype 은 다른데 field 명이 동일할 경우 함께 취급되게 동작해서, mappingtype 개념을 삭제하고 하나의 index 에는 하나의 mappingtype 만 지정할 수 있도록 변경 됐다고 한다.
이렇게 되면 얻을 수 있는 이점이 있는데 너무 길어서 chatGPT의 힘을 빌렸다.
- ChatGPT 요약문 첨부
Elasticsearch에서 mapping type이 삭제되는 이유는 주로 Elasticsearch의 버전 7.0부터 이후의 변경 사항과 관련이 있습니다. 이전 버전에서는 하나의 인덱스 내에서 여러 가지 유형의 문서를 처리하기 위해 mapping type을 사용했습니다. 그러나 Elasticsearch 7.0부터는 하나의 인덱스 내에 여러 개의 매핑 유형을 사용하는 것이 더 이상 허용되지 않습니다. 대신, 하나의 인덱스는 하나의 매핑 유형만을 가질 수 있습니다.
따라서 Elasticsearch에서 mapping type이 삭제되는 주요 이유는 다음과 같습니다:
- 단순화된 데이터 구조: 매핑 유형을 삭제함으로써 Elasticsearch의 내부 구조가 단순화되고 관리가 쉬워집니다. 이전에는 여러 매핑 유형이 하나의 인덱스 내에 혼합되어 있어 복잡성이 증가할 수 있었습니다.
- 성능 향상: 하나의 매핑 유형만을 사용함으로써 Elasticsearch의 내부 처리가 최적화되고 검색 및 색인 작업의 성능이 향상됩니다.
- 유지 관리 용이성: 단일 매핑 유형을 유지함으로써 인덱스의 구조를 이해하고 관리하기가 더욱 간단해집니다. 개발자 및 관리자는 하나의 매핑 유형만을 고려하면 되므로 혼란을 줄일 수 있습니다.
- 비용 감소: Elasticsearch의 내부 동작을 단순화함으로써 유지 보수 및 운영 비용을 줄일 수 있습니다.
요약하자면, Elasticsearch에서 mapping type이 삭제된 이유는 주로 단순화된 구조, 성능 향상, 유지 관리 용이성, 비용 감소 등의 이점을 얻기 위함입니다.
- 인덱스란?
문서(document)가 저장되는 논리적인 공간을 의미한다. 문서(document)를 저장하기 위해서는 반드시 인덱스가 존재해야 한다.
따라서, 인덱스 설계를 하는 것이 ES를 사용하기 위해 고려해야 하는 첫 번째 단계가 된다.
간단하게 표현하면, 인덱스 설계는 문서를 어떻게 저장할 것인가? 에 대한 결과라고 할 수 있다.
- 인덱스 설계
예를 들어 도서관 자료 검색 시스템을 만든다고 가정하자. 한 번에 모든 자료를 저장할 것인지, 자료의 분류에 따라서 저장할 것인지를 정하는 것이 설계이다. 사용 패턴과 문서(document)의 특징이 설계할 때 기준점이 된다.
하나의 인덱스를 사용한다면 관리해야 할 인덱스의 수가 적어 관리 리소스가 적게 발생한다는 장점이 있지만 쿼리와 문서(document)의 구조가 복잡해질 수 있다는 단점이 있다.
반대로 여러 개의 인덱스로 사용한다면 각각의 경우에 최적화된 쿼리와 문서(document) 구조를 사용할 수 있다는 장점이 있지만 관리해야 할 인덱스의 수가 늘어남에 따라 관리를 위한 리소스가 추가적으로 발생한다는 단점이 있다.
일반적으로는 하나의 인덱스로 단순하게 시작했다가 지원하는 서비스의 사용 패턴에 따라 인덱스를 별도로 운영하는 것이 가장 좋은 방식이다. ( 나중에 무조건 인덱스를 별도로 운영하라는 것이 아니라, 사용량이 증가하여 성능 향상의 이슈가 있을 때만 해당한다. )
- 샤드(shard) 란?
인덱스에 색인되는 문서가 저장되는 공간이 샤드다. 하나의 인덱스는 반드시 하나 이상의 샤드를 가진다.
샤드의 종류는 프라이머리 샤드와 레플리카 샤드로 나뉜다.
프라이머리 샤드 | 문서가 저장되는 원본 샤드를 의미함. 색인과 검색 성능에 모두 영향을 줄 수 있음 |
레플리카 샤드 | 프라이머리 샤드의 복제 샤드로 검색 성능에 영향을 준다. 프라이머리 샤드에 문제가 생기면 레플리카 샤드가 프라이머리 샤드로 승격 된다 |
실제 데이터로 보면 다음과 같다.
{
"index" : {
"number_of_shards" : 5,
"number_of_replicas" : 2
}
}
-> number_of_shards 는 프라이머리 샤드를 의미한다. 즉 프라이머리 샤드는 5개가 있다
-> 레플리카 샤드는 총 10 개가 있는 것이다. ( 프라이머리 샤드의 복제본이므로 복제본이 2개 있다고 생각하면 된다 )
- 샤드의 라우팅
문서(document)가 저장되는 방법을 의미한다. 샤드의 개수가 바뀌면 문서(document)가 저장되는 규칙이 완전히 바뀐다. ( 단순하게 생각하면 당연한 것이다. 저장하는 칸이 나뉘었는데 위치가 기존과 같을 수 없다 )
그런데 샤드의 개수는 한번 지정하면 바꿀 수가 없다.
따라서 인덱스를 생성할 때 프라이머리 샤드의 개수를 설정하는 것은 매우 중요하다.
라우팅 룰 ( routing rule ) : 문서의 ID % 샤드의 개수
일반적으로 샤드의 기본값 ( number_of_shards )은 1인데 이걸 그대로 사용하면 성능에 문제가 생길 수 있다.
- 인덱스 템플릿
인덱스는 많아지는데 인덱스에 설정해야 하는 샤드의 개수를 일일이 지정하려면 번거로운 일이 아닐 수 없다. 이를 해결하기 위해 인덱스 템플릿을 제공한다. 한번 설정해 두면 인덱스 생성이 편리해진다.
{
"index_patterns" : ["nginx-logs-*],
"template" : {
"settings" : {
"number_of_shards" : 3,
"number_of_replicas" : 2
}
}
}
index-patterns의 내용이 인덱스 템플릿이다. 'nginx-logs- 로 시작하는 모든 인덱스는 프라이머리 샤드 3개, 레플리카 샤드 6개로 생성한다'라는 의미를 가지고 있다.
매핑(mapping) 이해하기
매핑은 rdbms에서 스키마와 유사하다. 즉 문서의 구조를 나타내는 정보이다. 동적 스키마라는 단어 때문에 ES 가 스키마리스라는 오해를 받는데, 엄밀히 따지면 ES는 스키마리스인 것이 아니라, 스키마를 미리 정의하지 않아도 되는 것뿐이다.
매핑은 동적 매핑과 정적 매핑으로 나뉜다.
동적매핑 | 처음 색인되는 문서를 바탕으로 매핑 정보를 ES가 동적으로 생성 -> 어떤 문서가 색인될지 스키마를 미리 정의 하지 않아도 됨. |
정적매핑 | 문서의 매핑 정보를 미리 정의 ( 문서의 필드들이 가지는 값에 따라 타입을 지정해 줄 필요가 있을 때 ) -> 불필요한 색인이 발생하지 않게 하기 위해 ( keyword 같은게 필요 없을 경우) |
색인이란?
문서를 분석하고 저장하는 과정을 색인이라고 한다. ES는 역색인(inverted index)을 사용한다.
역색인은 쉽게 말해서 책 뒤에서 keyword를 통해 본문을 검색하는 것을 생각하면 된다. 내가 원하는 keyword 를 통해 역으로 문서 위치를 찾아가는 방식이다.
이 inverted index 가 cpu와 memory를 많이 잡아먹기 때문에 성능과 직결된다.
그렇기 때문에 적절한 수의 샤드를 설정하는 것이 성능에 큰 영향을 미친다. 단순히 노드 개수가 늘어난다고 해서 성능이 늘어나는 것이 아니라, 샤드의 배치가 적절해야 늘어난 노드를 '잘 사용할' 수 있다.
처음부터 완벽한 샤드 배치 계획을 세울 수는 없기 때문에, 샤드의 수를 늘리거나 데이터 노드를 스케일아웃/업 하면서 최적의 수치를 찾아가야 한다. ( -> 프라이머리 샤드는 변경할 수 없기 때문에 Reindex API를 사용해서 재색 인해야 함 )
색인 성능에 문제가 발생한다면 클러스터로서 이점을 살리고 있는가를 살펴보도록 하자.
'Dev > ELK' 카테고리의 다른 글
Springboot + ElasticSearch 연동하기 ( feat. RDBMS 에서 Like 를 사용할 때 보다 검색 속도가 얼마나 향상 될까? ) (1) | 2024.03.26 |
---|---|
MacOS 에서 ElasticSearch 설치하기 ( homebrew 사용 X ) (0) | 2024.03.13 |