[Elasticsearch] Elasticsearch 기본 개념 잡기

nooyji·2022년 7월 5일
0
  1. Elasticsearch 란 ?

Elasticsearch 는 Apache Lucene (아파치 루씬) 기반의 Java 오픈소스 분산 검색 엔진입니다.
Elasticsearch 를 통해 루씬 라이브러리를 단독으로 사용할 수 있게 되었으며, 방대한 양의 데이터를 신속하게, 거의 실시간 (NRT, Near Real Time) 으로 저장, 검색, 분석할 수 있습니다.

Elasticsearch 는 검색을 위해 단독으로 사용되기도 하며, ELK (Elasticsearch / Logstash / Kibana) 스택으로 사용되기도 합니다.

ELK 를 왜 사용하는가 ?
주로 ELK 는 로드밸런싱되어 있는 WAS 의 흩어져 있는 로그를 한 곳으로 모으고, 원하는 데이터를 빠르게 검색한 뒤 시각화하여 모니터링하기 위해 사용한다.

Logstash
다양한 소스 (DB, csv 파일 등) 의 로그 또는 트랜잭션 데이터를 수집, 집계, 파싱하여 Elasticsearch 로 전달

Elasticsearch
Logstash 로부터 받은 데이터를 검색 및 집계를 하여 필요한 관심 있는 정보를 획득

Kibana
Elasticsearch 의 빠른 검색을 통해 데이터를 시각화 및 모니터링

  1. Elasticsearch 와 관계형 DB 비교

RDB Elasticsearch
Database Index
Table Type
Row Document
Column Field
Index Analyze
Primary key _id
Schema Mapping
Physical partition Shard
Logical partition Route
Relational Parent/Child, Nested
SQL Query DSL

Elasticsearch 와 NoSQL 의 차이는 ?
Elasticsearch 는 실시간 처리가 불가능하지만, NoSQL 은 실시간 처리가 가능하다.
Elasticsearch 는 역색인 자료 구조가 있지만, NoSQL 은 없다.
Elasticsearch 는 저장소보다는 검색 엔진에 가깝다.

  1. Elasticsearch 아키텍처 / 용어 정리

Elasticsearch 에서 사용하는 대부분의 개념은 RDBMS 에도 존재하는 개념들입니다.

1) 클러스터 (cluster)
클러스터란 Elasticsearch 에서 가장 큰 시스템 단위를 의미하며, 최소 하나 이상의 노드로 이루어진 노드들의 집합입니다.
서로 다른 클러스터는 데이터의 접근, 교환을 할 수 없는 독립적인 시스템으로 유지되며,
여러 대의 서버가 하나의 클러스터를 구성할 수 있고, 한 서버에 여러 개의 클러스터가 존재할 수도 있습니다.

2) 노드 (node)
Elasticsearch 를 구성하는 하나의 단위 프로세스를 의미합니다.
그 역할에 따라 Master-eligible, Data, Ingest, Tribe 노드로 구분할 수 있습니다.

Master-eligible node
클러스터를 제어하는 마스터로 선택할 수 있는 노드
master 노드가 하는 역할은 다음과 같다.

  • 인덱스 생성, 삭제
  • 클러스터 노드들의 추적, 관리
  • 데이터 입력 시 어느 샤드에 할당할 것인지

Data node
데이터와 관련된 CRUD 작업과 관련있는 노드
이 노드는 CPU, 메모리 등 자원을 많이 소모하므로 모니터링이 필요하며, master 노드와 분리되는 것이 좋음

Ingest node
데이터를 변환하는 등 사전 처리 파이프라인을 실행하는 역할을 함

Coordination only node
data node 와 master-eligible node 의 일을 대신하는 이 노드는 대규모 클러스터에서 큰 이점이 있다. 로드밸런서와 비슷한 역할을 함

3) 인덱스 (index) / 샤드 (Shard) / 복제 (Replica)
Elasticsearch 에서 index 는 RDBMS 에서 database 와 대응하는 개념
또한 shard 와 replica 는 Elasticsearch 에만 존재하는 개념이 아니라, 분산 데이터베이스 시스템에도 존재하는 개념

샤딩 (sharding) 은 데이터를 분산해서 저장하는 방법을 의미
즉, Elasticsearch 에서 Scale out 을 위해 index 를 여러 shard 로 쪼갠 것
기본적으로 1개가 존재하며, 검색 성능 향상을 위해 클러스터의 샤드 갯수를 조정하는 튜닝을 하기도 함

replica 는 또 다른 형태의 shard 라고 할 수 있다.
노드를 손실했을 경우 데이터의 신뢰성을 위해 샤드들을 복제하는 것
따라서 replica 는 서로 다른 노드에 존재할 것을 권장

세그먼트

