티스토리 뷰

반응형

6.8 버전을 기준으로 작성되었다.

 

1. 엘라스틱서치

* 엘라스틱서치는 확장성이 뛰어난 오픈 소스로 전문 검색 및 분석 엔진이다.

* 대용량의 데이터를 거의 실시간으로 저장, 검색 및 분석할 수 있다.


1.1. 관계형 데이터베이스와 비교

엘라스틱서치 RDB
Index Table
Document Row
Field Column
Mapping Schema


* 장점 : 검색이 빠르고 검색하는데 필요한 기능들을 제공
* 단점 : 추가, 수정, 삭제가 느리다.

1.2. 구성요소

1.2.1. 클러스터

* 엘라스틱서치의 가장 큰 시스템 단위이며 하나의 클러스터는 하나 이상의 노드로 구성된다.

* 서로 다른 클러스터는 데이터의 접근, 교환을 할 수 없는 독립적으로 존재한다.

* 여러 대의 서버로 하나의 클러스터를 구성할 수 있으며, 반대로 하나의 서버에 여러 개의 클러스터를 구성할 수도 있다.

* 클러스터는 고유한 이름으로 식별되는데 클러스터에 노드가 포함되기 위해서는 이름에 의해 클러스터의 구성원이 되도록 설정되어 있기 때문에 클러스터의 이름은 중요하다.

* 클러스터에 포함되는 노드는 클러스터의 이름만 동일하게 작성해주면 자동으로 클러스터에 포함된다.

1.2.2. 노드

* 노드는 기본적으로 같은 클러스터에 포함된 모든 노드를 알고 있다.

* 노드는 클러스터에 포함된 단일 서버로 데이터를 저장하고 클러스터의 색인화 및 검색 기능을 수행한다.

* 각 노드는 1개 이상의 데이터 원본과 복사본을 가지고 다른 위치에 나누어 저장한다.

* 노드가 종료되거나 실행에 실패할 경우 다른 노드로 데이터를 이동시킨다.

* 노드는 기본적으로 HTTP 나 Transport 통신을 처리할 수 있다.

* 노드의 기본 설정은 마스터 노드이면서 데이터 노드인데 규모가 커질수록 분리하는 게 좋다.

1.2.2.1. 마스터(master) 노드

* 클러스터를 제어한다.

* 인덱스 작성 또는 삭제, 클러스터의 일부 노드 추적 클러스터에 할당할 샤드 결정과 같은 클러스터 전체에 걸친 작업을 담당한다.

* 클러스터 상태가 안정적인 마스터 노드를 갖는 것이 중요하다.

* 마스터 노드가 안정적인 상태를 유지하기 위해서 마스터 적합 노드와 데이터 노드 사이의 역할을 분리하는 것이 좋다.

1.2.2.2. 데이터(data) 노드

* 데이터를 보유하고 CRUD, 검색 및 집계와 같은 데이터 관련 작업을 수행한다.

* 데이터 노드는 I/O 메모리 및 CPU를 많이 사용하며 이러한 리소스를 모니터링하고 오버로드된 경우가 많은 데이터 노드를 추가하는 것이 중요하다.

1.2.3. 샤드와 복사본

* 모든 데이터를 색인에 모아놓을 경우 성능이 안좋아지는 문제를 해결하기 위해 만들어진 것이 샤드이다.

* 색인된 데이터는 여러 개의 샤드로 분할되어 저장된다.

* 색인을 생성할 때 원하는 수의 샤드를 정의할 수 있으며 기본적으로 생성되는 샤드는 5개이다.

* 생성된 인덱스의 샤드 설정은 변경할 수 없다.

* 샤드는 온전한 기능을 가진 독립적인 "색인"이며, 클러스터의 어떤 노드에서도 호스팅할 수 있다.

* 어떤 이유에서든 샤드/노드가 오프라인 상태가 되거나 사라질 경우를 대비하기 위해 복사본을 생성할 수 있다.

* 복사본은 색인을 생성할 때 복사본의 수를 정의할 수 있으며 기본적으로 1개의 복사본이 생성된다.

