ElasticSearch 설명
ElasticSearch 란?
ElasticSearch는 Apache Lucene 기반의 오픈소스, 분산, RESTful 검색 엔진입니다.
대량의 데이터를 신속하고 거의 실시간에 가까운 속도로 저장, 검새그 분석할 수 있도록 설계되었습니다.
ElasticSearch는 주로 로그나 트랜잭션 데이터와 같은 대규모 데이터셋을 분석하고 검색하는데 사용됩니다.
주요 특징
- 분산 시스템: Elasticsearch는 데이터를 여러 노드에 분산하여 저장하므로, 시스템이 확장될 때 데이터의 양이 증가해도 처리속도라 유지됩니다. 분산 시스템에 관한 자세한 내용은 다음과 같습니다. 이동하기
- 전문(Full-Text) 검색: ElasticSearch는 Lucene의 강력한 검색 기능을 활용하여 전문 검색을 지원합니다. 사용자가 특정 단어나 문구를 검색하면 관련도가 높은 문서를 빠르게 찾아낼 수 있습니다.
- 다양한 데이터 처리 기능: ElasticSearch는 데이터의 색인 생성, 검색, 분석 등 다양한 기능을 제공합니다. JSON형식의 문서를 직접 저장하고 검색 쿼리를 통해 복잡한 데이터 분석을 수행할 수 있습니다.
- 실시간 검색: ElasticSearch는 저장된 데이터에 대해 거의 실시간으로 검색과 분석을 수행할 수 있습니다. 이는 로그 모니터링, 이벤트 모니터링 등 실시간 데이터분석이 필요한 다양한 분야에서 활용됩니다.
- RESTful API: ElasticSearch는 RESTful API를 제공하여, 다양한 프로그래밍 언어로 작성된 애플리케이션에서 쉽게 접근하고 사용할 수 있습니다. HTTP를 통해 데이터를 색인, 검색, 수정, 삭제할 수 있습니다.
활용 분야
- 로그 분석: 시스템 로그, 웹 로그 등 다량의 로그 데이터를 실시간으로 분석하고 모니터링하는데 사용됩니다.
- 사이트 검색: 웹사이트나 애플리케이션 내에서 사용자가 원하는 정보를 빠르게 찾을 수 있도록 돕습니다.
- 데이터 분석: 비즈니스 인텔리전스, 시장분석 등 다양한 데이터 분석 작업에 사용됩니다.
사용 이유
- 빠른 검색 성능: ElasticSearch는 Lucene기반으로 구축되어 있어, 대량의 데이터에 대한 빠른 검색과 실시간 분석을 가능하게 합니다. 이는 전문(Full-Text)검색, 구조화된 검색, 데이터 분석 등 다양한 요구사항을 빠르게 충족시킬 수 있음을 의미합니다.
- 확장성: Elastic Searc는 수평적으로 확장 가능한 분산 시스템으로 설계되었습니다. 이는 데이터 양이 증가함에 따라 더 많은 서버를 추가하여 시스템를 확장할 수 있음을 의미하며, 이 과정에서도 검색 및 처리 성능을 유지할 수 있습니다.
- 고가용성과 신뢰성: ElasticSearch는 분산 특성은 높은 가용성을 보장합니다. 데이터는 자동으로 여러 노드에 복제되므로, 어떤 서버에 당애가 발생해도 데이터 손실 없이 서비스를 지속할 수 있습니다.
- 다양한 데이터 처리 가능: ElasticSearch는 단순한 검색뿐만 아니라, 복잡합 데이터집계, 분석 기능을 제동합니다. 이를 통해 사용자는 로그 데이터 분석, 실시간 모니터링, 비즈니스 인렝리전스 등 다양한 작업을 수행할 수 있습니다.
- 유연한 데이터 모델링: ElasticSearch는 JSON 형식의 문서를 사용하여 데이터를 저장합니다. 이는 구조화되지 않은 데이터를 쉽게 처리하고, 다양한 형태의 데이터를 유연하게 색인할 수 있음을 의미합니다.
단점 및 고려사항
- 리소스 요구사항: ElasticSearch는 고성능을 제공하지만, 이를 위해 상당한 양의 시스템 리소스를 필요로 합니다. 특히, 대량의 데이터를 처리하거나 높은 쿼리 부하를 처리하기 위해서는 충분한 메모리와 CPU가 필요할 수 있습니다.
- 관리의 복잡성: ElasticSearch는 분산 시스템이므로, 클러스터 관리, 데이터샤딩, 복제 등을 올바르게 설정하고 관리하는 것이 중요합니다. 이러한 관리 작업은 초보자에게는 복잡하게 느껴질 수 있으며, 잘못된 설정은 성능 저하나 데이터 손실로 이어질 수 있습니다.
- 보안 고려사항: ElasticSearch는 기본적으로 보안 설정이 비활성화되어 있습니다. 따라서, 사용자 인증, 데이터 암호화, 접근 제어 등 보안 관련 설정을 직접 추가해야 합니다. 이는 추가적인 설정과 관리 작업을 필요로 하며, 잘못 구성할 경우 보안 취약점이 발생할 수 있습니다.
- 업그레이드의 어려움: ElasticSearch의 버전을 업그레이드하는 과정은 때때로 복잡할 수 있습니다. 특히, 메이저 버전 간의 업그레이드는 호환성 문제를 유발할 수 있으며, 이는 데이터 마이그레이션 또는 인덱스 재구축을 필요로 할 수 있습니다.
- 비용: ElasticSearch를 자체 서버에 배포할 경우, 하드웨어 및 운영 비용이 발생할 수 있습니다. 또란 ElasticSearch를 클라우드 서비스로 사용할 경우, 트래픽과 저장공간에 따라 비용이 증가할 수 있습니다.
- 쿼리 언어의 복잡성: ElasticSearch의 쿼리 언어는 매우 강력하고 유연하지만, 복잡한 쿼리를 작성하고 최적화하는데는 학습 곡선이 있습니다. 복잡한 검색 요구 사항을 충족시키기 위해서는 쿼리 언어에 대한 깊은 이해가 필요할 수 있습니다.
클러스터 구조에 대한 개인적인 생각
일단 Cluster는 물리적인 개념이 아닙니다.
여러 Node들이 서로 연결되고 하나로서 이루어져 통신하고 논리적으로 묶여있는 그런 시스템을 Cluster 라고 명명한 것입니다.
1차 조사로 Cluster 안에 여러 Elasticsearch 기법이 적용된 Node들이 하나의 검색엔진으로서 기능하는것이다 라고 이해를 했었는데 그것이 아니었습니다.
Node들은 그저 분할된 정보들을 나눠서 저장하는 역할인데 서버에 Elasticsearch 프로세스를 띄우거나 Docker로 각각의 Node마다 하나의 Container로서 띄운다하여 각각의 Node가 서로 다른 엔진으로서 기능하는줄 이해했던 것이었습니다.
사용 예시(CRUD)
문서입력
- 단일 문서 삽입
POST /products/_doc
{
"name": "Logitech Mouse",
"price": 29900,
"category": "electronics"
}
-
자동으로 ID가 생성됨
-
_doc은 문서 타입 (현재는 거의 고정 사용)
-
ID 지정해서 삽입 (덮어쓰기 포함)
PUT /products/_doc/1234
{
"name": "Apple Magic Keyboard",
"price": 129000
}
-
1234라는 ID로 저장됨
-
같은 ID로 다시 넣으면 업데이트(덮어쓰기)
단일 문서 조회
GET /products/_doc/1234
-
특정 ID의 문서를 가져옴
-
조건 검색 (Query DSL)
GET /products/_search
{
"query": {
"match": {
"name": "keyboard"
}
}
}
-
"keyboard"라는 단어가 포함된 문서 검색 (전문 검색)
-
필터 검색 (정확히 일치)
GET /products/_search
{
"query": {
"term": {
"category.keyword": "electronics"
}
}
}
- 정렬/집계에 많이 쓰는 .keyword 필드를 활용한 정확한 매칭
문서 수정 (Update)
POST /products/_update/1234
{
"doc": {
"price": 119000
}
}
-
문서의 price만 부분 업데이트
-
전체가 아니라 특정 필드만 수정할 때 유용
문서 삭제 (Delete)
DELETE /products/_doc/1234
- 해당 ID의 문서를 삭제함
Bulk 처리 (대량 작업)
대용량 데이터 입력이나 수정 시 많이 씀
POST /_bulk
{ "index": { "_index": "products", "_id": "1" } }
{ "name": "item1", "price": 10000 }
{ "index": { "_index": "products", "_id": "2" } }
{ "name": "item2", "price": 20000 }
-
한 번에 여러 문서를 처리함
-
성능 매우 중요할 때 필수 사용
집계(Aggregation) - 데이터 분석
평균 가격 구하기
GET /products/_search
{
"size": 0,
"aggs": {
"avg_price": {
"avg": {
"field": "price"
}
}
}
}
-
검색 결과는 버리고(size: 0), 가격 필드의 평균값만 계산
-
범주별 집계 (Group By와 유사)
GET /products/_search
{
"size": 0,
"aggs": {
"by_category": {
"terms": {
"field": "category.keyword"
}
}
}
}
- category 별 문서 수를 계산 (SQL의 GROUP BY 역할)
사용 예시(docker-compose)
services:
elastic:
image: docker.elastic.co/elasticsearch/elasticsearch:8.17.4
ports:
environment: