[ES] 엘라스틱 서치

Posted by 김성철

참고링크

https://www.s-core.co.kr/insight/view/%EC%97%98%EB%9D%BC%EC%8A%A4%ED%8B%B1%EC%84%9C%EC%B9%98elasticsearch%EC%97%90%EC%84%9C-%EA%B4%80%EA%B3%84%ED%98%95-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%AA%A8%EB%8D%B8%EB%A7%81-%ED%95%98%EA%B8%B0/  
https://jaemunbro.medium.com/elastic-search-%EA%B8%B0%EC%B4%88-%EC%8A%A4%ED%84%B0%EB%94%94-ff01870094f0  

[ 엘라스틱 서치 ]

엘라스틱 기본 설명

일래스틱서치는 루씬 기반의 검색 엔진  
NoSQL 의 일종으로도 분류할 수 있음  

RDBMS 와 엘리스틱 서치의 맵핑

	Database		: Index  
	Table			: Type  
	Row				: Document  
	Column			: Field  
	Schema			: Mapping  
  
	SELECT			: GET  
	INSERT			: POST  
	UPDATE			: PUT  
	DELETE			: DELETE  
	인덱스정보확인	: HEAD  

[ 기본용어 설명 ]

Index

데이터 저장 공간  
하나의 물리 노드에 여러개 논리 인덱스 생성  
하나의 인덱스가 여러 노드에 분산 저장 (M:N)  

Shard

색인된 문서는 하나의 인덱스 - 인덱스 내부에 색인된 데이터는 여러개의 파티션으로 나뉘어 구성됨.  
파티션 = 샤드  

Type

인덱스의 논리적 구조  
6.1부터 인덱스당 하나의 타입만 설정 가능(6.0 이하에서는 music 인덱스에서 rock, pop등 장르별로 분리하는데 타입을 사용할 수 있었음)  

Document

데이터가 저장되는 최소 단위  
JSON 포맷으로 저장  
DB의 Row에 대응됨.  

Field

문서를 구성하기 위한 속성  
DB의 컬럼과 비교할 수 있음  
하나의 필드는 목적에 따라 다수의 데이터 타입을 가질 수 있음  

Mapping

문서의 필드, 필드 속성을 정의하고 그에 따른 색인 방법을 정의하는 프로세스  
스키마 정의 프로세스라고 보면 된다.  

Node Types

Master Node

클러스터 관리  
노드 추가/제거 등 관리  

Data Node

실질적인 데이터 저장 : 데이터가 실제로 분산 저장되는 물리 공간인 샤드가 배치됨.  
검색과 통계 등 데이터 관련 작업 수행 : 색인 작업은 CPU, 메모리, 스토리 등 컴퓨팅 리소스를 많이 소요하므로 리소스 모니터링이 필요함.  

Coordinating Node

사용자의 요청만 받아서 처리.  
클러스터 관련 요청은 마스터노드로, 데이터 관련 요청은 데이터 노드로 전달  

Ingest Node

문서의 전처리 담당  
인덱스 생성 전 문서의 형식을 다양하게 변경할 수 있음  

Cluster, Node, Shard

하나의 ES 클러스터는 인덱스의 문서를 조회할 때 마스터 노드를 통해 2개의 노드를 모두 조회해서 각 데이터를 취합한 후 결과를 하나로 합쳐서 제공.  
여러개의 클러스터를 연결해서 구성할 수도 있다. 클러스터 내 노드는 실시간으로 추가, 제거 가능  
아래는 인덱스별로 샤드가 2개고 리플리카가 1개로 설정한 예시  
  
{  
	"settings" : {  
		"index" : {  
			"number_of_shards" : 2,  
			"number_of_replicas" : 1  
		}  
	}  
}  

[ 엘라스틱 서치 주요 API ]

RESTful 방식의 API를 제공하며, 이를 통해 JSON 기반으로 통신한다.  

API 분류

- 인덱스 관리 API (Indices API)  
- 문서 관리 API (Document API)  
- 검색 API (Search API)  
- 집계 API (Aggregation API)  

Schemaless 지원 기능

- 인덱스의 존재 여부를 확인하고 인덱스가 존재하지 않는다면 문서를 분석해서 문서가 색인될 수 있도록 인덱스 자동 생성해주는 기능  
- 자동 생성된 필드를 보면 모든 필드가 text 타입과 keyword 타입을 동시에 제공하는 멀티필드 기능으로 구성되는 경우가 많다 -> 데이터 공간의 낭비 초래.  
- 단순히 문자열로 저장하고 싶은 경우 keyword. 형태소 분석을 원하는 경우 text 타입 사용.  
- 대부분 데이터가 복잡한 구조를 가지므로 성능상 문제가 발생할 가능성이 커지므로 실무에서 쓰기 힘든 기능이다.  

인덱스 관리 API

인덱스 생성  
인덱스 생성 시 맵핑이라는 세부설정을 이용할 수 있는데 맵핑은 문서와 문서에 포함된 필드, 필드 타입 등을 세세하게 지정하는 것이 가능한 설정 방식.  
주의 : 한번 생성된 맵핑 정보는 변경할 수 없다. 잘못 생성했다면 데이터 삭제하고 다시 색인하는 수밖에 없다.  
  
PUT /my-index-000001  
{  
  "settings": {  
	"index": {  
	  "number_of_shards": 3,  
	  "number_of_replicas": 2  
	}  
  }  
}  

Document 관리 API ( = single document api)

실제 Documnent 조회, 수정, 삭제  
기본적으로 search api를 제공하지만, 색인된 문서의 ID 기준으로 한건 한건의 문서를 다룰 경우 document 관리 api를 이용한다.  
- index api : 한건의 문서를 색인  
- get api : 조회  
- delete api : 삭제  
- update api : 업데이트  
multi-document api도 제공한다.  
- multi get api : 다수 문서 조회  
ID 지정하지 않고 문서 생성도 가능?  
- UUID를 통해 무작위 생성된다.  
- 단 검색엔진은 DB와 주기적 동기화가 필요하므로 random 식별자로 사용한 경우 DB 맵핑을 위해 별도의 룩업테이블이 필요함. 따라서 처음에 생성할 때 부터 DB의 식별자와 맞춰주는 것이 중요하다.  
  
POST my-index-000001/_doc/  
{  
  "@timestamp": "2099-11-15T13:12:00",  
  "message": "GET /search HTTP/1.1 200 1070000",  
  "user": {  
	"id": "kimchy"  
  }  
}  

##검색 API
검색 API 사용방식은 크게 두가지
- HTTP URI 형태의 파라미터를 URI에 추가해 검색
- RESTful API 방식인 Query DSL
(RESTful Request 방식이 URI 방식보다 제약사항이 적으므로 더 선호됨)

GET /my-index-000001/_search  
{  
  "query": {  
	"term": {  
	  "user.id": "kimchy"  
	}  
  }  
}  

집계 API

버킷 구조 안에 다른 그룹화된 데이터가 포함돼 있다. → 집계 API가 강력한 이유중 하나 : 버킷 안에 다른 버킷의 결과를 추가할 수 있다. 다양한 집계 유형을 결합, 중첩, 조합이 가능