* 생성된 인덱스라도 복사본의 수는 언제든 변경할 수 있다.

* 노드가 두 개 이상일 경우 샤드와 복사본은 같은 노드에 존재하지 않는다.

1.2.3.1. 최초 샤드

* 데이터가 색인되어 저장되는 공간이다.

* 최초 샤드에 데이터가 색인되면 동일한 수만큼 복사본을 생성한다.

* 최초 샤드가 유실되는 경우 복사본이 최초 샤드로 승격한다.

* 최초 샤드와 복사본은 서로 다른 노드에 저장한다.

1.2.4. 색인

* 색인은 비슷한 특성을 가진 문서의 모음이다.

* 색인의 이름은 모두 소문자로 이루어져 있어야 한다.

* 색인은 이름으로 식별되며 색인에 포함된 문서에 대한 색인화, 검색, 업데이터, 삭제 작업에서 해당 색인을 가리키는 데 사용된다.

* 단일 클러스터에서 원하는 개수의 색인을 정의할 수 있다.

1.2.5. 문서

* 문서는 색인화할 수 있는 기본 정보 단위이다.

* 문서는 JSON 형식을 사용한다.

* 하나의 색인에 원하는 만큼 문서를 저장할 수 있다.

1.2.6. 색인 별칭

* 인덱스에 별칭을 지정할 수 있으며 여러 인덱스가 하나의 별칭을 가질 수 있다.

* 검색 시 별칭을 통해서 검색할 수 있다.

* 별칭 추가 : POST _aliases { "actions" : [ { "add" : { "index" : "색인명", "alias" : "별칭명" } } ] }

* 별칭 제거 : POST _aliases { "actions" : [ { "remove" : { "index" : "색인명", "alias" : "별칭명" } } ] }

1.3. 용어

1.3.1. term

* 검색엔진에 색인되는 값이다.

* FOO, Foo, foo 모두 다른 값이다.

* Term Query를 이용하여 검색할 수 있다.

1.3.2. text(또는 full text)

* text는 일반적으로 작성되는 문자열을 뜻하며 색인에 저장될 때 term으로 분석된다.

* text는 저장하는 시점에 분석되고 이때 분석되는 용어들로만 검색할 수 있다.

* "색깔"이라는 단어가 "색", "깔"로만 분석되면 "색깔"로는 검색되지 않는다.

1.3.3. _source

* 색인에 저장되어 있는 데이터를 저장해두는 필드이다.

* 검색 쿼리를 통해 검색했을 때 나오는 결과물이 담겨있는 필드이다.

 

2. 검색 방법

* 검색 방법은 크게 쿼리와 필터로 나뉜다.

2.1. 쿼리

2.1.1. Bool Query

* 여러 개의 쿼리를 조합하여 검색하기 위한 쿼리다. 

2.1.1.1. sould(OR 조건)

* 하나의 쿼리 : { "query" : { "bool" : { "should" : { 쿼리 } } } }

* 여러 쿼리 : { "query" : { "bool" : { "should": [ { 쿼리 } , { 쿼리 } ] } } }

2.1.1.2. must(AND 조건)

* 하나의 쿼리 : { "query" : { "bool" : { "must" : { 쿼리 } } } }

* 여러 쿼리 : { "query" : { "bool" : { "must": [ { 쿼리 } , { 쿼리 } ] } } }

2.1.1.3. must_not(NOT 조건)

* 하나의 쿼리 : { "query" : { "bool" : { "must_not" : { 쿼리 } } } }

* 여러 쿼리 : { "query" : { "bool" : { "must_not": [ { 쿼리 } , { 쿼리 } ] } } }

2.1.1.4. 여러 조건의 조합

* { "query" : { "bool" : { "should" : 쿼리 }, { "must" : 쿼리 }, { "must_not" : 쿼리 } } }

2.1.2. Term Query

* 질의문을 분석하지 않고 term과 정확하게 일치하는 내용을 찾기 위해서 사용한다.

