- Elasticsearch란?2025년 04월 24일 00시 18분 37초에 업로드 된 글입니다.작성자: do_hyuk728x90반응형
1. Elasticsearch에 대해 알아보자.
Elasticsearch는 Apache Lucene 기반의 Java 오픈소스 분산형 RESTful 검색 및 분석 엔진이다.
방대한 양의 데이터에 대해 실시간으로 저장과 검색 및 분석 등의 작업을 수행할 수 있다.
특히 정형 데이터, 비정형 데이터, 지리 데이터 등 모든 타입의 데이터를 처리할 수 있는데,
Elasticsearch는 JSON 문서(Document)로 데이터를 저장하기 때문이다.
Elasticsearch는 단독 검색을 위해 사용하거나, ELK(Elasticsearch & Logstash & Kibana) 스택을 기반으로 사용한다.
ELK
ELK는 Elasticsearch + Logstash + Kibana를 같이 연동하여 사용한다는 의미이다.
- Filebeat
- 로그를 생성하는 서버에 설치해 로그를 수집한다.
- Logstash 서버로 로그를 전송한다.
- Logstash
- 로그 및 트랜잭션 데이터를 수집과 집계 및 파싱하여 Elasticsearch 로 전달한다.
- 정제 및 전처리를 담당한다.
- Elasticsearch
- Logstash로부터 전달받은 데이터를 저장하고, 검색 및 집계 등의 기능을 제공한다.
- Kibana
- 저장된 로그를 Elasticsearch의 빠른 검색을 통해 가져오며, 이를 시각화 및 모니터링하는 기능을 제공한다.
RDB 비교
Elasticsearch는 데이터를 행렬 데이터로 저장하는 것이 아니라, JSON 문서(Document)로 직렬화된 복잡한 자료 구조를 저장하는 방식을 채택하고 있다. 따라서 RDB에서 사용하던 용어를 그대로 사용하지 않는다.
단, 그에 대응하는 적합한 용어들이 존재하고 위에 사진이 해당 용어들이다.
Inverted Index
인덱스와 역인덱스 Elasticsearch는 특정 문장을 입력받으면, 파싱을 통해 문장을 단어 단위로 분리하여 저장한다.
또한 대문자를 소문자로 치환하거나 유사어 체크 등의 추가 작업을 통해 텍스트를 저장한다.Elasticsearch는 역 색인이라고 하는 자료 구조를 사용하는데, 이는 전문검색에 있어서 빠른 성능을 보장한다.
책의 전반부에 위치한 일반적인 목차가 Index라면, 책 후반부에 키워드마다 내용을 찾아볼 수 있도록 돕는 목차가 Inverted Index이다.
역 색인은 각 Document에 등장하는 모든 고유한 단어들을 리스트 업하고, 해당 단어들이 등장하는 Document들을 식별한다.
색인은 최적화 된 Document 컬렉션이며, 각 Document는 데이터를 포함하고 있는 Key-Value 쌍으로 이루어진 Field의 컬렉션이다.
Elasticsearch는 모든 Field의 데이터를 인덱싱하는데, 인덱싱 된 Field는 각각의 최적화 된 자료구조를 사용한다.
텍스트 형식의 Field는 Inverted Index에 저장되며, 숫자 혹은 지리 관련 Field는 BKD 트리에 저장된다.
RDB는 데이터 수정-삭제의 편의성과 속도 면에서 강점이 있지만 다양한 조건의 데이터를 검색하고 집계하는데에는 구조적인 한계가 존재한다.
특정 단어 검색 시 ROW 개수만큼 확인을 반복하기 때문이다. 반면 단어 기반으로 데이터를 저장하는 Elasticsearch는 특정 단어가 어디에 저장되어 있는지 이미 알고 있어 모든 Document를 검색할 필요가 없다.
반면 수정과 삭제는 내부적으로 굉장히 많은 리소스가 소요되는 작업이라, RDBMS를 대체하기 어렵다.
Architecture
하나의 클러스터 내부에 복수 개의 노드를 사용하는 경우, 저장된 Document는 클러스터 전역으로 분배되기 때문에 어느 노드에서든 즉시 접근이 가능하다.
- Cluster
- 최소 하나 이상의 노드로 이루어진 노드들의 집합을 의미한다.
- Node
- Elasticsearch를 구성하는 하나의 단위 프로세스를 의미한다.
- Shard
- 데이터를 분산해서 저장하는 방법을 의미한다.
- Scale-Out을 위해 RDB의 Database에 해당하는 Index를 여러 Shard로 쪼갠다.
- 기본적으로 1개가 존재하며, 검색 성능 향상을 위해 클러스터의 Shard 개수를 조정할 수 있다.
- Replica
- 또 다른 형태의 Shard를 의미한다.
- 노드를 손실했을 경우, 데이터의 신뢰성을 위해 Shard를 복제하는 것이다.
- 따라서 Replica는 서로 다른 노드에 위치시킬 것을 권장하고 있다.
추가적으로 Node는 다양한 역할로 분류할 수 있다.
- 대규모 클러스터에서 로드 밸런싱 역할을 하는 노드
- 데이터 변환 등 사전 처리 파이프라인 노드
- 색인된 데이터 CRUD 노드
- 메타 데이터 등 전체 클러스터를 제어하는 마스터 노드
- 인덱스 생성과 삭제
- 데이터 입력 시 샤딩 할당
단일 노드로 Elasticsearch를 구동할 수 있지만, 트래픽이 많아진다면 노드별로 서버를 분리하거나 작업 노드에 대해 Scale-Out 및 로드 밸런싱을 함으로써 성능을 향상시킬 수 있다.
특징
- Scale-Out: Shard를 통해 규모가 수평적으로 늘어날 수 있다.
- 고가용성: Replica를 통해 데이터의 안정성을 보장하고, 단일 장애점을 극복한다.
- Schema Free: Json 문서를 통해 데이터를 검색하므로, 스키마의 개념이 없다.
- RESTful: CRUD 작업은 RESTful API를 통해 수행되며, 각각이 HTTP의 PUT / GET / POST / DELETE 메서드에 대응
2. Spring Data Elasticsearch
Spring Data Elasticsearch 프로젝트는 Elasticsearch 검색 엔진을 사용하는 솔루션 개발을 도와주는 모듈이다.
다음 작업에 대해 높은 수준의 추상화를 템플릿으로 제공한다.
- Document의 저장과 검색 및 정렬
- Document를 Aggregate로 재구성
Spring Data JPA가 Repository 인터페이스에 정의한 메서드 이름을 분석해서 JPQL을 자동으로 생성 및 실행해주는 것처럼, Spring Data Elasticsearch 또한 Repository 인터페이스에 메서드를 정의함으로써 쿼리를 표현할 수 있다.
3. Docker를 활용한 Elasticsearch 설치
bash
> docker pull docker.elastic.co/elasticsearch/elasticsearch:8.15.5 > docker run -d -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:8.15.5
다양한 설치 방법이 있지만 그 중 가장 간편한 Docker를 사용했다.
해당 예제는 단일 노드로 클러스터를 구성하는데, 클러스터를 멀티 노드로 구성하고 싶다면 docker-compose를 활용하면 된다.
9200 포트는 HTTP 클라이언트와 통신에 사용되며, 9300 포트는 노드들간 통신할 때 사용된다.
- 현재 프로젝트의 Spring Boot 버전은 3.4.x이기 때문에 최신 공식 문서 기준으로 Spring 6.2.x 버전과 Spring Data Elasticsearch 5.4.x 버전이 Elasticsearch 8.15.5 버전과 호환되기 때문에 8.15.5 버전으로 이미지를 받는다.
- 다른 버전을 사용하고 싶다면 공식 홈페이지를 확인해 보면 되겠다.
4. Spring Boot 설정
build.gradle
현재 사용 중인 Elasticsearch 버전과 호환되게 Spring Data Elasticsearch 5.4.x 버전으로 의존성을 받는다.
Elasticsearch Clients 설정
ElasticsearchOperations.java
public interface ElasticsearchOperations extends DocumentOperations, SearchOperations { ... }
Elasticsearch 관련 작업을 수행할 때 주로 ElasticsearchOperations 인터페이스의 구현체를 사용한다.
해당 인터페이스는 DocumentOperations 인터페이스를 확장하고 있다.
AbstractElasticsearchConfiguration.java | Spring Data Elasticsearch 5.x 이전 버전 방식
public abstract class AbstractElasticsearchConfiguration extends ElasticsearchConfigurationSupport { @Bean public abstract RestHighLevelClient elasticsearchClient(); @Bean(name = { "elasticsearchOperations", "elasticsearchTemplate" }) public ElasticsearchOperations elasticsearchOperations(ElasticsearchConverter elasticsearchConverter, RestHighLevelClient elasticsearchClient) { ElasticsearchRestTemplate template = new ElasticsearchRestTemplate(elasticsearchClient, elasticsearchConverter); template.setRefreshPolicy(refreshPolicy()); return template; } }
ElasticsearchConfig Class에서 위의 코드를 상속받아서 사용했지만 이후에는 다르다.
해당 클래스에서 RestHighLevelClient와 ElasticsearchRestTemplate는 5.x 버전 이후 부터는 Deprecated 되었기 때문에 최신 버전에 맞게 설정해야한다.
5. Spring Data Elasticsearch - 새로운 ElasticsearchClient 사용법
1. 새로운 클라이언트 적용
기존의 `RestHighLevelClient`는 deprecated 되었고, 새로운 ElasticsearchClient사용이 권장된다.
Spring Data Elasticsearch 4.4 이상부터 새로운 클라이언트를 지원한다.
2. 동기 환경 스타일 구성@Configuration public class NewRestClientConfig extends ElasticsearchConfiguration { @Override public ClientConfiguration clientConfiguration() { return ClientConfiguration.builder() .connectedTo("localhost:9200") .build(); } }
이 설정만 하면 자동으로 다음 빈들이 생성된다
- RestClient (저수준 클라이언트)
- ElasticsearchClient (새 고수준 클라이언트)
- ElasticsearchOperations (`elasticsearchOperations`, `elasticsearchTemplate` 이름으로 사용 가능)
3. 비동기 환경 스타일 구성
@Configuration public class NewRestClientConfig extends ReactiveElasticsearchConfiguration { @Override public ClientConfiguration clientConfiguration() { return ClientConfiguration.builder() .connectedTo("localhost:9200") .build(); } }
이 설정으로 생성되는 빈
- RestClient
- ReactiveElasticsearchClient
- ReactiveElasticsearchOperations (`reactiveElasticsearchOperations`, `reactiveElasticsearchTemplate` 이름)
4. 기존 `RestHighLevelClient` 계속 사용하기
기존 클라이언트를 쓰려면 명시적으로 의존성을 추가해야 한다. (Spring Data Elasticsearch가 자동으로 포함하지 않음)
// Elasticsearch High Level REST Client (RestHighLevelClient 사용을 위해 추가) implementation 'org.elasticsearch.client:elasticsearch-rest-high-level-client:8.15.5'
728x90반응형'백엔드' 카테고리의 다른 글
JVM에서 GC 대상 객체를 판단하는 기준은 무엇인가요? (0) 2025.05.04 어떤 예외가 발생하면 트랜잭션을 롤백하나요? (1) 2025.05.02 Full-Text Search 사용법 (0) 2025.04.22 [MySQL] LIKE 문의 동작 방식과 Index와의 관계 (0) 2025.04.21 방어적 복사에 대해서 설명해주세요. (0) 2025.04.17 댓글 - Filebeat