본문 바로가기

DB/ElasticSearch

Elastic Search 개념

728x90

1. 개념

NoSQL 기반의 document 데이터베이스. 루씬 기반의 분산형 RESTful 검색 및 분석 엔진이다. 방대한 양의 데이터를 신속하게 저장, 검색, 분석할 수 있다. 확장성, 복원성뿐 아니라 정형/비정형 데이터를 모두 수용할 수 있는 유연성을 가지고 있다. 이로 인해 검색 엔진을 넘어 빠른 데이터 확인이 필요한 모든 분야에서 관심을 끌고 있기도 하다. 

 

Elasticsearch는 검색을 위해 단독으로 사용되기도 하며, ELK 스택으로 사용되기도 한다. ELK 스택은 아래와 같다. 

출처: https://www.elastic.co

  • logstash: 다양한 소스( DB, csv 등)의 로그 또는 트랜잭션 데이터를 수집, 집계, 파싱하여 Elasticsearch로 전달한다. 
  • beats: 경량 데이터 수집기. logstash가 데이터 수집기로써 훌륭하지만, 너무 기능이 다양해 사이즈가 커져서 많은 자원을 필요해졌다. 모든 시스템에 Logstash를 설치하는 것은 큰 부담이기에, beats는 데이터를 수집하고 필터기능 없이 가볍게 데이터를 전송하는 역할을 대체했다. 
  • elasticsearch: Logstash로부터 받은 모든 데이터를 색인하여 저장하고 검색, 집계 등을 수행하여 결과를 클라이언트 혹은 다른 프로그램으로 전달하여 동작한다. 
  • kibana: 시각화 할 수 있는 도구. 집계 기능을 사용하여 집계 결과 등을 웹 도구로 시각화를 한다. 

 

2. RDBMS와의 차이점 

출처:https://www.slideshare.net/deview/2d1elasticsearch
출처:https://www.slideshare.net/deview/2d1elasticsearch

기본적으로 용어가 다르며 RDBMS와는 아래의 차이점이 있다. 

 

RDBMS

  • 행 기반으로 데이터 저장.
  • 데이터 수정/삭제의 편의와 속도 면에서 강점.
  • 집계하는데 구조적 한계.

Elastic Search

  • 단어를 기반으로(역 인덱스) 저장.
  • 단어가 저장된 도큐먼트를 알고 있기 때문에 개수와 상관없이 한 번의 조회로 검색을 끝낸다.
  • 수정과 삭제는 많은 리소스가 소요되기에, 엘라스틱서치가 RDBMS를 완전히 대체할 수 없다. 

수정과 삭제가 많은 경우에 RDBMS와 Elastic Search 영역을 나누면 된다.

 

3. Inverted index

Elasticsearch는 텍스트를 파싱해서 검색어 사전을 만들고 역색인(inverted index) 방식으로 텍스트를 저장한다. 아래의 문장을 파싱해보면

 

"Where there is a will there is a way"

 

Where, there, is, a will, there, is ,a, way 이런식으로 문장의 각 단어들을 저장. 대문자는 소문자 처리, 유사어 체크 등의 작업을 걸쳐 텍스트를 저장한다. 이로 인해  Elastic Search가 RDBMS보다 전문검색( Full Text Search)에 빠른 성능을 보여준다. 

 

4. ELASTIC 구조 

1) 클러스터

클러스트는 하나 이상의 노드(서버)가 모인 것이며, 전체 데이터를 저장하고 모든 노드를 포괄하는 통합 색인화 및 검색 기능을 제공한다. 클러스터는 고유한 이름으로 식별되는데, 기본 이름은 "elasticsearch"이다. 이 이름은 중요한데, 어떤 노드가 어느 클러스터에 포함되기 위해서는 이름에 의해 클러스터의 구성원이 되도록 설정되기 때문이다. 

여러 대의 서버가 하나의 클러스터를 구성할 수 있고, 한 서버에 여러 개의 클러스터가 존재할 수도 있다. 

 

2) 노드

Elasticsearch를 구성하는 하나의 단위 프로세스를 의미. 노드는 클러스터에 포함된 단일 서버로서 데이터를 저장하고 클러스터의 색인화 및 검색 기능에 참여한다. 노드는 클러스터처럼 이름으로 식별되는데, 기본 이름은 시작 시 노드에 지정되는 임의 UUID이다. 기본 이름 대신 어떤 노드 이름도 정의할 수 있다. 

노드는 클러스터 이름을 통해 어떤 클러스터의 일부로 구성될 수 있다. 기본적으로 각 노드는 "elasticsearch"라는 이름의 클러스터에 포함되도록 설정된다. 즉 네트워크에서 다수의 노드를 시작할 경우 이 노드가 모두 자동으로 "elasticsearch"라는 단일 클러스터를 형성하고 이 클러스터의 일부가 된다.

하나의 클러스터에서 원하는 개수의 노드를 포함할 수 있다. 뿐만 다른 어떤 Elasticsearch 노드도 네트워크에서 실행되지 않은 상태에서 단일 노드를 시작하면 기본적으로 "elasticsearch"라는 이름의 새로운 단일 노드 클러스터가 생긴다.

 

3) 인덱스 

다소 비슷한 특성을 가진 문서의 모음이다. 이를테면 고객 데이터에 대한 색인, 제품 카탈로그에 대한 색인, 주문 데이터에 대한 색인을 각각 둘 수 있다. 색인은 이름으로 식별되며, 이 이름은 색인에 포함된 문서에 대한 색인화, 검색, 업데이트, 삭제 작업에서 해당 색인을 가리키는 데 쓰인다. 단일 클러스터에서 원하는 개수의 index를 정의할 수 있다.

 

4) 샤드 & 리플리카

index는 방대한 양의 데이터를 저장할 수 있고, 이 데이터가 단일 노드의 하드웨어 한도를 초과할 수도 있다. 예를 들어 10억 개의 문서로 구성된 하나의 색인에 1TB의 디스크 공간이 필요할 경우, 단일 노드의 디스크에서 수용하지 못하거나 단일 노드에서 검색 요청 처리 시 속도가 너무 느려질 수 있다.

 

출처: https://www.linkedin.com/pulse/elasticsearch-elastic-real-paul-m-veillard-p-eng?trk=articles_directory


Elasticsearch는 이러한 문제를 해결하고자 색인을 이른바 샤드(shard)라는 조각으로 분할하는 기능을 제공한다. 색인을 생성할 때 원하는 샤드 수를 간단히 정의할 수 있다. 각 샤드는 그 자체가 온전한 기능을 가진 독립적인 "색인"이며, 클러스터의 어떤 노드에서도 호스팅할 수 있다.

샤딩은 무엇보다도 2가지 이유로 중요하다.

(1) 콘텐츠 볼륨의 수평 분할/확장이 가능
(2) 작업을 여러 샤드에 분산 배치하고 병렬화함으로써 성능/처리량을 늘릴 수 있다.

 

샤드가 분산 배치되는 방식 및 그 문서가 다시 검색 요청으로 집계되는 방식의 메커니즘은 모두 Elasticsearch에서 관리하며 사용자에게 투명하게 이루어진다. 

언제든 오류가 일어날 가능성이 있는 네트워크/클라우드 환경에서는 어떤 이유에서든 샤드/노드가 오프라인 상태가 되거나 사라지게 될 경우에 대비하여 페일오버 메커니즘을 마련하는 것이 매우 유익하고 바람직하다. 이러한 취지에서 Elasticsearch에서는 색인의 샤드에 대해 하나 이상의 복사본을 생성할 수 있는데, 이를 리플리카 샤드(replica shard), 줄여서 리플리카라고 한다. 

리플리카를 만드는 복제는 무엇보다도 2가지 이유로 중요하다. 샤드/노드 오류가 발생하더라도 고가용성을 제공한다. 따라서 리플리카 샤드는 그 원본인 기본 샤드와 동일한 노드에 배정되지 않는다. 모든 리플리카에서 병렬 방식으로 검색을 실행할 수 있으므로 검색 볼륨/처리량을 확장할 수 있다.

 

요약하자면 각 색인은 여러 개의 샤드로 분할할 수 있다. 또한 하나의 색인을 복제하지 않거나(리플리카 X), 1회 이상 복제할 수 있다. 복제되면 각 색인은 기본 샤드(복제 원본 샤드)와 리플리카 샤드(기본 샤드의 복사본)를 갖는다. 샤드 및 리플리카의 수는 색인별로, 색인 생성 시점에 정의할 수 있다. 색인이 생성된 다음 언제라도 탄력적으로 리플리카의 수를 변경할 수 있으나, 샤드 수는 사후 변경이 불가하다.

기본적으로 Elasticsearch의 각 색인은 기본 샤드 5개, 리플리카 1개를 갖는다. 따라서 클러스터에 최소한 2개의 노드가 있다면 색인은 기본 샤드 5개, 리플리카 샤드 5개(완전한 리플리카 1개)를 가지므로 색인당 총 10개의 샤드가 존재하게 된다.

 

5. 데이터 모델링 방법

크게 4가지가 있으며 각각 기술적 장단점이 있어서, 데이터 특성 및 상황을 고려하여 적절한 모델링 방법을 적용해야 한다. 


1) Nested 모델링
Nested data type을 활용해 설계하는 방법. 인덱스에서 Nested data type을 선언하고 오브젝트 속성들을 정의하여 Array하게 배치하는 방식이다. 

 

모델링 예시는 공식 문서 참고. 

 

두 개 이상의 속성을 가진 오브젝트를 Array 구조로 표현해야 할 때 사용한다. 

 

2) Parent-Child 모델링
Join data type을 바탕으로 설계하는 방법. 본질적으로 중첩 모델과 유사하다 . 둘 다 하나의 엔터티를 다른 엔터티와 연결할 수 있다. 차이점은 중첩 개체의 경우 모든 엔터티가 동일한 문서 내에 있는 반면 부모-자식의 경우 부모와 자식이 완전히 별개의 문서라는 것이다.

 

전체 도큐먼트에서 업데이트와 삭제가 빈번할 때 사용한다. 

 

3) Application Side Join 모델링

기본 키를 기준으로 엔티티(Entity)들을 서로 다른 도큐먼트에 배치하여 Application side에서 키를 기준으로 조인하여 처리하는 방식. Application side에서 키 값을 기준으로 2회 이상 조회하여 가공해야 하므로 페이징 및 정렬에 유의해야 한다.

 

1:1 관계일 때 자주 사용한다. 


4) Denormalization 모델링

데이터 전체를 비정규화하여 인덱싱하는 방법. 각 데이터의 중복을 허용하여 Join이 필요하지 않도록 한다. 데이터 비정규화의 장점은 속도이다. 단, 데이터 크기가 엄청 증가할 수 있기에 공통 필드의 변경이 번번하거나  한정된 물리 서버로 구성한다면 유의해서 사용해야 한다. 

 

공통 필드의 변화가 적고, 최고의 성능이 필요할 때 사용한다. 

 

6. 번외: AWS Elastic Search는 무엇일까?

2015년 AWS에서 Elasticsearch Service를 Managed Service로 제공한다고 발표했다. 이후  AWS와 Elastic은 오픈 소스 협력에 관한 견해에 차이를 보이면서 서로 다투게 된다. 

 

결국 2021년에 Elastic에서는 7.11 버전부터 새로운 라이센스(SSPL)와  Elastic 라이센스 중에서 하나를 골라 사용할 수 있는 Daul 라이센스를 발표했다. 이에 AWS는 7.10 이후 버전에 대해서 Fork를 통해 독자적으로 Apache 2.0 라이센스를 가지는 오픈 소스 생태계를 유지할 것이라고 발표한다.

 

정리하면  Elastic과 AWS가 오래 전부터 싸워왔고, 결국 Elastic이 SSPL을 채택함으로써 Elasticsearch는 더 이상 오픈 소스가 아니게 됐다. 그리고 2021년에 완전히 갈라져 각자 독자적인 노선을 타고 있다. 

 

 

출처:

https://www.slideshare.net/kjmorc/ss-80803233

https://victorydntmd.tistory.com/308

https://www.elastic.co/guide/en/elasticsearch/reference/7.10/elasticsearch-intro.html

https://blog.opsnow.com/

728x90