* { "query" : { "term" : { "필드" : "검색할 내용" } } }

* "keyword" 검색 시 "keyword"만 검색된다.

2.1.2.1 Terms Query

* 하나의 term 쿼리로 여러 필드에 있는 내용을 검색하고자 할 때 사용한다.

* { "query" : { "terms" : { "필드" : ["검색 내용1", "검색 내용2"] } } }

2.1.3. Match Query

* 질의문을 형태소 분석기를 통해 분석한 후 텍스트 전체에서 검색한다.

* { "query" : { "match" : { "필드" : "검색 내용" } } }

2.1.3.1. Multi Match Query

* 하나의 match 쿼리를 가지고 여러 필드에 있는 내용을 검색하고자 할 때 사용한다.

{ "query": { "multi_match" : { "query": "검색할 내용", "fields": [ "필드1", "필드2" ] } } }

2.1.4. Bulk Query

* 데이터를 추가, 삭제, 수정 처리할 수 있다.

* 여러 쿼리를 모아서 한 번에 실행시킬 수 있도록 도와준다.

* index, create, update, delete 기능이 있다.

* index는 데이터가 없으면 추가하고 있으면 수정한다.

* 각각의 기능은 개행문자를 통해 구분되므로 쿼리문 내부에 개행문자는 없어야 한다.

* index

{ "index" : { "_index" : "인덱스", "_id" : "아이디" } }

{ "필드" : "수정 또는 추가할 값" }

* delete

{ "delete" : { "_index" : "인덱스", "_id" : "아이디" } }

* create

{ "create" : { "_index" : "인덱스", "_id" : "아이디" } }

{ "필드" : "추가할 값" }

* update

{ "update" : {"_id" : "아이디", "_index" : "인덱스"} }

{ "doc" : {"필드" : "변경할 값"} }

2.1.5. Range Query

* 숫자 형태 또는 날짜 형태의 데이터 타입일 때 범위를 지정하여 검색할 수 있다.

* gte : 보다 크거나 같은 값 검색, lte : 보다 작거나 같은 값 검색, gt : 보다 큰 값 검색, lt : 보다 작은 값 검색

{ "query": { "range" : { "필드" : { "gte" : "검색 범위", "lte" : "검색 범위" } } } }

* 날짜일 경우 검색 범위에 now/d, now-7/dnow/M와 같은 값을 넣어 현재 날짜를 기준으로 구할 수 있다.

* 날짜일 경우 "format": "dd/MM/yyyy||yyyy"과 같은 값을 추가해서 날짜 값의 형태를 지정할 수 있다.

* 날짜일 경우 "time_zone": "+01:00"과 같은 값을 추가해 타임 존을 지정할 수 있다.

2.1.6. Query String Query

* 구문으로 분석하기 위해서 구문 분석기를 사용한다.

* 연산자로 구분하여 구문을 분석한 후 검색된다.

* 연산자로 AND와 OR가 있다.

* 연산자는 대소문자를 구분하기 때문에 And나 Or 등 소문자를 포함하여 검색 시 원하는 결과가 나오지 않는다.

* 공백은 연선자로 간주되지 않는다.

* 기본적으로 *,?를 이용한 Wildcard Query를 사용할 수 있고 설정을 통해 막을 수 있다.

* (, )를 통해서 우선 적용할 연산자를 고를 수 있다.

* +를 통해 원하는 단어가 포함된 내용을 검색하거나 -를 통해 빼고 검색할 수 있다.

* 하나의 필드로 검색 : GET _search { "query": { "query_string" : { "default_field" : "필드", "query" : "검색할 내용" } } }

* 여러 필드로 검색 : GET _search { "query": { "query_string" : { "fields" : ["필드1", "필드2"], "query" : "검색할 내용" } } }

2.1.7. boost 속성(검색 쿼리 공통)

* 각 검색 쿼리에서는 boost 값을 주어 score 계산에 영향을 줄 수 있다.

* boost 값이 높을수록 score가 더 높게 나온다. // boost에 2를 준다고 score값이 2배가 되는 것은 아니다.

