Elasticsearch는 Apache Lucene(아파치 루씬) 기반의 Java 오픈 소스 분산 검색 엔진이다. Elasticsearch를 통해 루씬 라이브러리(Java에서 개발한 정보 검색용 라이브러리)를 단독으로 사용할 수 있으며, 방대한 양의 데이터를 신속하게(거의 실시간) 저장, 검색, 분석을 수행할 수 있다.
Elasticsearch는 검색을 위해 단독으로 사용되기도 하며, ELK(Elasticsearch / Logstash / Kibana) 스택으로 사용되기도 한다. ELK 스택은 다음과 같다.
LogStash : 다양한 소스(DB, csv파일 등) 의 로그 또는 트랜잭션 데이터를 수집, 집계, 파싱하여 ElasticSearch 로 전달
ElasticSearch : LogStash 로 부터 받은 데이터를 검색 및 집계하여 필요한 관심 있는 정보를 획득
Kibana : ElasticSearch의 빠른 검색을 통해 데이터를 시각화 및 모니터링
주로 ELK는 로드밸런싱되어 있는 WAS의 흩어져 있는 로그를 한 곳으로 모으고, 원하는 데이터를 빠르게 검색한 뒤 시각화하여 모니터링하기 위해 사용한다.
📚 ElasticSearch 과 RDB 의 비교
기존에 RDB를 많이 써 왔다면 Elasticsearch에서 사용하는 키워드와 매칭을 하기 쉽다. 다만, 인덱스와 타입에 대해 주의할 점이 있다.
⭐RDB처럼 여러 테이블, 한 인덱스 내의 멀티 타입이 가능한가?
결론부터 말하면 불가능하다!
위에서 인덱스는 RDB의 데이터베이스이고, 타입은 RDB의 테이블이라고 하였다. 하나의 데이터베이스에 여러 테이블을 가지듯이, Elasticsearch도 하나의 인덱스에 여러 타입을 가질 수 있다. 하지만 Elasticsearch 7.0 이상부터는 하나의 인덱스에는 하나의 타입만 가질 수 있도록 바뀌었다. 이 변경은 Elasticsearch의 간소화와 스키마 관리의 용이성을 높이기 위한 것이다. 만약 여러 종류의 데이터를 함께 저장해야 한다면, 다음과 같은 방법을 고려할 수 있다.
하나의 인덱스에 여러 타입 대신 여러 인덱스 사용: : 각각의 데이터 타입에 대해 별도의 인덱스를 생성하고 필요할 때에는 별도의 검색을 수행하는 방법을 고려할 수 있다.
Nested 타입 사용: : 하나의 인덱스 내에서 여러 타입이 필요한 경우, Nested 타입을 사용하여 복잡한 구조의 문서를 저장할 수 있다.
기본적으로 Elasticsearch는 인덱스가 매핑되면 수정이 불가능하므로, 데이터 구조를 변경하려면 새로운 인덱스를 만들고 데이터를 마이그레이션하는 과정이 필요할 수 있다.
📚 ElasticSearch의 구조
아래와 같은 구조를 통해 Elasticsearch는 대용량 데이터를 효과적으로 저장하고 검색하는 데 사용된다. 분산형 아키텍처를 통해 확장성을 가지며, 고성능 검색 및 질의 기능을 제공한다.
인덱스(Index) : Elasticsearch에서 데이터가 저장되는 단위다. 각 인덱스는 하나 이상의 샤드로 구성되어 있다. 일반적으로 하나의 인덱스는 특정 유형 또는 카테고리의 데이터를 담고 있다. 즉 RDBMS에서 데이터베이스와 대응하는 개념이다.
샤드(Shard) : 색인된 데이터를 여러 파티션으로 나누어 저장하는 논리적인 단위이다. 색인이 커질 경우에 검색 성능을 향상시키기 위해 여러 노드에 쉬드를 분산 저장할 수 있다. 샤드는 프라이머리 샤드와 레플리카 샤드로 나뉜다.
노드(Node) : Elasticsearch 클러스터를 구성하는 각각의 서버 또는 인스턴스를 나타낸다. 노드는 클러스터에 참여하여 데이터를 저장하고 검색 작업을 수행한다.
문서(Document) : 인덱스 내에서 저장되는 기본 데이터 단위입니다. JSON 형식으로 표현되며, 각 문서는 고유한 ID를 가지고 있다.
필드(Field) : 문서 내의 데이터를 나타내는 단위로, 각 문서는 여러 필드로 구성된다. 각 필드는 해당 데이터의 유형과 값을 가지고 있다.
매핑(Mapping) : Elasticsearch에서는 인덱스 내의 문서에 대한 구조를 정의하는 것을 "매핑"이라고 한다. 매핑은 어떤 필드가 어떤 유형의 데이터를 포함하고 있는지를 정의한다.
검색 및 질의(Query) : Elasticsearch는 강력한 검색 엔진을 제공하며, 사용자는 JSON 형식의 쿼리를 사용하여 데이터를 검색할 수 있다.
클러스터(Cluster) : Elasticsearch의 전체 시스템을 나타내며, 하나 이상의 노드로 구성된다. 노드는 클러스터에 참여하여 데이터를 공유하고 분산 처리를 수행한다.
📚 ElasticSearch의 장/단점
ES도 NoSQL의 일종으로 분류할 수 있고, 분산처리를 통해 실시간성으로 빠른 검색이 가능하다. 특히 기존의 데이터로 처리하기 힘든 대량의 비정형 데이터 검색이 가능하며 전문 검색(full text) 검색과 구조 검색 모두를 지원한다. 기본적으로는 검색엔진이지만 MongoDB나 Hbase와 같은 대용량 스토리지로도 활용이 가능하다.
장점
오픈소스 검색엔진이다. 활발한 오픈소스 커뮤니티가 ES를 끊임없이 개선하고 발전시키고 있다.
전문검색 내용 전체를 색인해서 특정 단어가 포함된 문서를 검색할 수 있다. 기능별, 언어별 플러그인을 적용할 수 있다.
통계 분석 비정형 로그 데이터를 수집하여 통계 분석에 활용할 수 있다. Kibana를 연결하면 실시간으로 로그를 분석하고 시각화할 수 있다.
Schemaless 정형화되지 않은 문서도 자동으로 색인하고 검색할 수 있다.
RESTful API HTTP기반의 RESTful를 활용하고 요청/응답에 JSON을 사용해 개발 언어, 운영체제, 시스템에 관계없이 다양한 플랫폼에서 활용이 가능하다.
Multi-tenancy 서로 상이한 인덱스일지라도 검색할 필드명만 같으면 여러 인덱스를 한번에 조회할 수 있다.
Document-Oriented 여러 계층 구조의 문서로 저장이 가능하며, 계층 구조로된 문서도 한번의 쿼리로 쉽게 조회할 수 있다.
역색인(Inverted Index)
확장성 분산 구성이 가능하다. 분산 환경에서 데이터는 shard라는 단위로 나뉜다.
단점
완전 실시간은 아니다. 색인된 데이터는 1초 뒤에나 검색이 가능하다. 내부적으로 commit과 flush같은 복잡한 과정을 거치기 때문.
Transaction Rollback을 지원하지 않는다. 전체적인 클러스터의 성능 향상을 위해 시스템적으로 비용 소모가 큰 롤백과 트랜잭션을 지원하지 않는다. 조심하자..
데이터의 업데이트를 제공하지 않는다. 업데이트 명령이 올 경우 기존 문서를 삭제하고 새로운 문서를 생성한다. 업데이트에 비해서 많은 비용이 들지만 이를 통해 불변성(Immutable)이라는 이점을 취한다.