본문 바로가기

데이터베이스(DA, AA, TA)/NoSQL

[ELK] 엘라스틱서치 배우기

Elastic Search의 이용


- 위키피디아: ElasticSearch를 이용해 전문검색(Full Text Search)을 수행하고 실시간 타이핑 검색, 추천 검색어 기능 등에 활용 중.

- 더가디언지: 방문객의 로그 분석을 통한 소셜 데이터를 생성해 실시간 응대와 기사에 대한 반응 분석 등에 ElasticSearch를 사용 중.

- 스택오버플로우: 검색 내용과 결과를 통합해 유사한 질문과 해답을 연결하는데 ElasticSearch를 활용.

- 깃허브: 1,300억 줄이 넘는 소스 코드를 검색하는데 ElasticSearch를 사용 중.


http://www.elasticsearch.org/case-studies




Search Engine 아키텍처 (https://www.searchtechnologies.com/blog/search-engine-security-architecture)



데이터는 검색에 사용되기 위해 별도의 재시작이나 상태의 갱신이 필요하지 않음.

데이터는 색인작업이 완료됨과 동시에 바로 검색할 수 있음.


노드 - 데이터 색인 / 검색 기능을 수행하는 Elastic Search의 단위 프로세스


단일 노드로 시스템을 구성한 후에 시스템의 규모가 늘어나면, 기존 노드 + 새 노드를 실행해 연결하는 것으로 쉽게 시스템 확장이 가능함.


데이터는 각 노드에 분산 저장되고 복사본을 유지해 각종 충돌로부터 노드 데이터 유실 방지.


항상 일정한 데이터 복사본의 개수를 유지 + 높은 가용성(High Availability) + 안정성 보장.



ElasticSearch의 데이터는 분리된 인덱스들(Indices)에 그룹으로 저장됨. 인덱스는 RDB의 데이터베이스로 대응됨. RDB에서 다른 Database 검색을 위해서는 별도의 커넥션을 생성해야 하는 것과 달리 ElasticSearch에서는 데이터를 검색할 때 서로 다른 인덱스의 데이터를 바로 하나의 질의로 묶어서 검색하고 여러 검색 결과를 하나의 출력으로 도출할 수 있다. 이를 Multi Tenancy라고 부름.


private final String INDEX = "device_info";
private final String TYPE = "logs"; // "doc"

QueryBuilder query = QueryBuilders.boolQuery().must(QueryBuilders.matchQuery("date", today));

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(query);

SearchRequest searchRequest = new SearchRequest();
searchRequest.indices(INDEX).types(TYPE).source(searchSourceBuilder);
SearchResponse searchResponse = getEsClient().search(searchRequest);


데이터의 전체 문장에서 검색어를 추출해 저장 / 이를 바탕으로 검색하는 전문검색(Full Text Search) 지원


NoSQL과 같이 Schema Free를 지원 / 별도의 사전 매핑 없이 JSON 문서 형식으로 데이터 입력하면 바로 검색 가능한 형태로 색인 작업이 수행.


RDB에서는 데이터를 테이블 구조로 저장하지만, 아파치 Lucene에서는 데이터를 검색할 수 있는 구조로 저장하기 위해 색인(indexing) 절차를 거쳐 입력된 텍스트로 토큰을 변환해 역파일 색인(inverted index)라는 구조로 저장함.



ElasticSearch와 MongoDB는 모두 JSON 문서를 사용하므로 사용 방법이 매우 유사하지만 서로 다른 목적으로 만들어졌음. 보통 데이터 저장이 중요한 시스템에는 몽고DB를, 검색이 중요한 시스템에는 ElasticSearch를 사용하도록 권장.




Elastic Search 데이터 구조


서로 다른 인덱스와 타입들은 서로 다른 매핑 구조로 구성되며 각각 다른 공간에 저장/처리 된다. Elastic Search는 Multi Tenancy를 지원하므로 _all 명령어나 와일드카드 질의 등으로 여러 개의 인덱스를 한꺼번에 묶어 검색하거나 처리할 수 있다.


데이터 추출 과정과 저장 공간인 index인 색인과, Elastic Search의 데이터 구조 Index는 다른 개념이다.


http://host:port/{인덱스}/{타입}/{도큐먼트 id} -d '{데이터}'


인덱스는 _all 명령어로 모든 인덱스를 표현할 수 있으며 어떤 명령은 인덱스와 타입에 콤마(,)와 와일드카드 문자를 사용해서 다중 표현이 가능하다. 데이터는 -d 옵션 뒤에 작은따옴표(')로 묶어 표현하며 여기에 사용되는 데이터 형식은 항상 JSON이다.


 관계형 DB

 Elastic Search

 데이터베이스(Database)

 인덱스(Index)

 테이블(Table)

 타입(Type)

 열(Row)

 도큐먼트(Document)

 행(Column)

 필드(Field)

 스키마(Schema)

 매핑(Mapping)





Elastic Search 시스템 구조


ElasticSearch의 가장 큰 시스템 단위는 클러스터이다. 서로 다른 클러스터는 데이터의 접근/교환을 할 수 없는 독립적인 시스템으로 유지된다. 여러 대의 서버가 하나의 클러스터를 구성할 수 있고, 하나의 물리적인 서버에 여러 개의 클러스터가 존재할수도 있다.


클러스터 -> 노드, 노드, 노드 ...


클러스터는 하나 이상의 노드로 이루어져 있으며, 노드는 각 하나의 ElasticSearch 프로세스로써 실행됨. 별도의 설정을 하지 않고 Elastic Search를 실행하면 임의의 이름의 노드 하나가 생성된다. 같은 시스템, 또는 네트워크 바인딩이 되도록 설정한 다른 시스템에서 다시 한번 같은 클러스터명으로 설정된 ElasticSearch를 실행하면 또다시 임의의 이름의 새로운 노드가 실행되면서 두 개의 노드는 하나의 클러스터로 바인딩 되어 묶인다.


config/elasticsearch.yml 파일에서 cluster.name을 서로 다른 이름으로 설정한 노드 두 개를 실행하면 바인딩 되지 않고 각각 다른 클러스터를 구성하게 된다.


이렇게 ElasticSearch는 클러스터명을 같게 유지하는 것만으로 손쉽게 하나의 시스템으로 묶을 수 있다. 즉, 클러스터명만 같게 유지하고 프로세스만 실행하면 시스템의 확장이 끝난다. 수많은 데이터를 처리하기 위해 수시로 Scale-Up / Scale-Out을 요구하는 시스템에는 더할 나위 없이 적합한 기능을 제공한다.



Master Node & Data Node


마스터 노드: 전체 클러스터의 상태에 대한 메타 정보를 관리하는 노드.

기존의 마스터 노드가 종료되는 경우, 새로운 마스터 노드가 선출 된다. config/elasticsearch.yml 설정 파일에서 node.master 속성이 true인 노드는 마스터 노드로 선출될 수 있다(반드시 마스터 노드가 되는 것은 아님. 선출의 가능성일뿐) node.master 속성을 false로 지정하면 해당 노드는 마스터 노드의 선출 후보로 선정되지 않는다.


데이터 노드: 색인된 데이터를 실제로 저장하는 노드.

node.data 속성을 false로 지정하면 해당 노드는 데이터를 저장하지 않는다.



샤드와 복사본


사용자는 인덱스 단위로 데이터를 처리하고 샤드는 ElasticSearch가 직접 노드로 분산시키는 작업을 한다. 처음에 데이터가 색인돼 저장되는 공간을 최초 샤드(Primary Shard)라고 한다. 최초 샤드에 데이터가 색인되고 나면 다시 동일한 최초 샤드 수만큼 복사본을 생성한다.


- 데이터 손실(Fail Over)을 방지하는 목적으로, 최초 샤드가 유실되는 경우 복사본을 최초 샤드로 승격시켜 시스템의 무결성을 유지

- 성능 향상을 목적으로 최초 샤드와 복사본을 동시에 검색해서 더 빠르게 데이터를 찾을 수 있다.





Elastic Search


Elastic Search의 검색 기능은 질의(query) 명령어를 이용해 수행된다. 질의는 타입/인덱스 그리고 여러 개의 인덱스를 묶어서 멀티 인덱스 범위로 질의할 수 있다. 여러 인덱스를 묶어서 처리하는 Elastic Search의 특징을 Multi Tenancy라고 한다.



Bool Query

bool 쿼리는 내부의 질의로 다른 쿼리를 포함시켜 사용한다. 쿼리를 조건문인 boolean combination으로 적용해서 최종 검색 결과를 나타낸다. bool 쿼리에 사용할 수 있는 조건문으로는 다음 3가지가 있다.


must - 이 쿼리에 반드시 해당 (AND 조건)

must_not - 이 쿼리에 해당돼서는 안된다. (NOT 조건)

should - 이 쿼리에 반드시 해당될 필요는 없지만 해당된다면 더 높은 스코어를 가진다. (OR 조건)