2.2. filter

* 스코어를 계산하지 않기 때문에 쿼리보다 빠르다.

 

3. 자동완성 구현 방법

3.1. 검색 기능을 활용하는 방법

* Prefix Query를 활용하여 자동완성을 구현하는 방법이다.

3.2. 토크나이저를 활용하는 방법

* NGram이나 Edge_NGram Tokenizer로 분리된 term을 검색하는 방법으로 여타 다른 검색과 다르지 않다.

* `synonym`을 적용하여 동의어도 검색할 수 있다.

3.3. Completion Suggest

* 자동완성을 위해 엘라스틱 서치에서 검색 속도를 최대로 올려 제공하는 기능이다.

* weight으로 중요도 표시가 가능하다.

* 단점 : 무조건 앞에서부터 검색한다. (ex: "가나다 라마바"가 있을 때 "가", "가나" 등으로만 검색이 가능하다)

* synonym을 적용하여 동의어도 검색할 수 있다.

 

4. 데이터 타입

4.1. keyword

* 데이터를 분석하지 않기 때문에 term으로 분해되지 않는다.

* 집계에 사용할 수 있다.

4.1.1. 설정

ignore_above : 설정되는 숫자보다 긴 데이터의 경우 색인 및 저장되지 않으며 따라서 검색되지 않는다.

* index : 기본값은 true이며 false로 설정 시 검색되지 않도록 할 수 있다.

* doc_values : 기본 값은 true이며 false로 설정 시 정렬, 집계 등에서 사용할 수 없도록 할 수 있다.

* norm : 기본 값은 false이고 true로 설정 시 점수를 계산할 때 값의 길이를 포함한다.

* null_value : 기본 값은 값이 없다는 것을 나타내기 위해 null이며 null을 대체할 문자열을 넣을 수 있다.

* store : 기본 값은 false이며 true로 설정 시 값을 _source 필드 이외에 별도로 저장할 수 있다. 특정 상황에서 사용되는데 제목이나 날짜 필드가 있고 매우 큰 내용을 담는 필드가 있을 경우 검색하게 되면 매우 큰 내용도 같이 검색되는데 제목이나 날짜 필드의 값만 검색하고 싶을 때 사용된다.

4.2. text

* 데이터를 분석하여 term으로 분해한다.

* 집계에 사용할 수 없다.

4.2.2. 설정

* analyzer : 색인에 저장될 때 text를 분석하는 분석기를 설정한다. 기본적으로 standard analyzer가 적용되어 있다.

* search_analyzer : 검색할 때 검색하는 키워드를 분석하는 분석기를 설정한다. 설정하지 않으면 analyzer와 동일하게 설정된다.

* index : 기본값은 true이며 false로 설정 시 검색되지 않도록 할 수 있다.

* norm : 기본 값은 false이고 true로 설정 시 점수를 계산할 때 값의 길이를 포함한다.

* store : 기본 값은 false이며 true로 설정 시 값을 _source 필드 이외에 별도로 저장할 수 있다. 특정 상황에서 사용되는데 제목이나 날짜 필드가 있고 매우 큰 내용을 담는 필드가 있을 경우 검색하게 되면 매우 큰 내용도 같이 검색되는데 제목이나 날짜 필드의 값만 검색하고 싶을 때 사용된다.

4.3. date

* 날짜를 표현하기 위한 데이터 타입이다.

* Range Query를 이용할 수 있다.

4.3.1. 설정

* format : date의 포맷을 설정할 수 있다.

* index : 기본값은 true이며 false로 설정 시 검색되지 않도록 할 수 있다.

* doc_values : 기본 값은 true이며 false로 설정 시 정렬, 집계 등에서 사용할 수 없도록 할 수 있다.

* norm : 기본 값은 false이고 true로 설정 시 점수를 계산할 때 값의 길이를 포함한다.

* null_value : 기본 값은 값이 없다는 것을 나타내기 위해 null이며 null을 대체할 문자열을 넣을 수 있다.

