# Elastic Summary 개념 정리

## Elastic Search

해당 문서는\
Elastic 가이드북 - <https://esbook.kimjmin.net/\\>
Elastic Search 인프런 강의 - <https://www.inflearn.com/course/elasticsearch-essential/dashboard\\>
를 기반으로 작성되었습니다

### Elastic Search 란?

Apache Lucene 이라는 검색 기능을 제공해주는 자바 라이브러리를 기반으로 만든 오픈 소스 검색 엔진입니다\
JSON 기반의 문서를 저장하고 검색하는 것이 가능하며 해당 데이터들을 분석하는 작업 또한 가능합니다\
elasticsearch 는 검색을 위해서 단독으로도 사용하는 것이 가능하기도 하고 ELK(Elasticserch, Logstatsh, Kibana)로 조합해서 사용하는 것도 가능합니다\
조합해서 사용하게 되면 흐름은 이렇습니다\\

1. logstash : 로그나 데이터를 수집/집계/파싱 후 elasticsearch 로 전달
2. elasticsearch : logstash 로부터 전달받은 데이터를 검색/집계
3. kibana : elasticsearch 의 검색으로 수집한 데이터를 시각화 / 모니터링

Elasticsearch 의 특징으로는 아래와 같은 내용이 있습니다

* realtime 검색 시스템
  * Elasticsearch 클러스터가 돌고 있는 동안 검색과 데이터의 적재가 거의 동시에 일어나고 있기 때문에 엄청나게 빠른 속도를 자랑합니다
* 클러스터 구조
  * 하나 이상의 노드로 구성해서 데이터 관리, 검색에서 높은 수준의 안정성을 보여줄 수 있으며 부하의 분산도 가능합니다
* Rest API 기반의 인터페이스
  * 단순하게 Elasticsearch 서버에 api 을 쏘는 방식으로 데이터를 입력, 조회, 수정 등 다양한 elasticsearch의 기능들을 시용하는 것이 가능합니다
* 동적 스키마 생성
  * RDBMS 와 비교해서 생각해보면, 스키마를 생성하고 데이터를 적재하는 방식이 아니라 동적으로 생성하기 때문에 따로 미리 정의할 필요가 없습니다

\
\\

### Elastic Search 의 기본 개념

#### ES의 시스템 구조

