es를 사용하기 전 반드시 알아야 하는 기본 개념을 정리하는 포스팅이다.
es는 하나 이상의 노드로 이루어진 클러스터로 구성된다. 클러스터에 노드를 하나 이상 둠으로써 노드 하나가 다운되어도 다른 노드들이 계속 es에 들어오는 요청을 처리할 수 있도록 하여 정상적으로 운영이 가능하도록 한다.
es에 데이터(es 용어로는 도큐먼트) 처리 요청이 들어오면 이 노드들에 요청이 분산되어 데이터 인덱싱 및 저장 처리가 이루어진다.
사진 출처: https://esbook.kimjmin.net/03-cluster/3.1-cluster-settings
Elasticsearch의 노드들은 http 포트(포트번호: 9200~9299)로 클라이언트와 통신하고 tcp 포트 (9300~9399)로 노드 간 통신을 한다. 포트 번호의 기본값은 각각 9200, 9300이며 노드가 추가될 때마다 +1씩 증가한다.
내가 생각하는 이상적인 클러스터 구성은 아래와 같다.
목적에 따라 클러스터를 구분한다.
ex) 로그 데이터 수집이라는 요구사항과 매일 새벽마다 DB 데이터를 es에 인덱싱해야 한다는 요구사항이 있다면 로깅용 클러스터 1대와, DB 데이터 처리용 클러스터 1대를 둔다.
사유: 서비스 트래픽이 증가하면 로그 데이티도 많이 나와서 es에 가해지는 부담도 커지기 때문에 이에 대비하여 클러스터 및 노드를 구성해야 한다. 이렇게 로그 데이터에 맞춰 구된 클러스터는 상대적으로 트래픽이 덜한 DB 데이터 인덱싱 요구사항에 오버스펙일 수 있다.
로그 데이터 역시 어떤 프로덕트의 로그인가에 따라 구분되어야 할 수 있다. 이는 인덱스 단위로 구분한다.
클러스터에 최소 3대 이상의 노드를 배치하고, 물리 서버 1대에 노드 1개를 배정한다.
클러스터에 최소 3대 이상의 노드를 배치하는건 es가 권장하는 프로덕션 레벨에서 지켜져야 하는 규칙이다. (이유는 다른 포스팅에서 설명하겠다.)
물리 서버 1대에 여러 대의 노드를 설치하여 기동시킬 수 있다. 다만 해당 서버가 과도한 트래픽으로 다운되면 여러 개의 노드를 한꺼번에 잃기 때문이 서버 1대당 노드 1개가 가장 이상적이라고 생각한다.
es의 단일 데이터 단위. es에 인덱싱하고자 하는 데이터를 말하며 json 형태이다.
# 도큐먼트 예시
{
"_id": 1,
"product: "order",
"log_type": "info"
"log_message":"Hello, Elasticsearch!"
}
도큐먼트를 모아놓은 집합을 인덱스(Index) 라고 한다. 도큐먼트를 구분하는 추상적인 개념이다.
단일 루씬 검색 인스턴스로 클러스터에 있는 데이터의 하위 집합에 대한 쿼리를 색인하고 처리하는 자체 포함 검색 엔진이다. 각 인덱스는 하나 이상의 샤드로 구성된다. 인덱스 하나에 3개의 샤드가 구성되어 있다면 인덱스는 3개의 샤드로 나누어져서 노드에 분산 저장된다.
처음 생성된 샤드를 프라이머리 샤드(Primary Shard), 복제본은 리플리카(Replica)라고 지칭한다. 리플리카 수는 인덱스를 생성한 이후에도 변경 가능하나 프라이머리 샤드 수는 인덱스를 생성한 이후에는 고정이다.
ex) 인덱스 1개에 프라이머리 샤드 수를 3개, 레플리카 수를 1개로 설정한다면
인덱스 1개는 프라이머리 샤드 3개에 나눠서 인덱싱되고, 이 프라이머리 샤드 각각이 레플리카 1개씩으로 복제된다.
P1 | P2 | P3
P1의 R1 | P2의 R2 | P3의 R3
이 경우에는 P1과 R1이 동일한 데이터를 갖고 있고, 이 두 샤드가 노드 A에 같이 저장되지 않는다. P1이 노드 A에 있고 R2가 노드 B에 있다면 노드 A가 다운되어 복구되지 않을 때 es는 노드 B에 있는 R2를 복제하여 샤드 수를 유지한다.
공식문서 원본 참고:
An Elasticsearch index is really just a logical grouping of one or more physical shards, where each shard is actually a self-contained index.
...
There are two types of shards: primaries and replicas. Each document in an index belongs to one primary shard. A replica shard is a copy of a primary shard. Replicas provide redundant copies of your data to protect against hardware failure and increase capacity to serve read requests like searching or retrieving a document.
...
The number of primary shards in an index is fixed at the time that an index is created, but the number of replica shards can be changed at any time, without interrupting indexing or query operations.
primary와 replica를 나누어 관리함으로서 redundancy를 보장하여 노드 다운과 같은 하드웨어 고장과 같은 상황에 대비한다. 노드 하나가 다운되어도 다른 노드에 있는 복제본 or primary 데이터를 사용하면 되기 때문이다.
또한 인덱스 하나에 여러 개의 샤드를 둘 수 있는 환경은 병렬 처리를 보장할 수 있다. 만약 인덱스 하나에 샤드 하나만 있다면 검색 요청 100건을 샤드 하나가 전부 처리해야할 것이다. primary, replica 샤드 1개씩 총 두 개의 샤드로 나눠서 처리한다면 병렬 처리가 가능하다 (replica 샤드라도 검색 요청은 처리할 수 있음)
그렇다고 해서 인덱스 당 샤드 개수를 무한정 늘리는 건 좋지 않다. 샤드 개수가 증가하면 샤드 당 크기가 작아지고, 이는 세그먼트가 작아져 클러스터 내 오버헤드가 증가할 수 있어 시스템 다운으로까지 이어질 수 있기 때문이다. 잘못된 샤드 전략을 채택해서 ES가 다운되는 경우도 자주 발생한다.
샤드 개수와 크기는 ES의 안정성과 직결되는 문제이기 때문에 설정을 제대로 하는게 매우 중요하다. 특히 primary 샤드의 경우 인덱스를 만들 때 설정하고 이후에는 변경할 수 없다. 이에 관련된 내용은 이후 포스팅에서 다루겠다.
es에서 노드는 여러가지 유형이 있으며, 노드 하나당 여러 개의 역할을 동시에 맡을 수 있다(마스터 노드 제외). 버전 7 기준 특정 역할을 지정해주지 않으면 해당 노드는 모든 역할을 수행한다.
인덱스를 생성하거나, 어느 샤드가 어떤 노드에 할당될지 결정하는 등의 클러스터를 제어하는 역할을 한다. 클러스터 내 1개 있다.
위 마스터 노드로 선출될 수 있는 노드를 말한다. 마스터 노드가 다운되었을 때 es는 노드들끼리 voting 과정을 통해 새로운 마스터 노드를 선출하는데, 이 선출 시에 후보가 될 수 있는 노드를 말한다. 마스터 후보 노드이면서 데이터 노드나 코디네이팅 노드 역할도 맡을 수 있다.
오로지 마스터 후보 역할만 맡은 노드를 말한다. 클러스터 규모가 크다면 마스터 후보 노드를 모두 전용 마스터 후보 노드로 두는 것이 좋다.
공식문서 원문 참고:
The most reliable way to avoid overloading the master with other tasks is to configure all the master-eligible nodes to be dedicated master-eligible nodes which only have the master role, allowing them to focus on managing the cluster.
노드를 새로 생성해 클러스터에 추가할 수 있다. 이러한 확장성을 보장하기 위해 새로운 노드를 발견하는 discovery 과정이 필요하다. 또한 마스터 노드가 다운되었을 때 새로운 마스터 노드를 선출하는 voting 과정을 통해 hardware failure에 대비한다. 이 두 개념은 다음 포스팅에서 더 자세히 다루겠다.