DB/ElasticSearch

[ElasticSearch] 기본 개념과 특징(장단점) + 써야 하는 8가지 이유

HMHA 2023. 2. 9. 11:57
300x250
반응형

Lucene

검색엔진의 시초, Lucene

모든 검색엔진의 시초는 루씬(Lucene).
더그 커팅이 고안한 역색인(Inverted Index) 구조인 아파치 루씬을 기반으로 분산처리를 가능하게 한 아파치 솔라(Solr)가 등장해서 검색엔진 시장을 장악했고, 몇 년 후에 역시 루씬을 기반으로 한 Elastic Search가 등장해 지금은 검색엔진 분야에서 지배적인 위치에 있다.

서치엔진 순위 트렌드. 2016년 무렵부터 ES가 가장 많이 사용되고 있다.(https://db-engines.com/en/ranking_trend/search+engine)

ES와 RDBMS

조금 더 쉬운 개념 파악을 위해서 ES에서 사용되는 데이터 구조를 RDBMS에 대응해보면 다음과 같이 맵핑된다.

데이터 구조

Elastic Search는 기본적으로 http 프로토콜로 접근이 가능한 REST API를 통해 데이터 조작을 지원한다. 이를 역시 RDBMS의 SQL과 맵핑해보면:

ES의 HTTP METHOD와 SQL

역색인

일반적인 DB에서는 볼 수 없는 개념인 ‘역색인'은 뭘까?
간단하게 컨셉만 훑어보면,
일반적인 색인의 목적은 ‘문서의 위치’에 대한 index를 만들어서 빠르게 그 문서에 접근하고자 하는 것인데, 역색인은 반대로 ‘문서 내의 문자와 같은 내용물’의 맵핑 정보를 색인해놓는 것이다.
역색인은 검색엔진과 같은 문서의 내용의 검색이 필요한 형태에서 전문 검색의 형태로 주로 쓰인다.
쉬운 예시로 들어보면 일반 색인(forward index)은 책의 목차와 같은 의미이고, 역색인(inverted index)은 책 가장 뒤의 단어 별 색인 페이지와 같다.

모든 단어가 어떤 document에 있는지 색인해두는 것을 역색인이라고 한다. (https://www.elastic.co/blog/found-elasticsearch-from-the-bottom-up)

만약 DB에서 “Trade”라는 문구가 포함된 문자열을 찾으려고 한다면 SQL에서는 %Trade% 라고 명확히 입력해야 검색이 가능할 것이다. trade, TRADE, trAde…. 등의 문자열은 직접 하나하나 명시하기 전에는 찾을 수 없을 것이다. ES의 역색인을 활용하면 대소문자 구분 없이 어떤 문구가 들어와도 찾을 수 있다.

ES의 특징과 장단점

ES도 NoSQL의 일종으로 분류할 수 있고, 분산처리를 통해 실시간성으로 빠른 검색이 가능하다. 특히 기존의 데이터로 처리하기 힘든 대량의 비정형 데이터 검색이 가능하며 전문 검색(full text) 검색과 구조 검색 모두를 지원한다.
기본적으로는 검색엔진이지만 MongoDB나 Hbase와 같은 대용량 스토리지로도 활용이 가능하다.

ES의 장점과 단점에 대해서 간단히 살펴보자.

장점

  • 오픈소스 검색엔진이다. 활발한 오픈소스 커뮤니티가 ES를 끊임없이 개선하고 발전시키고 있다.
  • 전문검색
    내용 전체를 색인해서 특정 단어가 포함된 문서를 검색할 수 있다. 기능별, 언어별 플러그인을 적용할 수 있다.
  • 통계 분석
    비정형 로그 데이터를 수집하여 통계 분석에 활용할 수 있다. Kibana를 연결하면 실시간으로 로그를 분석하고 시각화할 수 있다.
  • Schemaless
    정형화되지 않은 문서도 자동으로 색인하고 검색할 수 있다.
  • RESTful API
    HTTP기반의 RESTful를 활용하고 요청/응답에 JSON을 사용해 개발 언어, 운영체제, 시스템에 관계없이 다양한 플랫폼에서 활용이 가능하다.
  • Multi-tenancy
    서로 상이한 인덱스일지라도 검색할 필드명만 같으면 여러 인덱스를 한번에 조회할 수 있다.
  • Document-Oriented
    여러 계층 구조의 문서로 저장이 가능하며, 계층 구조로된 문서도 한번의 쿼리로 쉽게 조회할 수 있다.
  • 역색인(Inverted Index)
  • 확장성
    분산 구성이 가능하다. 분산 환경에서 데이터는 shard라는 단위로 나뉜다.

단점

  • 완전 실시간은 아니다.
    색인된 데이터는 1초 뒤에나 검색이 가능하다. 내부적으로 commit과 flush같은 복잡한 과정을 거치기 때문.
  • Transaction Rollback을 지원하지 않는다.
    전체적인 클러스터의 성능 향상을 위해 시스템적으로 비용 소모가 큰 롤백과 트랜잭션을 지원하지 않는다. 조심하자..
  • 데이터의 업데이트를 제공하지 않는다.
    업데이트 명령이 올 경우 기존 문서를 삭제하고 새로운 문서를 생성한다. 업데이트에 비해서 많은 비용이 들지만 이를 통해 불변성(Immutable)이라는 이점을 취한다.

ES 기본용어

하나의 Index는 복수의 Shard로 구성. Shard와 Lucene Index는 1:1로 맵핑된다.

  • 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        }
    }
} 

위의 설정값이 서버에 적용되면 아래와 같은 형태가 된다.

인덱스별로 샤드 2개, 리플리카 1개

초록색 네모는 Primary shard, 투명한 네모는 Replica이다.
a 인덱스를 예시로 보면, a0 a1 두개의 shard로 구성되었으며, 이는 각각 node1과 node2에 저장되어 있다.
a0 a1 shard의 replica는 각각 다른 node인 node4와 node3에 저장되어 있다.

ES 주요 API

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

각 API는 별도로 직접 커맨드를 날려보는 것이 좋고, 혹은 실무에서 사용하게될 때는 어차피 문서를 뒤적거려야할 것이 분명하므로..
아래는 API별 눈에 띄는 특징들에 대해서만 정리했다.

인덱스 관리 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가 강력한 이유중 하나 : 버킷 안에 다른 버킷의 결과를 추가할 수 있다. 다양한 집계 유형을 결합, 중첩, 조합이 가능

더 알아보기

샤드를 설정하는 기준에 대해서 알아보았습니다: [샤드의 개수와 크기는 어떻게 정할까?]

Reference

엘라스틱서치 실무 가이드(2019), 위키북스

 

엘라스틱 서치를 써야 하는 8가지 이유

 

Schemaless와 문서지향

 

엘라스틱 서치는 JSON 구조를 사용하여 기존의 RDMS와 같은 엄격한 구조를 적용하지 않는다. 비정형 데이터는 비구조적이며, 스키마(Schema)가 다이나믹하게 변할 수 있다. 전통적인 관계형 구조로 구성할 경우 프로젝트 막바지에 모든 스키마를 변경하고, 데이터를 다시 구성하는 문제에 봉착할 수 있는데 JSON 구조는 이런 문제들을 사전에 막을 수 있다.

 

또다른 장점으로 데이터 공간을 절약할 수 있다. 컬럼을 동적으로 정의하여, 필요한 데이터만 넣게 되어 데이터 공간 및 CPU 사용량, 네트워크 트래픽도 줄일 수 있는 효과를 볼 수 있다. 아래의 예시를 한번 보도록 하자

 

 

데이터 예시 1

{

"title":"엘라스틱에 대하여",

"author":"강철의 기술사",

"date":"2020-04-20"

}

 

위와 같이 title, author, date 필드(DB로 따지면 컬럼)으로 된 한개의 데이터가 있다. JSON은 다음과 같이 구조를 유연하게 만들 수 있다.

 

데이터 예시 2

{

"title":"동해물과 백두산이 마르고 닳도록...",

"author":"안익태",

"date":"2020-03-10",

"type":"음악"

}

 

다음과 같이 하나의 공간에서 type이라는 컬럼을 추가할수도 있다. 일반적인 database구조였다면 첫번째 예시에도 type를 만들어야 하고, 공백이라도 넣어야 되겠지만 JSON 구조로 만든 것들은 모두 독립적인 데이터 구조를 가져도 문제가 없다. 물론 이로 인해서 개발자들이 힘들어 하는 경향이 있지만, 그것도 어디까지나 포맷을 잘 맞추고 파싱 방식을 잘하게 되면 이 방식에 큰 문제를 느끼지 않게 된다.

 

누구는 DB의 트래픽 역시 마찬가지로 줄일 수 있다는 식의 얘기로 정규화, 조인등을 말할 수 있을 것이다. 그러나 그렇게 구성을 만들 경우 DB 설계를 처음부터 다시 할 수 있으며 DB의 조인등의 연산으로 인해서 DB에서의 CPU 사용률 부하는 필연적으로 있을 수 밖에 없다.

 

 

검색능력(Searching)

 

엘라스틱서치는 기본적으로 검색엔진이다 그렇기에 검색 기능 뿐만 아니라 특히 Full-text 검색 능력이라는 강력한 기능을 탑재하고 있다. 예를 들어 구글 사이트에서 문장을 입력하여 연관된 문서, 이메일 그리고 문서 파일등을 출력하고 싶으면 어플리케이션에 Elastic Search를 설치하는 것이 매우 쉬운 방법이 될 것이다.

 

이것은 개발자들이 흔히 사용하는 관계형 데이터베이스(ex: Oracle, Mysql)의 문자열 컬럼에 대해 실행되는 단순한 SQL 질의와는 상당히 다르다. (ex: like 쿼리) 기본적으로 엘라스틱은 검색을 할 수 있는 Term(의미의 최소단위)로 단어의 형태소 분석을 수행하고, 이 단어들과 연관된 문서를 매핑하여 검색을 시켜주는 개념으로 문서를 통째로 like 검색하는 DB와는 구조적으로 다르다(DB는 형태소 분석을 하지 않음)

 

 

분석(Analytics)

엘라스틱서치를 탑재한 만든 사이트에 접속하는 사람들의 OS가 무엇인지, 혹은 어느 나라에서 접속했는지 등을 알고 싶을 때 엘라스틱의 분석 기능을 사용하면 편리하게 알 수 있다.

 

 

풍부한 API와 REST 지원

엘라스틱은 기본적으로 Java, C#, Python, PHP, Javascript, Ruby, Perl 등 20개의 프로그램 언어를 지원하며, 기본적으로 Elasticsearch는 REST API를 제공하여 REST API를 사용하는 모든 언어에서 HTTP 형식으로 사용할 수 있다.

 

쉬운 작동, 쉬운 확장

single node instance로 작동을 하며, 수백개의 스케일 아웃을 쉽게 할 수 있다. Elasticsearch는 대부분의 빅데이터 플랫폼들이 그러하듯 Vertical Scaling보다 Horizontal Scaling을 사용한다.

 

Vertical Scaling은 CPU 및 CPU Cores를 늘리거나, 메모리, 저장장치 등을 늘려서 한대의 서버의 성능을 올리는 것을 말하며 Horizontal Scaling은 같은 타입의 서버들을 분산하여 늘리는 방식으로 비용적인 측면과 확장적인 측면에서 일반적으로 Vertical 방식보다 효율적이고 효과적이다

 

 

Near real-time(근접 실시간)

검색엔진은 기본적으로 형태소를 분석하고 색인을 해야 하는 시간이 다른 DBMS보다 오래 걸린다. 엘라스틱 역시 데이터를 삽입한 순간 약 몇초정도는 이 단계를 지나며 그 후 검색을 할 수 있다. 

 

 