간단한 도식화 ![img\_1.png](https://1004662897-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWIONvtnbdGZDNTxRR2%2Fuploads%2Fgit-blob-724ca6b249d31a74ff0f20184da4a8c9ff0e86a0%2Fimg_1.png?alt=media)\
Elasticsearch 는 **클러스터링 구조**를 가지고 있으면서 클러스터 내부에서는 **여러개의 노드**로 나뉘어져있으며,\
각각의 노드 안에는 **인덱스**들이 구성되어 있습니다\
\
\\

**클러스터**

위키백과에서는 '컴퓨터 클러스터는 여러 대의 컴퓨터들이 연결되어 하나의 시스템처럼 동작하는 컴퓨터들의 집합을 말한다' 라고 정의되어 있습니다\
ES을 가장 밖에서 봤을 떄의 구조라고 볼 수 있습니다\\

\
\\

**노드**

클러스터 내부에 구성되어 있는 각각의 기능을 가진 하나의 단위라고 볼 수 있습니다\
각각의 노드는 가장 많이 사용하는 종류로 나누어 4개로 나눌 수 있습니다\\

* 마스터 노드 : 클러스터 상태 관리 및 메타 데이터 관리
  * 인덱스 생성/삭제, 데이터를 샤드에 분배
  * 마스터 노드가 있어도 마스터 노드가 뻗는 경우에 다음 마스터 노드를 설정할 수 있도록 **후보 마스터 노드**를 가질 것인지에 대한 여부를 설정할 수 있습니다
* 데이터 노드 : 문서 색인 및 검색 요청 처리
  * 해당 노드에 데이터를 저장할 것인지 지정하는 것이 가능합니다
* 코디네이팅 노드 : 데이터, 마스터 노드의 일을 대신할 수 있는 노드 > 로드밸런싱처럼 대규모 클러스터 구조에서 유용
* 인제스트 노드 : 색인되는 문서의 데이터 전처리

\\

클러스터 구조를 가져가고 있는 ES이기 떄문에 가지는 특징들도 있습니다.\
위에서 정의한 노드들의 4가지 기능들은 뭐 각각의 특징을 가지고 있다고는 했지만 사실 모든 각각의 노드들은 위에서 정의한 모든 역할을 수행하는 것이 가능합니다\
그렇기 때문에 기본적으로는 >> 어떤 노드에게 요청을 하던지 모든 노드는 **동일한 결과**를 돌려줄 것이라는 것입니다\
\\

위에서 많이 쓰인다고 언급한 각각의 노드의 각 기능들은 config 에서 true/false 값의 조정을 통해서 설정하는 것이 가능한데\
각 노드에 각각의 기능을 설정하는 작업을 통해서 각 노드에서 모든 기능을 수행하는 것이 아닌 MSA 와 같이 각각의 독립적인 기능을 한 노드를 구성하는 것이 가능합니다\
해당 작업의 의의는 노드밸런싱을 통해서 각 노드별로 부하가 가지 않도록 처리하고 각 노드에 맞게 라우팅해주는 작업이 필요합니다\
\
\\

**인덱스와 샤드**

요기 부분은 실제로 데이터가 들어가는 부분에 대한 내용이기 때문에 RDBMS와 비교한 용어를 보면 편할 것 같아서 정리해봤습니다

| RDBMS    | ES       |
| -------- | -------- |
| database | index    |
| schema   | mapping  |
| row      | document |

\\

위의 표를 정리해보면 ES 에서는 RDBMS에서 저장되는 데이터를 보고 document 이라고 명명하고 있으며\
document를 모아둔 집합을 보고 인덱스라고 명명하고 있습니다\\

**인덱스란**\
document가 저장되는 논리적인 공간이고 인덱스가 구성이 되어있어야만 document을 저장하는 것이 가능합니다\
인덱스를 설계하는 것이 ES을 사용하는데 가장 고려가 필요한 부분이라고 합니다\\

\
예시)\
book, magazine, dvd 이러한 개념들이 있다고 가정해봅시다\
이들을 각각의 index으로 저장할 것인지 vs library 이라는 공통된 index 으로 저장할 것인지\
나눈다면 > 관리 리소스가 요하지만 쿼리나 문서구조가 간단\
통합한다면 > 관리적인 관점에서는 편리하지만, 쿼리나 문서구조를 포기\
강의에서는 우선 저장하고자 하는 애의 통합적인 것으로 구조를 잡아두고 쪼개는 방식을 추천\
\\

**샤드란**\
인덱스에 색인되는 문서가 저장되는 공간이고 하나의 인덱스는 반드시 하나 이상의 샤드를 갖습니다\
따라서 인덱스(1)는 (n)개의 샤드로 분리되어 각 노드에 분산되어 저장되게 됩니다\
+샤드는 ES의 기반인 루씬(Lucene)의 단일 검색 인스턴스\
\\

샤드의 종류는 크게 프라이머리 / 레플리카 이렇게 나뉘어집니다\
프라이머리는 document가 저장되는 원본 샤드이고, 해당 샤드는 색인과 검색 성능 모두에게 큰 영향을 줍니다\
레플리카는 프라이머리의 복제 샤드이고, 복제된 샤드이기 때문에 검색 성능에 영향을 끼지는 샤드이고 만약 프라이머리에 문제가 생긴다면 프라이머리가 될 수도 있습니다\
\\

