Elasticsearch
elasticsearch
Elasticsearch
특징
- 스키마가 없는 JSON 기반 저장소
- JSON 형태의 데이터 모델을 사용함
- NoSQL 처럼 사용 가능
- 스키마를 정의하지 않아도 JSON 데이터를 넘겨주면 자동으로 인덱싱
- 숫자나 날짜 등의 타입을 자동 매핑
- Document-Oriented
- JSON 형식의 구조화된 문서로 인덱스에 저장
- 계층 구조로 문서도 한번의 쿼리로 쉽게 조회 가능
- Multi-Tenancy 를 지원
- Multi-Tenancy 란 단일 소프트웨어 인스턴스로 다른 여러 사용자 그룹에 서비스를 제공할 수 있는 소프트웨어 아키텍쳐
- 하나의 ES 서버에 여러 인덱스를 저장하고, 여러 인덱스의 데이터를 하나의 쿼리로 조회 가능
- 서로 상이한 인덱스라도 검색할 필드명만 같으면 여러개의 인덱스를 한번에 조회가능
단점
- 실시간이 아니다
- 인덱스가 된 데이터는 통상적으로 1초 뒤에 검색이 가능하다.
- 내부적으로 commit 과 flush 과 같은 과정을 거치기 때문에
- 이를 준 실시간 시스템 (Near Realtime System) 이라고 한다
- 트랜잭션과 롤백이 없다
- ES는 기본적으로 분산 시스템으로 구성된다
- 전체적인 클러스터의 성능 향상을 위해서 시스템적으로 비용 소모가 큰 롤백과 트랜잭션을 지원하지 않는다.
- 데이터 손실의 위험이 있다.
- 데이터의 업데이트는 권장되지 않는다
- Immutable 이다.
- 업데이트 요청이 발생할 경우 기존 문서를 삭제하고 변경된 내용으로 새로운 문서를 생성하는 방식을 쓴다.
- 단순 업데이트에 비해서 많은 비용이 발생한다
Elasticsearch Rest API
http://host:port/ ${index} / ${type} / ${action | id}
Client SDK
- Spring data elasticsearch
- Rest High-Level Client
Spring data Elasticsearch PoC(Proof of Concept)
Scenario
In(Index)
유저 정보를 삽입할 수 있다.
Out(Query)
유저 이름으로 유저 정보를 조회할 수 있다. 유저 전화번호로 유저 정보를 조회할 수 있다.
SDK
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-elasticsearch'
}
Elasticsearch Repository
/**
* ElasticsearchRepository 를 상속합니다. 해당 인터페이스는 PagingAndSortingRepository 를 상속합니다.
* save(), findById(), findAll(), count(), delete() 등의 메소드가 포함됩니다.
*/
Elasticsearch Configuration
/**
* Spring data Elasticsearch 가 Spring Data 저장소에 대해 제공된 패키지를 스캔하도록 합니다.
* Elasticsearch Server 와 통신을 위해 간단한 RestHighLevelClient 를 사용합니다.
* ElasticsearchOperations Bean 을 설정해, 서버에서 작업을 실행합니다.
*/
User
@Document(indexName = "user_index")
public class User {
@Id
private String id;
@Field(type = FieldType.Text, name = "name")
private String name;
@Field(type = FieldType.Text, name = "phoneNumber")
private String phoneNumber;
}
Run server
Elasticsearch
$ make start-elasticsearch * jar is required.
Opensearch
$ make start-opensearch * jar is required.
Indexing
$ curl -d '{"id":"test","name":"currenjin","phoneNumber":"01012341234"}' \
-H "Content-Type: application/json" \
-X POST http://localhost:{PORT}/
Query
$ curl -X GET "http://localhost:{PORT}/test"
$ curl -X GET "http://localhost:{PORT}?name=currenjin"
$ curl -X GET "http://localhost:{PORT}?phoneNumber=01012341234"
{"id":"test","name":"currenjin","phoneNumber":"01028810909"}