* store : 기본 값은 false이며 true로 설정 시 값을 _source 필드 이외에 별도로 저장할 수 있다. 특정 상황에서 사용되는데 제목이나 날짜 필드가 있고 매우 큰 내용을 담는 필드가 있을 경우 검색하게 되면 매우 큰 내용도 같이 검색되는데 제목이나 날짜 필드의 값만 검색하고 싶을 때 사용된다.

4.4. integer

* 숫자를 표현하기 위한 데이터 타입이다.

* -2의 31승 ~ 2의 31승 -1 사이의 값을 갖는 부호가 있는 32 비트 정수

* Range Query를 이용할 수 있다.

4.4.1. 설정

* index : 기본값은 true이며 false로 설정 시 검색되지 않도록 할 수 있다.

* doc_values : 기본 값은 true이며 false로 설정 시 정렬, 집계 등에서 사용할 수 없도록 할 수 있다.

* norm : 기본 값은 false이고 true로 설정 시 점수를 계산할 때 값의 길이를 포함한다.

* null_value : 기본 값은 값이 없다는 것을 나타내기 위해 null이며 null을 대체할 문자열을 넣을 수 있다.

* store : 기본 값은 false이며 true로 설정 시 값을 _source 필드 이외에 별도로 저장할 수 있다. 특정 상황에서 사용되는데 제목이나 날짜 필드가 있고 매우 큰 내용을 담는 필드가 있을 경우 검색하게 되면 매우 큰 내용도 같이 검색되는데 제목이나 날짜 필드의 값만 검색하고 싶을 때 사용된다.

4.5. long

* 숫자를 표현하기 위한 데이터 타입이다.

* -2의 63승 ~ 2의 63승 -1 사이의 값을 갖는 부호가 있는 64 비트 정수

* Range Query를 이용할 수 있다.

4.5.1. 설정

* index : 기본값은 true이며 false로 설정 시 검색되지 않도록 할 수 있다.

* doc_values : 기본 값은 true이며 false로 설정 시 정렬, 집계 등에서 사용할 수 없도록 할 수 있다.

* norm : 기본 값은 false이고 true로 설정 시 점수를 계산할 때 값의 길이를 포함한다.

* null_value : 기본 값은 값이 없다는 것을 나타내기 위해 null이며 null을 대체할 문자열을 넣을 수 있다.

* store : 기본 값은 false이며 true로 설정 시 값을 _source 필드 이외에 별도로 저장할 수 있다. 특정 상황에서 사용되는데 제목이나 날짜 필드가 있고 매우 큰 내용을 담는 필드가 있을 경우 검색하게 되면 매우 큰 내용도 같이 검색되는데 제목이나 날짜 필드의 값만 검색하고 싶을 때 사용된다.

 

5. 동의어(synonym)

* 사전 등록 후 다시 인덱싱해야 사전에 등록한 단어를 활용할 수 있다.

* config 하위 파일의 인코딩 방식은 utf-8이어야 한다.(아니면 에러가 발생할 수 있다.)
* 동의어 사전과 분석기 사전에 동일한 내용을 넣으면 에러가 발생한다. 예) sell-in sell (둘 중 하나의 사전에만 넣어도 동일하게 동작하도록 구현할 수 있다.) // https://github.com/elastic/elasticsearch/issues/37751
* 한글 분석기 nori 사용 시 decompound_mode=mixed를 사용하면 동의어 사전과 충돌한다.
* 동의어 사전에서 `=>` 키워드 사용 시 A => B 일 때 B로 검색하면 A가 나오지만 A로 검색하면 B가 나오지 않는다.

 

6. Analyzer

* Tokenizer를 통해 문자열을 분석한다.

* Analyzer는 전체 문자열을 용어로 변환하는 프로세스이다.

* Analyzer를 통해 변환되는 용어는 실제로 색인에 저장되는 용어이다.

* Analyzer의 종류나 설정에 따라 다르지만 FOO BAR, Foo-Bar, foo, bar가 모두 foo와 bar라는 용어로 분석될 수 있다.

6.1. Standard Analyzer