![img\_5.png](https://1004662897-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWIONvtnbdGZDNTxRR2%2Fuploads%2Fgit-blob-c9abb8eae26c8b498a0e9c4153c067b95ec60923%2Fimg_5.png?alt=media)

왜 나뉘어있을까?\
레플리카가 만들어지게 되면 프라이머리와 동일한 노드에 구성되는 것이 아닌 반드시 다른 노드에 구성되어 있습니다\
그것은 노드의 상태가 망가지는 케이스에는 노드 내부 인덱스에 나뉘어있는 샤드들이 전부 망가지는데 망가져도 데이터의 신뢰성을 위해 다른 노드에 저장하기 위해서입니다\
그래야 위에서 언급한 내용인 프라이머리에 문제가 생기면 레플리카에서 프라이머리로 승격하는 것이 가능합니다(승격하면서 새로운 레플리카를 생성합니다)\
추가로 ES에서는 아무리 작은 클러스터 구조여도 최소 3개의 노드를 구성할 것을 권장하고 있습니다\
\\

샤드의 갯수 설정은 인덱스를 생성하는 시점에 지정합니다\
인덱스를 생성할 떄 > settings 항목에 number\_of\_shards, number\_of\_replicas 두 항목을 통해서 설정할 수 있습니다\
인덱스 생성 시, 샤드의 갯수를 지정하는 과정에서 가장 중요한 항목은 > **프라이머리 샤드의 갯수는 인덱스를 처음 생성하는 시점에만 지정할 수 있다는 것**입니다\
기본 값으로는 number\_of\_shards 가 1인데, 1 그대로 사용하게 되면 성능 상 문제가 될 수 있다고 하는데 예시 및 실습이 좀 필요할 듯합니다\
+일일이 인덱스 생성할 때마다 이것을 조절하는 것은 어려울 것으로 보이니 인덱스 템플릿으로 공통화해서 작업하는 것도 가능\
number\_of\_shards 는 프라이머리 샤드의 갯수\
number\_of\_replicas 는 복제 샤드의 갯수\
그럼 복제 샤드는 프라이머리 샤드 하나 당 나오는 구조이기 때문에 총 샤드의 갯수는 number\_of\_shards \* number\_of\_replicas 로 볼 수 있습니다\\

정리해서 보면\
레플리카가 많은 경우에는 데이터 색인 시 > 많은 레플리카에 데이터나 나뉘어져서 들어가야 하기 떄문에 색인 성능은 떨어지고 검색 성능이 빨라진다고 볼 수 있습니다\
레플리카의 수가 부족한 경우에는 색인 시 > 색인을 나누어서 저장해야하는 데이터의 양이 없기 떄문에 색인 성능은 빠르지만 검색 성능이 떨어진다고 볼 수 있습니다\
따라서 샤드의 수를 지정하는데 있어서 색인/검색 성능 중에서 어떤 것에 중점을 두느냐가 숫자를 어떻게 구성할 것인지에 지표가 될 것이라고 생각합니다\
\\

성능을 확인하는데 있어서 이렇게 샤드의 수를 고민하고, 노드의 분산이 기능별로 잘 나뉘어 있는지, 각 데이터 노드들에 데이터가 잘 분산되어 저장되어 있는지에 대해서 확인하는 것이 중요하다고 생각합니다\\

\
\\

결과적으로 지금까지 확인한 사항을 보고 위에 raw하게 그린 항목에 내용을 집어넣어 ES의 총괄적 구조를 보면\
이렇게 볼 수 있습니다\
![img.png](https://1004662897-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWIONvtnbdGZDNTxRR2%2Fuploads%2Fgit-blob-670ab26fc6a077d47dedf5fb198cf28b83577141%2Fimg.png?alt=media)\\

\
\\

## ES의 데이터 처리

인덱스는 모든 데이터 관련 정보들의 기본 단위가 됩니다\
인덱스가 각 샤드로 나뉘어지면서 여러 노드에 저장이 되는데, 각각의 인덱스별로 데이터의 저장 및 검색 방법에 대해서 고려하게 되어 있습니다\
크게 인덱스의 설정과정, 매핑과정으로 나누어서 볼 수 있습니다\
\\

### 인덱스의 설정(\_setting)

인덱스의 설정 같은 경우에는 위에서 잠깐 언급되었던 해당 인덱스를 샤드에 배치하는 과정에서 샤드의 설정을 하는 number\_of\_shards, number\_of\_replicas 가 가장 대표적인 설정입니다\
설정하는 예시를 보면 요런 방식으로 설정합니다\\

```
PUT my_index
{
  "settings": {
    "index": {
      "number_of_shards": 3,
      "number_of_replicas": 1
    }
  }
}
```

\
위와 같이 설정하게 되면 프라이머리 샤드의 숫자는 3개, 레플리카는 각각 프라이머리 샤드의 추가적인 1개로써 3개가 됨으로\
number\_of\_shards + (number\_of\_shards \* number\_of\_replicas)\
총 3 + (3 \* 1) = 6 개의 샤드가 구성된다고 볼 수 있습니다\\

\
이외에도 아래와 같은 설정들이 존재합니다

* refresh\_interval : 세그먼트(샤드에 다수의 세그먼트로 나뉘어져있음 - 검색하는데 사용)가 만들어지는 리프레시 타임(defaut 1), replica 설정 수와 동일하게 동적으로 설정하는 것이 가능(떠 있는 상태에서 설정 가능)
* analyzer : 색인 받은 문장을 분석하는 작업 주로 진행할 기능을 가진 부분
* tokenizer : 데이터 색인 과정에서 검색 기능에 가장 많은 영향을 미치는 부분(반드시 하나만 사용)
* filter : 문장을 단어로 쪼개고 나서 쪼갠 단어들을 처리하는 과정에서 해당 파트에서 지정한 규칙을 기준으로 처리

\
\
인덱스별로 가장 많이 보이는 기능들은 위와 같고, 각각의 커스터마이징을 통해서 지정하는 것이 가능하기 때문에 필요할 떄 확인 및 사용이 필요합니다\
공식 페이지를 보고 참고하면 좋을 것 같습니다\
<https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-update-settings.html\\>
\\

### 매핑(\_mapping)

매핑이라는 단어는 위에서 RDBMS 와 비교 할떄 잠깐 보였는데 ES에서의 mapping = RDBMS에서의 schema 라고 볼 수 있습니다\
매핑에는 크게 2가지 방식이 있습니다 > 동적 매핑, 정적 매핑\\

* 동적 매핑은 처음 색인되는 문서를 바탕으로 매핑정보를 ES가 동적으로 알아서 매핑
* 정적 매핑은 RDBMS 에서 진행했던 방식처럼 데이터에 대한 타입을 미리 지정해주고 해당 타입만 색인될 수 있도록 제한하는 방식

\
각각의 특성을 사용해서 특정 값으로 지정해서 사용해야 하는 항목에는 제한시키고, 나머지는 유동적으로 알아서 처리될 수 있도록 중복되서 사용하는 것도 좋은 방법으로 보입니다\
문서 내에서 필드 타입을 하나를 지정하는 순간 나머지 필드들도 함께 지정해야 한다는 점 > 없으면 지정된 필드만 매핑되어 들어가는 것으로 보입니다\
\
\\

ES에서 제공하는 데이터 타입은 다음과 같습니다

* 문자열 - text, keyword
  * text : 해당 타입 같은 경우에는 해당 타입으로 넣어둔 문자열이 **각각의 단어를 단위로 각각 이 토큰화**되는 방식입니다 > 토큰화 되는 것은 /\_analyze 을 통해서 토큰화되는 내용 확인 가능
  * keyword : 해당 타입 같은 경우에는 해당 타입으로 넣어둔 문자열이 문자열 **전체가 그대로 토큰화**되는 방식입니다 > keyword보다 빠른 속도를 보장
* 숫자 - long, integer, short, byte, double, float, half\_float, scaled\_float
* 날짜 - date
* 불린 - boolean
* 객체 - Object / Nested
  * Object 같은 경우에는 객체 단위로 document 으로 인식
  * Nested 같은 경우에는 객체 내에 다양한 객체가 존재한다고 했을 때 해당 객체들을 상위 객체와 별도로 document 으로 인식해서 색인구조를 가질 수 있음
* 위치 정보 - Geo
* 기타 필드 - IP, Rang, Binary

\
인덱스 설정과 해당 인덱스의 구성은 필요에 따라서 작업하면 좋을 것으로 보입니다\
\
\\

### 삽질기록

document ID..\
개발계에서 id를 long 타입으로 잡아두고 >> 아이디를 자동생성해주는 작업을 안하고 그냥 계속해서 null로 해서 넣어주고 있었는데\
elasticsearch 에서 @Id로 잡아둔 부분의 데이터가 들어오지 않는다면 자동으로 아이디를 할당해준다고 합니다\
x`x`

#### 세미나 이후 개념 관련해서 다시 확인해봐야할 사항

elasticsearch 를 가장 상단에서 확인해보면 클러스터 구조로 구성이 되어 있는데, 클러스터의 구조, 그 내부의 구성내용에 대해서 조금 더 deep 하게 볼 필요가 있을 것 같습니다\
클러스터 구조는 어떻게 이루어져있는건지\
노드들은 어떻게 나뉘어져 있는지\
노드의 분할은 어떻게 진행하는지 샤드만큼 노드가 분리되어있지 않는 경우에는 어떻게 되는지\
코드 단에서 @Document 으로 잡아둔 객체로부터 처음으로 인덱스 구조를 먼저 잡고나서 이후에 객체가 변경되는 경우에는 인덱스가 어떻게되는지\
이미 만들어둔 인덱스에서 타입을 변경하는 케이스에는 이미 저장되어있는 데이터가 어떻게 되는지\
인덱스 - 객체 사이읭 데이터 타입 매핑 대한 고민\
색인이라는 단어, 역인덱스라는 단어 >> 이러한 개념에 대한 다시 공부\\

\
\\

#### 피드백에 대한 리서치 내용

**Elasticsearch 의 구조**

<https://www.elastic.co/guide/en/elasticsearch/reference/current/documents-indices.html\\>
클러스터 구조로 보았을 때 다수의 노드들이 있다면, document 가 저장될 때 클러스터 전반에 걸쳐서 저장되게 되고, 어느 노드에서든 해당 문서를 확인하는 것이 가능합니다\
Elasticsearch 는 역인덱스라고 불리우는 데이터 구조를 가지고 있습니다\
토크나이징을 통해서 받은 데이터를 쪼개고 그 쪼갠 단어와 그 단어가 어떤 document 에서 나왔는지를 저장하는 구조입니다\
아래의 사진을 기준으로 보시면 좋습니다\
![img\_2.png](https://1004662897-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWIONvtnbdGZDNTxRR2%2Fuploads%2Fgit-blob-43acddee6d355c1d84e984335ff8be1fd2dc5409%2Fimg_2.png?alt=media)\\

<https://www.elastic.co/guide/en/elasticsearch/reference/current/scalability.html\\>
Elasticsearch 공식문서에서는 Elasticsearch 가 무엇인가? 에 대한 설명을 하는데 하나의 특징으로 확장성(Scalability), 회복성(resilience) 을 꼽고 있습니다\
ES 는 항상 필요에 의해서 크기를 조절할 수 있도록 가용성을 가지고 있으며 서버, 즉 노드를 추가함으로써 **자동으로** 데이터를 동일하게 분산시키고 가능한 노드에서 조회할 수 있도록 처리합니다\
애플리케이션 단에서 직접 하나하나 까보면서 정비할 필요 없이, ES는 공간을 제공하고 높은 가용성을 제공하기 위해 멀티노드로 구성된 클러스터 구조에서 밸런싱을 조절하는 방법을 알고 있습니다\
다다익선 > 노드가 많으면 많을수록 좋다\\

\
밸런싱을 어떻게 하는걸까? > 결국 ES의 구조로 이어지게 되는데, 우선 ES의 인덱스는 논리적으로 샤드를 그룹핑하기 위해서 존재하는 개념이고 사실 각각의 샤드에는 인덱스(논리적으로 틀)를 가지고 있습니다\
document 을 각각의 샤드에 동일하게 저장하는 과정에서 ES 에서는 다중화를 보장합니다 - 하드웨어 이슈(노드다운)에도 문제 없이 동일한 값을 전달할 수 있도록 해주고, 노드가 추가되어도 어느 노드든 동일한 조회결과를 줄 것입니다\
이렇게 클러스터가 커지거나, 줄어들게 되면 ES는 샤드의 재배치를 통해서 클러스터를 변화에 맞게 다시 밸런싱해줍니다\
\\

다시 ES의 구성을 물리적 저장공간으로 가장 안쪽부터 보면,\
document 는 각각의 인덱스 틀에 맞춰져서 각각의 샤드에 분산되어 동일하게 되고\
그렇게 분산된 샤드들이 다수의 노드들에 분산되어 저장되어 있습니다\
그리고 이렇게 다수의 노드들이 얽혀있는 구조를 보고 클러스터 구조로 되어있다고 정의하는 것이라고 보면 좋을 것 같습니다\
\\

이러한 구조가 ES으로 하여금 하드웨어적 이슈를 해결하거나 쿼리의 기능을 발전시킨다는 점이였습니다\\

* 샤드의 수를 늘리면 > 모든 샤드에 document 가 들어가야 하니 시간이 더 오래걸립니다
* 샤드의 사이즈가 크면 > 클러스터를 다시 밸런싱하는 시간 이 오래 걸립니다

\
추가로 샤드의 사이즈는 최대한 수 GB 에서 수십 GB 사이를 유지할 수 있도록 목표를 세워야 한다고 합니다\
운영 구조에서는 ES 클러스터들을 모니터링하고 제어하는 것이 아주 중요한데 이것을 키바나를 통해서 확인하고 관리하면 좋다고 합니다\
\\

<https://www.elastic.co/guide/en/elasticsearch/reference/current/cluster.html\\>
샤드의 분할은 cluster.routing 설정값을 통해서 가중치에 대한 설정을 진행하는 것이 가능합니다\\

```http
PUT localhost:9200/_cluster/settings
{
   "transient": {
     ~~~
   }
}
```

\
\\

추가로 샤드의 배치에 대한 내용입니다\
<https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-cluster.html\\>
클러스터의 균형이 잡혀있다고 하는 정의는 각각의 노드에 배치된 샤드의 갯수가 동일하고, 각각의 노드들이 동일한 자원을 잡아먹는다고 가정했을 때를 의미합니다\
ES는 자동으로 rebalancing 을 통해서 노드간에 샤드를 배치시켜 균형을 맞춥니다\
여기서 잡는 기준은 기본적으로 데이터 노드 같은 경우에는 데이터 노드의 티어(<https://www.elastic.co/guide/en/elasticsearch/reference/current/data-tiers.html)에> 따라서 ES 가 자동으로 해당 티어에 맞는 밸런싱을 진행하지만 config 을 통해서 따로 설정하는 것도 가능합니다\\

![img\_8.png](https://1004662897-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWIONvtnbdGZDNTxRR2%2Fuploads%2Fgit-blob-a6cd12c3647d711a748f9079cecf8c32900d67df%2Fimg_8.png?alt=media)

\
만약 노드가 1개이고, primary가 1개, replica가 5개 이렇게 있는 상황에서\
primary 같은 경우에는 반드시 노드에 존재해야 하고, replica 같은 경우에는 반드시 다른 노드에 존재해야 하는데 primary 가 있는 노드 외에 노드가 없는 경우에 이렇게 unassigned 상태로 표기되고 결국은 replica의 업무를 다하지 못하고 있게 됩니다\\

\
\\

<https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-node.html\\>
노드의 종류는 다양하게 존재하고 있습니다\
기본적으로는 모든 기능을 수행하는 것이 가능하지만 ES의 설정을 하는데 있어서 yml 로 세팅하는 환경에서 node.roles 을 통해서 노드들을 list 형식으로 각각의 역할을 부여하는 것이 가능합니다\
\
\
\\

질문\
엘라스틱에서 노드가 클러스터구조로 되어있는지 설정으로 할 수 있는가\
<https://esbook.kimjmin.net/03-cluster> > 항상 클러스터를 기본으로 동작\
\\

인덱스를 처음에 설정했을 때 프라이머리와 레플리카의 갯수가 어떻게 구성되는지\
<https://esbook.kimjmin.net/03-cluster/3.2-index-and-shards> > 단 하나만 들어감\\

노드에 프라이머리와 레플리카가 같이 들어갈 수 있는지\
<https://esbook.kimjmin.net/03-cluster/3.2-index-and-shards> > 반드시 서로 다른 노드에 저장이 됩니다.\\

\
프라이머리와 레플리카를 샤드에 배치하는걸 알아서 할 수 있는지 > 사용할 수 있는 샤드들은 자동으로 사용이 가능한 데이터 노드들으로 분산되어 들어가게 되어있다\\

<img src="https://1004662897-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MWIONvtnbdGZDNTxRR2%2Fuploads%2F8LDVU0mg8eb10U9ELXHr%2Fimage.png?alt=media&#x26;token=e68d086d-b35a-4363-85ed-bcbfccf1287d" alt="" data-size="line">\
`GET http://localhost:9200/_cat/indices?v`

인덱스를 처음 만들었을 때 프라이머리 샤드의 갯수는 default 으로 1\
인덱스를 처음 만들었을 때 레플리카 샤드의 갯수는 default 으로 1\\

참고\
<https://www.elastic.co/guide/en/elasticsearch/reference/current/high-availability-cluster-small-clusters.html>

**동적 매핑에 대한 고민**

<https://www.elastic.co/guide/en/elasticsearch/reference/current/dynamic-mapping.html\\\\>

이미 생성된 movie 라는 인덱스에 text 타입을 가진 title 이 있다고 가정하고, document 을 넣는다고 가정해 보았을 떄\\

전에 고려사항으로 나왔던 항목들을 확인해보면\
이미 만들어진 인덱스에 같은 이름으로 지정하지 않은 타입을 넣어주면 > **들어갑니다**\
title 에 double 값을 넣고 document 을 넣으려고 하면 저장됩니다\
\\

이미 만들어진 인덱스에 기존에 선언하지 않은 필드를 추가해서 데이터를 넣으려고 하면 elasticsearch 의 특성 대로 > **들어갑니다**\
여기서 중요한건, Elasticsearch 에서 이미 매핑이 등록되어 있는 인덱스에 새로운 필드를 추가해서 다시 인덱스의 매핑을 설정해주게 되면\
ES 내부의 프로세스는 새로운 매핑을 기준으로 인덱스를 새로 만들고, 기존의 인덱스로 들어가 있는 document 들을 새로운 인덱스에 복사하는 과정을 거치게 됩니다\
즉 프로퍼티를 추가로 생성하게 되면, 데이터의 재색인이 일어난다는 것입니다\\

인덱스 는 document 의 논리적인 그룹이며 ES의 특\`성 상 유연한 데이터 구조를 가지기 때문에 문제 없이 들어가게 됩니다\
어떻게 보면 장점이기도하고 단점이기도 한 점이라고 보이는데\
전 데이터를 관리하는데 있어서 데이터의 틀을 맞추어야 예상하지 못한 데이터에 보복당하지 않을 것이라고 생각하기 때문에\
저희가 RDBMS 에서 테이블을 관리하는 것처럼 맞지 않는 타입을 가진 document 나 알 수 없는 새로운 필드를 가진 document 가 들어왔을 때 document가 저장되지 못하도록 막고 싶었습니다\
그 방법이 바로 dynamic 설정입니다\\

\
이전에 말씀드렸던 ddl-auto 설정과 비슷하다고 생각하면 됩니다\
설정 값은 아래와 같습니다\
\- true : default 값으로 매핑에 신경쓰지 않고 유연하게 대응하겠다는 의미 - runtime : runtime field로 매핑해주겠다는 의미로, 평소에는 유연하게 대응하지만 조회할 때만 확인하겠다는 의미 - false : 인덱스에 설정된 케이스 이외의 타입이나 필드가 확인되면 무시하겠다는 의미 - strict : 인덱스에 설정된 케이스 이외의 타입이나 필드가 확인되면 ES에서 에러를 전달하겠다는 의미

dynamic 설정 값은 index의 매핑을 설정하는 과정에서 설정하는 것이 가능합니다\
인덱스에 지정하지 않은 필드가 들어오는 케이스를 방어하기 위해서는 인덱스의 상위 json에 설정하는 것이 가능하고\
각각의 필드에 처음에 설정하지 않은 데이터 타입이 들어오는 케이스를 방어하기 위해서는 porperties 설정하는 json 부분에서 설정하는 것이 가능합니다\
추가로 인덱스의 알 수 없는 필드를 dynamic 설정을 통해서 제한하는 설정은 인덱스가 생성되고 나서 설정하는 것이 가능하지만,\
필드에 맞지 않은 데이터 타입으로해서 전달받을 때 dynamic 값을 설정하는 것은 인덱스가 생성되고 나서는 불가능합니다 하여 처음에 설정해야 합니다\\

\\

default 으로는 true 으로 설정되어 있으며 false 같은 경우에는 새로운 필드를 무시하고 strict 같은 경우에는 새로운 필드가 들어오게 되면 에러를 발생시킵니다\\

springboot 코드 단에서도 가능한데요, @Field 애노테이션에서 ignoreMalformed 이라는 boolean 옵션 값이 있습니다 이걸 사용해서 이상한 타입이 들어오면 무시하는 방법도 있습니다\\

\
\\

결론적으로는 elasticsearch 에서 인덱스의 매핑을 설정하는데 있어서 dynamic 을 strict 으로 해서 의도치 않은 새로운 필드가 추가되어서 모든 document가 다시 색인되는 것에 대해서 방지할 필요가 있을 것으로 보입니다\
추가적으로 객체 단에서 필드가 변경되는 사항에 대해서 방어할 수 있는 방법으로는 자바 단에서 objectmapper 등을 통해서 코드단에서 매핑을 체크해주는 작업해주는 방법이 있다고 생각했습니다\
추가로 그냥 신규로 넣고 싶은 경우에는 PUT /\_mapping 을 통해서 넣고 싶은 **새로운 필드만** 전달해주면 기존의 필드들에 새로운 필드가 정상적으로 추가됩니다\
\
\\

\
\
\
\
\
\
\
\
\
\\