세그먼트란 Elasticsearch 에서 문서의 빠른 검색을 위해 설계된 자료 구조이며, 샤드의 데이터를 가지고 있는 물리적인 파일이다. 각 샤드는 다수의 세그먼트로 구성되어 있으므로 검색 요청을 분산 처리하여 훨씬 효율적인 검색이 가능하다.
샤드에서 검색 시, 먼저 각 세그먼트를 검색하여 결과를 조합한 후 최종 결과를 해당 샤드의 결과로 반환하게 된다. 이 때 세그먼트는 내부에 색인된 데이터가 역색인 구조로 저장되어 있으므로 검색 속도가 매우 빠르다.
그런데, 매 요청마다 새로운 세그먼트를 만들어주면 엄청나게 많은 세그먼트가 생성될 것이고, 이로 인해 다른 요청에 지장이 생길 수 있다. 이를 방지하기 위해 인메모리 버퍼를 사용한다. 인메모리 버퍼에 쌓인 내용을 일정 시간이 지나거나 버퍼가 가득차면 flush 를 취하고, flush 작업이 수행되면 시스템 캐시에 세그먼트가 생성된다. 이 시점부터 데이터가 비로소 검색이 가능해진다. 하지만 이 상태는 세그먼트가 시스템 캐시에 저장된 상태이지, 디스크에 저장된 상태는 아니다.
디스크에 쓰여지는 작업 역시 일정 시간이 지나면 commit 을 통해서 물리적인 디스크에 세그먼트를 저장해 주고, 저장된 세그먼트는 시간이 지날수록 하나로 병합하는 과정을 수행한다. 병합을 통해 세그먼트를 하나로 줄여주면, 검색할 세그먼트의 개수가 줄어들기 때문에 검색 성능이 향상된다.

  1. Elasticsearch 특징

Scale out
샤드를 통해 규모가 수평적으로 늘어날 수 있음

고가용성
Replica 를 통해 데이터의 안정성을 보장

Schema Free
Json 문서를 통해 데이터 검색을 수행하므로 스키마 개념이 없음

Restful
데이터 CURD 작업은 HTTP Restful API 를 통해 수행하며, 각각 다음과 같이 대응

Data CRUD Elasticsearch Restful
SELECT GET
INSERT PUT
UPDATE POST
DELETE DELETE

단점

실시간 처리가 불가능하다.
elasticsearch 는 인메모리 버퍼를 사용하므로 쓰기와 동시에 읽기 작업을 할 경우, 세그먼트가 생성되기 전까지는 해당 데이터를 검색할 수 없다.

트랜잭션을 지원하지 않는다.
분산 시스템 구성의 특징 때문에 시스템적으로 비용 소모가 큰 트랜잭션 및 롤백을 지원하지 않는다.

진정한 의미의 업데이트를 지원하지 않는다.
세그먼트에서 데이터가 삭제될 경우 Soft-Delete 를 한다. (삭제 flag = true)
세그먼트에서 데이터가 수정될 경우 Soft-Delete 를 하고, 수정된 데이터를 새로운 세그먼트로 생성한다.
RDBMS 의 Index 와 유사한 동작

  1. 간단한 예제

Restful API 로 document 를 추가하고 조회하는 예제

Elasticsearch CRUD 작업은 특징에서 살펴본 바와 같이 API 를 호출해서 이루어지며,
curl 로 데이터를 넘겨줄 수도 있지만, json 파일을 저장해서 데이터를 넘길 수도 있고, json 포맷으로 queryDSL 을 작성해서 API 를 호출할 수도 있음

1) document 생성
#curl -XPOST 'localhost:9200/nooyji/velog/1?pretty' -d '{"postName" : "elasticsearch", "category" : "IT"}' -H 'Content-Type: application/json'

-d 옵션
추가할 데이터를 json 포맷으로 전달합니다.

-H 옵션
헤더를 명시합니다. 예제에서는 json 으로 전달하기 위해서 application/json 으로 작성했습니다.

?pretty
결과를 에쁘게 보여주도록 요청

이렇게 curl 요청을 하면, nooyji 인덱스에 velog 타입으로 id 값이 1 인 document 가 저장됩니다.

{
"_index" : "nooyji",
"_type" : "velog",
"_id" : "1",
"_version" : 1,
"result" : "created",
"_shard" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}

2) document 조회
#curl -XGET 'localhost:9200/nooyji/velog/1?pretty'
document 를 조회하는 API 입니다.

{
"_index" : "nooyji",
"_type" : "velog",
"_id" : "1",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"_source" : {
"postName" : "elasticsearch",
"category" : "IT"
}
}

Elasticsearch 를 잘 다루기 위해서는 Elasticsearch 에서 제공하는 API 를 알아둘 필요가 있으며, queryDSL 을 통해 쿼리를 작성해 원하는 방식대로 다양하게 조회할 수 있어야 합니다.

  1. 역색인

Elasticsearch 는 왜 빠를까 ?
그 이유는 inverted index (역색인) 에 있다.

예를 들어 책에서 맨 앞에 볼 수 있는 목차가 index 이고,
책 맨 뒤에 키워드마다 찾아볼 수 있도록 찾아보기가 inverted index 이다.

Elasticsearch 는 텍스트를 파싱해서 검색어 사전을 만든 다음에 inverted index 방식으로 텍스트를 저장한다.

"Lorem lpsum is simply dummy text of the printing and typesetting industry"
예를 들어, 이 문장을 모두 파싱해서 각 단어들 (Lorem, lpsum, is, simply ..) 을 저장하고,
대문자는 소문자 처리하고, 유사어도 체크하고 .. 등의 작업을 통해 텍스트를 저장합니다.
때문에 RDBMS 보다 전문검색 (Full Text Search) 에 빠른 성능을 보인다.

원문 : https://victorydntmd.tistory.com/308
https://steady-coding.tistory.com/573

0개의 댓글