Lightning-fast (빠른 속도)

엘라스틱 서치의 DNA는 Lucene(Java 기반의 검색엔진 라이브러리)이기 때문에 단어 입력후 문서를 찾는 속도가 다른 NoSQL들에 비해 매우 빠르다.

 

 

Fault-tolerant (내고장성)

노드 실패시 replicate된 다른 노드에서 데이터를 가져오며, 네트워크 실패 시 다른 마스터 복제본으로 선택한다.

 


해당 내용은 Learning Elastic Stack 7.0을 참고하였고 필자의 생각을 포함하여 적었습니다. 책에서는 엘라스틱의 매우 좋은 부분들을 다뤘습니다. 당연히 엘라스틱을 공부하는 사람에게 부정하는 글을 적을 수 없을테고 일반인들은 다른 검색엔진을 다뤄본적이 없으니 오로지 Elasticsearch vs 일반적인 DBMS로 구도를 잡게 됩니다.

 

그러나, 필자는 검색엔진 업체에 약 8년간 근무를 하면서 얻은 경험과 엘라스틱 서치를 써서 한때 크게 낭패를 봤던 경험을 복합하여 말하자면 케이스 바이 케이스입니다. 즉, 상용 검색엔진을 사용할 수 있으면 사용하는 것이 좋고, 만약에 비용 문제로 모든 서버에 상용 검색엔진을 들일 수 없다고 한다면 리스크가 적은 곳에 엘라스틱 서치를 사용하는 것이 좋습니다.

 

엘라스틱의 가장 큰 문제점은 바로 Java 기반으로 만들어졌고, 태생이 Lucene 입니다. 누구는 속도가 빠르다고 하는데 검색엔진에서 속도를 좌지우지하는 것은 바로 엔지니어의 역량 및 형태소 분석 속도입니다. C/C++ 기반의 다른 상용 검색엔진보다 엘라스틱이 더 빠를 순 없습니다. 엘라스틱이 만약에 더 빠르다면 여러가지 기능들이 빠져 있다는 거죠. 이는 뭐랑 비교하는 것과 같다면, 제가 만든 하루만에 만든 심플한 검색엔진이 엘라스틱서치보다 빠르기에 제것이 더 좋다라는 궤변과 같습니다.

 

상용 검색엔진은 동사무소의 홈페이지에 넣어도 1천~2천만이 훌쩍 넘는 고가의 엔진입니다. 그런 상용 엔진과 엘라스틱의 성능을 비교하는 것 그리고 특히 해외 검색엔진과 형태소를 분석하기 위한 단어의 개수만 수백만개를 가지고 있는 검색엔진과 비교하는 것은 무리가 있을 것입니다.

 

그러니 머리속에서 엘라스틱 서치가 최고의 솔루션이다라는 환상에서 벗어나는 것이 좋습니다. 물론 상용 검색엔진을 다루기 힘든 분들에게는 최고의 선택이 될 수 있겠지만 말입니다.

 

 

참고자료

Learning Elastic Stack 7.0 Second Edition

 

 

출처 : https://jaemunbro.medium.com/elastic-search-%EA%B8%B0%EC%B4%88-%EC%8A%A4%ED%84%B0%EB%94%94-ff01870094f0

 

[Elastic Search] 기본 개념과 특징(장단점)

엘라스틱서치의 기본 개념, 특징에 대해 정리

jaemunbro.medium.com

 

출처2 : https://needjarvis.tistory.com/519

 

엘라스틱 서치(Elasticsearch)를 써야 하는 8가지 이유

엘라스틱 서치를 써야 하는 8가지 이유 Schemaless와 문서지향 엘라스틱 서치는 JSON 구조를 사용하여 기존의 RDMS와 같은 엄격한 구조를 적용하지 않는다. 비정형 데이터는 비구조적이며, 스키마(Sche

needjarvis.tistory.com

 

 

300x250
반응형