* Standard Tokenizer를 기반으로 동작하는 분석기다.

6.2. Whitespace Analyzer

* Whitesapce Tokenizer를 기반으로 동작하는 분석기다.

6.3. Keyword Analyzer

* 데이터 타입이 Keyword인 것처럼 데이터를 분해하지 않는다.

6.4. 분석기를 테스트하는 방법

* 엘라스틱서치에서 제공하는 분석기 : POST _analyze { "analyzer": "분석기", "text": "테스트할 값" }

* 인덱스에 세팅한 분석기 : POST 인덱스/_analyze { "analyzer": "분석기", "text": "테스트할 값" }

* 필드에 적용된 분석기 : POST 인덱스/_analyze { "field": "필드", "text": "테스트할 값" }

 

7. Tokenizer

* 문자열을 분석하는 방법을 나타낸다.

7.1. Standard

* Unicode® Standard Annex #29에 명시된 유니 코드 텍스트 분할 알고리즘을 기반으로 동작한다.

* 공식문서에 대부분의 언어에서 잘 작동한다고 작성되어 있다.

7.2. Whitespace

* 공백 문자를 만날 때 텍스트를 term으로 분리한다.

* 대소문자를 구분한다.

7.3. nori

* mecab-ko-dic 사전을 사용하여 제작되었으며 엘라스틱서치에서 기본적으로 제공하는 한글 형태소 분석기이다.

* 플러그인을 수동으로 설정해줘야 한다.

* 필요에 따라 사전을 생성하여 직접 단어를 추가할 수 있다.

7.4. NGram

* text를 잘게 분해한다.

* ngram에 대한 기본 설정은 min_gram값과 max_gram값의 차이는 1로 정해져 있다.

* 색인을 생성할 때 setting의 속성으로 max_ngram_diff에 값을 주는 것으로 min_gram값과 max_gram값의 차이를 더 크게 할 수 있다.

ex) cat => cat, ca, at, c, a, t  // 설정에 따라 다르게 분해할 수 있다.

7.5. Edge_NGram

* 앞부분을 기준으로 잘게 분해한다.

ex) cat => cat, ca, c  // 설정에 따라 다르게 분해할 수 있다.

 

8. 설정

* http.max_content_length : HTTP 요청 내용의 최대 길이를 제어한다. 기본값은 100mb이며 2GB를 넘을 수 없다.

 

9. 점수

9.1. 점수란?

* 검색했을 때 나오는 결과에 대한 정확도가 높은 결과부터 보여주기 위한 내용이다.

* 검색했을 때 점수가 높은 결과가 먼저 나온다.

9.2. 점수 계산 방식

* Term frequency: 필드 안에 term이 자주 출현할 수도록 고득점

* Inverse document frequency: 많은 문서에 포함된 용어일 경우 중요도가 낮다고 보기 때문에 저득점

* Field length normalization: 용어의 수가 많은 필드보다 용어의 수가 적은 필드에서 일치할 경우 고득점

 

10. 백업

10.1. 기초작업 : elasticsearch.yml 파일에서 path.repo: ["경로"] 설정이 필요하다.

10.2. 기본 설정 : PUT /_snapshot/이름 { "type": "fs", "settings": { "location": "경로" } }

* "settings"에 "compress": true 설정을 추가하여 압축할 수 있다.

10.3. 백업 : PUT /_snapshot/backup/snapshot

* "ignore_unavailable": true => 존재하지 않는 색인은 저장하는 동안 무시하며 설정하지 않았을 때 존재하지 않는 색인을 저장하려고 하면 실패한다.

* "include_global_state": false => 클러스터의 글로벌 상태를 저장하지 않기 위한 설정이다. true일 경우 색인의 모든 샤드가 살아있지 않은 경우 실패한다.

10.4. 복원 : POST /_snapshot/backup/snapshot_1/_restore

* "indices" : "색인명" => 원하는 색인만 복원할 수 있도록 지원한다.

반응형
댓글
반응형
최근에 올라온 글
Total
Today
Yesterday
글 보관함
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31