Elastic Search가 무엇인지, Elastic Cluster에서 제공하는 Elastic Node 유형, ElasticSearch Replica, Segment 및 node 사이에 발생할 수 있는 SplitBranProblem에 대해서도 살펴보겠습니다.
what is Elastic Search
Elastic Search는 기본적으로 데이터 저장소입니다.
특징
NoSQL JSON 기반 스토리지.
Cluster 구성. Schemaless 구조입니다.
Rest API 기반의 간단한 인터페이스 제공
Cluster
ElasticSearch는 Cluster와 Node 환경을 제공합니다.
Cluster는 하나 이상의 Node(Server)를 모아서 전체 데이터를 저장하고 모든 Node를 포괄하는 통합 Indexing 및 검색 기능을 제공합니다.
Cluster 이름은 고유한 이름으로 식별되며 Default는 “elasticsearch”입니다.
Cluster 이름이 중요하지만 동일한 Cluster 이름을 다른 환경에서 재사용하면 위험합니다.
노드가 잘못된 클러스터에 포함될 위험이 있습니다.
Cluster에 하나의 노드만 있으면 유효합니다.
고유한 클러스터 이름을 가진 별도의 클러스터를 여러 개 넣거나 여러 서버가 하나의 클러스터를 구성할 수 있으며 하나의 서버에 여러 클러스터가 있을 수 있습니다.
노드 간 데이터 교환을 위해 http port(9200-9299), TCP 포트(9300-9399)를 열어 둡니다.
Node와 Node의 종류에 대해 알아보세요.
컴퓨터 데이터 통신 네트워크에서, 데이터를 전송하는 통로에 접속되는 하나 이상의 기능 유닛; 통신망의 분기점이나 단말의 접속점을 이름.
클러스터에 포함된 단일 서버 데이터를 저장하고 클러스터 인덱싱 및 검색 기능에 참여
노드도 이름으로 식별되며 Default는 Node에 지정된 UUID입니다.
네트워크의 어떤 서버가 Elastic Search 클러스터의 어느 노드에 해당하는지 식별하기 위해 관리 목적의 이름이 중요합니다.
Cluster라는 이름에서 Node는 일부로 구성될 수 있습니다.
기본적으로 각 노드는 “elasticsearch”라는 클러스터에 포함되도록 구성됩니다.
ex) 네트워크내에 복수의 노드가 존재→노드를 실행(각각 검색 기능이 가능)→모두가 자동적으로 「elasticsearch」라고 하는 단일의 클러스터를 형성해, 클러스터의 일부가 됩니다.
네트워크에서 실행되지 않고 단일 노드를 시작하면 기본값인 “elasticsearch”라는 단일 노드 클러스터가 생성됩니다.
Master-eligible Node
master에 선출할 수 있는 node. 마스터 노드는 index를 생성, 삭제, 샤드 할당 등 전체적으로 index나 node를 관리하는 역할을 하는 Node입니다.
Node Cluster 구성없이 단일 노드에서 elasticsearch를 사용하는 경우 노드는 마스터 역할과 데이터를 저장하는 역할을 모두 실행합니다.
여러 노드에서 클러스터를 구성하는 경우 master 역할 전용 노드와 데이터를 저장하기 위한 노드로 구분하여 사용하는 것이 일반적입니다.
데이터 노드
데이터를 저장하는 역할. CRUD, Search 및 coordinate node가 없는 경우 aggregation 쿼리도 실행합니다.
Ingest Node
preprocessing 프로세스를 실행하는 노드.
logstash나 beats 혹은 RestAPI등을 개입시켜 데이터를 보존하기 전에, 전처리를 통해서 데이터를 파이프라인을 개입시켜 변형해 보존 가능.
전처리 프로세스만이 전문적으로 실행되는 노드는 ingestnode입니다.
전처리할 데이터가 많으면 ingest node가 성능 향상에 도움이 될 수 있습니다.
Machine learing Node
preprocessing 프로세스를 실행하는 노드.
logstash나 beats 혹은 RestAPI등을 개입시켜 데이터를 보존하기 전에, 전처리를 통해서 데이터를 파이프라인을 개입시켜 변형해 보존 가능.
전처리 프로세스만을 전문으로 하는 노드가 ingetnode 전처리하는 데이터가 많은 경우, ingest node 가 퍼포먼스 향상에 도움이 되는 일이 있습니다.
Coordinating Node
사용자 요청에 대한 일종의 로드 밸런서 역할을 하는 노드 만약 협력 노드가 없는 경우 데이터 노드는 협정 노드 역할을 합니다.
데이터 노드가 집계를 수행하면 상당한 리소스가 소모됩니다.
data node 의 main role인 데이터 보존보다 aggregation 에 보다 많은 자원을 소비하게 되어, 기능을 실행할 수 없는 경우가 있습니다.
관련 데이터 노드간에 태스크를 찾아서 분배하는 작업을 수행합니다.
aggregation 쿼리를 받아 각 데이터 노드에 적절하게 요청을 분산하고 집계하여 aggregation을 실행합니다.
각 노드는 각 노드에 대해 하나의 역할뿐만 아니라 동시에 다양한 역할을 할 수 있습니다.
Elastic Search 아키텍처/용어
RDBMS와 비교하여 ElasticSearch 용어.
+---------------------------------------+-----------------------+
| RDBMS | ElasticSearch |
+---------------------------------------+-----------------------+
| Database | Index |
| Table | Type |
| Row | Document |
| Column | Field |
| Schema | Mapping |
| SQL | Query DSL |
| SELECT * FROM | GET API |
| UPDATE <TABLE> SET | POST API |
| INSERT INTO <TABLE> | PUT API |
| Indexing on demand | Everything is indexed |
| SELECT <FIELD>, COUNT(*) FROM <TABLE> | Aggregation |
+---------------------------------------+-----------------------+
출처: https://gist.github.com/agrawalo/c7c56b6109702cd93b24405a769c2fc4#file-elasticsearchvsrdbms-txt
색인
RDBMS의 Database 및 해당 개념
비슷한 특성을 가진 Document(Row) 컬렉션
ex) 고객 데이터 Indx, 제품 카탈로그 Index, 주문 데이터 Indx 각각에 넣을 수 있습니다.
모든 인덱스 이름은 소문자여야 하며 이름으로 식별됩니다.
Index 이름은 Inedx에 포함된 Doucument의 Indexing, select, update, delete 작업에 해당하는 Index를 가리키는 데 사용됩니다.
단일 Cluster에 필요한 인덱스 수를 정의할 수 있습니다.
색인
데이터를 검색할 수 있는 구조로 변경하려면 원본 문서를 쿼리 토큰으로 변환하고 저장합니다.
유형
Type은 Index에서 하나 이상의 유형을 정의할 수 있습니다.
Table과 비슷한 개념입니다.
의미는 완전히 사용자에 의해 결정됩니다.
Elastic Search6.x 이상에서는 색인당 하나의 유형만 허용합니다.
ex) BlogPlatform Index
userData Type
blogData Type
commentData Type
색인당 단일 유형만 허용한 이유
🤔 왜 Elastic Search 6.x부터 index 당 하나의 유형만 허용합니까?
그 이유 중 하나는 Index에 존재하는 다른 유형의 이름이 같은 JSON 문서 필드를 만들 수 있기 때문에 의도하지 않은 검색 결과가 표시되는 문제가 발생했다는 것입니다.
test_index
test_type1, test_type2 만들고 각각 하나씩 indexing하는 경우.
# curl -H ’Content-Type: application/json'
-XPOST "http://localhost:9200/test_index/test_typel?pretty" -d '
{
"name": "elasticsearch",
"type_name": "test_typel"
}
,
{
"_index" : "test,index",
"_type" : "test_typel",
"_id" : "AWpzMGuKKs3l0pC—hyf",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"created" : true
}
# curl -H 'Content-Type: application/json'
—XPOST ,,http://localhost:9200/test_index/test_type2?prettyH -d '
{
“name”: "elasticsearch",
"type_name": "test_type2"
}
,
{
"_index" : "test_index",
"_type" : "test_type2",
"_id" : "AWpzMKEZKs3l0pC-hyg",
"_version" : 1,
”result" : "created",
"_shards" : {
"total" : 2,
“successful" : 1,
"failed" : 0
},
"created" : true
}
test_index에는 다른 유형 type1, type2에 name이라는 동일한 필드가 있습니다.
test_index 에 검색 요구를 실시하면(자), 양쪽 모두 name 라고 하는 필드가 존재한다.
따라서 6.x 버전에서는 하나의 인덱스에 하나의 유형만 지원합니다.
문서
Document는 Index화할 수 있는 기본 정보 단위. Row와 비슷합니다.
JSON 형식.
Sharding(shard)
sharding과 Replication은 분산 데이터 시스템에도 존재하는 개념입니다.
index는 엄청난 양의 데이터를 저장할 수 있지만 단일 노드 하드웨어 한계를 초과하는 경우?
단일 노드에서 검색 요청을 처리하면 속도가 느려질 수 있습니다.
Elastic Search에는 이 문제를 해결하기 위해 index를 shard라는 조각으로 나누는 기능이 있습니다.
index 생성 시 원하는 샤드 수를 정의할 수 있습니다.
각 샤드는 완전한 기능을 가진 독립적인 인덱스이며 클러스터의 모든 노드에서 호스팅할 수 있습니다.
Elastic Search의 기본 샤드 값은 5입니다.
1 개의 Index 를 생성해 데이터를 indexing 하면 , node 내부에 논리적으로 5 개의 shard 생성합니다.
클러스터에 노드를 추가하면 샤드가 각 노드에 분산됩니다.
ex) 노드가 2개인 경우 shard는 3개, 2개
shard 방법과 검색 요청에 집계되는 방법의 모든 메커니즘은 ElasticSearch에 의해 관리됩니다.
🔥 shard 수는 index 생성 후 변경할 수 없습니다.
인덱싱된 후에는 언제든지 복제본 수를 탄력적으로 변경할 수 있습니다.
장점
- 볼륨 수평 분할/확장 가능
- 여러 샤드에 분산 배치/병렬화하여 성능/처리량을 늘릴 수 있습니다.
Segement
Shard는 Index에 Indexing되는 Document가 포함되는 논리 공간입니다.
Segment는 Shard의 데이터가 포함된 실제 파일을 의미합니다.
Segment는 immutable의 특성을 가지고 있습니다.
Index 외부에는 node가 node 외부에는 Cluster가 있습니다.
샤드마다 세그먼트 수가 다를 수 있습니다.
Segement Immutable
update 와 delete 시, 일반적으로 알고 있는 데이터를 변경하지 않습니다.
Segement가 불변인 것 → 기존의 데이터를 변경하지 않는 것.
Segement에서 해당 데이터를 Disconnected하여 표시합니다(불용 처리).
- Update 처리시에 새롭게 기입해, 기존의 것을 불용 처리합니다.
- Delete도 삭제시 즉시 지우지 않고 폐기 처리만 합니다.
- 나중에 해당 데이터를 지우는 것은 즉시 지워지지 않습니다.
장점
단점
- 불변의 특성을 유지하기 위해 작은 크기의 세그먼트가 점점 증가하고 검색 당 많은 수의 세그먼트가 응답해야한다는 단점이 있습니다.
- Elastic Search는 백그라운드에서 세그먼트를 병합하여 단점을 보완합니다.
Replication (replica)
네트워크/클라우드 환경에서 어떤 이유로 오류가 발생하여 샤드/노드가 오프라인이거나 사라진 경우.
Failover 메커니즘이 필요하며,
ElasticSearch에서는 인덱스 샤드에 대해 하나 이상의 사본을 만들 수 있습니다.
복제본 샤드라고 부르고 줄이고 복제본이라고 합니다.
각 인덱스는 여러 개의 샤드로 분할될 수 있으며, 하나의 인덱스에는 복제본이 없을 수 있으며 복제하여 하나 이상의 복제본이 있을 수 있습니다.
🔥 기본적으로 Elasticsearch의 각 인덱스에는 기본 shard 5개의 복제본이 하나 있습니다.
replica 1이라는 단어는 index를 생성하고 데이터를 indexing할 때 하나의 replica가 추가로 생성된다는 의미입니다.
ex) Cluster에 적어도 두 개의 Node가 있다면? Index에는 5개의 기본 shard 복제본 shard 5개(replica 1개)가 있으므로 index당 총 10개의 shard가 존재합니다.
장점
shard/node 오류가 발생해도 고가용성을 제공합니다.
📢 복제 샤드는 원래 샤드와 동일한 노드에 할당되지 않습니다.
모든 복제본에서 병렬로 검색을 수행할 수 있으므로 검색 볼륨과 처리량을 확장할 수 있습니다.
즉, 읽기 분산 처리에 사용할 수 있습니다.
Split Brain Problem
Elasticsearch뿐만 아니라 Cluster 역할을 하는 모든 서비스는 Master Node 후보 노드를 홀수 개로, 적어도 살아야 하는 노드 수를 n/2+1로 설정하는 것이 좋습니다.
예
두 개의 노드가있는 elasticsearch cluster에서 Node1은 Cluster가 시작될 때 Master로 선택되고 OP라는 기본 shard를 유지하고 Node2는 OR이라는 Replica를 유지합니다.
어떤 이유로 두 노드 간의 통신이 실패한 경우
Node 중 하나가 응답하지 않기 때문에 발생할 수 있습니다 ( ex : GC stop-the-world)
여기서 문제는 Node1, Node2 모두 다른 노드가 실패했다고 생각합니다.
Node1은 이미 Master이므로 아무 작업도 수행하지 않지만 Node2는 Master가 Cluster 내에 있지 않다고 생각하므로 Master-eligible Node인 Node2를 Master로 선택합니다.
OR인 Replica를 더 이상 Replica에 넣지 않으므로 OR을 OP로 승격시킵니다.
각 클러스터에 데이터가 추가되거나 변경되면 나중에 통합될 때 데이터 무결성 문제가 발생하여 데이터 무결성이 손상됩니다.
How to avoid the split-brain problem
elastic search 6.x 이전 버전
elasticsearch.yml 파일에서 discovery.zen.minimum_master_nodes 설정 값 변경 N/2+1에 해당하는 값을 설정해야 하며, N은 클러스터의 마스터 후보 노드 수입니다.
마스터 후보 노드의 수는 홀수로 지정해야 합니다.
🤔 discovery.zen.minimum_master_nodes Master를 선택하기 위해 통신해야 하는 노드 수를 나타냅니다.
기본값은 1
위의 예→(2/2+1)=2→2
두 노드 간의 네트워크 연결이 끊어지면 Node1은 Master 상태를 잃고 Node2도 Master로 선택되지 않습니다.
홀수로 지정된 나머지 하나의 마스터 후보 노드가 살아있는 경우 마스터 노드로 승격
elastic search 7.x 이상
cluster.initial_master_nodes→master 노드 후보 목록
cluster.initial_master_nodes : 과반수 이상이 살아 있어야하는 Cluster의 동작
즉, 클러스터가 자신의 minum_master_nodes 노드 값을 변경하도록 변경합니다.
참고
기본 개념 | Elasticsearch 문서(5.4) | Elastic
https://github.com/exo-archives/exo-es-search
How to avoid the split-brain problem in elasticsearch – Trifork Blog