본문 바로가기
데이터 엔지니어( 실습 정리 )/elasticsearch

6. 클러스터 운영 (1, 2, 3)

by 세용용용용 2025. 1. 8.

[ 엘라스틱 서치 바이블 ] 공부한 후 정리한 내용 입니다!!!

 

 

1. 클러스터 설정 API

  • 엘라스틱서치 운영중 클러스터 설정을 동적으로 변경해야 할 떄 사용
### 클러스터 관련 설정정보 조회
curl -XGET "http:/192.168.219.20:9200/_cluster/settings?pretty"

### 클러스터 관련 설정정보 지정
** persistent : 클러스터 풀 리스타트 해도 유지
** transient : 클러스터 재시작시 내용 사라짐
** persistent, transient 동일 설정 지정시 transient 우선 적용
curl -XPUT "http://192.168.219.20:9200/_cluster/settings?pretty" -H "Content-Type: application/json" -d \
'{
  "persistent": {
    "indices.breaker.total.limit": "70%"
  },
  "transient": {
    "cluster.routing.allocation.enable": "primaries",
    "indices.breaker.total.limit": "90%"
  }
}'

### 클러스터 관련 설정 제거시 해당 값 null로 지정
curl -XPUT "http://192.168.219.20:9200/_cluster/settings?pretty" -H "Content-Type: application/json" -d \
'{
  "transient": {
    "cluster.routing.allocation.enable": null
  }
}'

 

 

 

2. cat API를 통한 클러스터 관리, 모니터링

  • cat API는 클러스터 현재 상태를 조회할수 있는 api
### cat API
### -v 옵션을 추가로 넣으면 응답에 컬럼명 출력
1. curl -XGET "http://192.168.219.20:9200/_cat/health"
- 클러스터 전반적인 상태 체크
- green : 모든 샤드 할당 굿
- yello : 적어도 모든 주샤드는 할당된 상태
- red : 할당되지 못한 주샤드 존재 상태

2. curl -XGET "http://192.168.219.20:9200/_cat/indices"
- 인덱스 종류와 상태

3. curl -XGET "http://192.168.219.20:9200/_cat/nodes"
- 각 노드 상태 조회
- 노드 역할, 힙 사용량, 평균 부화 상태 확인

4. curl -XGET "http://192.168.219.20:9200/_cat/shards"
- 샤드에 문서 갯수, 노드 배치 정보, 크기 확인 가능

5. curl -XGET "http://192.168.219.20:9200/_cat/segments"
- 루씬 세그먼트 상태 조회

6. curl -XGET "http://192.168.219.20:9200/_cat/recovery"
- 샤드 복구 진행율

7. curl -XGET "http://192.168.219.20:9200/_cat/allocation"
- 각 노드 디스크 사용량, 노드별 샤드 할당과 관련 정보

8. curl -XGET "http://192.168.219.20:9200/_cat/thread_pool"
- 각 노드 스레드 풀 상태 조회

9. curl -XGET "http://192.168.219.20:9200/_cat/master"
- 마스터 선출 노드 확인

 

 

3. 인덱스 운영 전략

  • 인덱스 설계시 이후 발생할 수 있는 운영 이슈 고려해 설계

 

(3-1) 템플릿, 명시적 매핑 활용

  • 최대한 명시적 매핑을 지정하고, 사전에 지정 못한 신규 필드 추가 예상시 템플릿, 동적 템플릿 최대한 활용

 

(3-2) 라우팅 활용

  • 데이터 요건을 파악하여 어떤 값으로 라우팅 지정시 효율적일지 설계
  • 라우팅 지정시 해당 인덱스 색인하는 모든 클라이언트도 라우팅 정책 내용을 숙지 ( 인덱스 매핑시 _routing = true 을 통해 라우팅 필수 지정 )

 

(3-3) 시계열 인덱스 이름

  • 인덱스 이름에 시간을 넣어 관리를 편하게 가능 ( 인덱스 명 : sy_log_20250108 )

 

(3-4) alias

  • 인덱스 명을 다른 이름으로도 가리키도록 하는 기능
  • alias로 하나 이상의 인덱스 지정 가능 ( 두개 이상 인덱스 대상 조회시 is_write_index 지정한 인덱스만 쓰기 작업 가능 )
  • es 운영중 인덱스 변화가 생기면 alias가 가리키는 인덱스만 변경해 운영 중 새로운 인덱스로 스무스하게 넘어가는 방법
### alias 지정 테스트
curl -XPOST "https://192.168.56.10:9200/_aliases" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k \
-H "Content-Type: application/json" -d \
'{
  "actions": [
    {
	  "add": {
	    "index": "kibana_sample_data_logs",
		"alias": "kibana_sample_data"
	  }
	},
	{
	  "add": {
	    "index": "kibana_sample_data_flights",
		"alias": "kibana_sample_data",
		"is_write_index": true
	  }
	}
  ]
}'
>>> kibana_sample_data_flights 해당 인덱스는 alias를 사용하여 쓰기 가능


### alias 지정 해체
curl -XPOST "https://192.168.56.10:9200/_aliases" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k \
-H "Content-Type: application/json" -d \
'{
  "actions": [
    {
	  "remove": {
	    "index": "kibana_sample_data_flights",
		"alias": "kibana_sample_data"
	  }
	}
  ]
}'
>>> remove를 사용하여 alias 지정 해제 가능

 

 

(3-5) 롤 오버

  • 인덱스 관리를 자동화하는 기능, 특정 조건을 만족하는 경우 새로운 인덱스를 생성하고 기존 인덱스는 보관하여 데이터의 관리를 용이
  • alias 대상 롤 오버는 쓰기 담당 인덱스 샤드가 커지면 새 인덱스 생성하고 alias로 묶고 is_write_true를 새 인덱스로 옮기는 작업을 자동화 가능
### alias를 대상으로 하는 롤 오버 테스트

1) 롤 오버 테스트용 인덱스 생성
- 롤오버 수행시 is_write_index 명은 반드시 [~~~ - 숫자 패턴]

curl -XPUT "https://192.168.56.10:9200/%3Ckibana_sample_data_flights-%7Bnow%2Fd%7D-000001%3E" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k \
-H "Content-Type: application/json" -d \
'{
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 1
  }
}'


2) reindex 를 사용하여 데이터 복사
curl -XPOST "https://192.168.56.10:9200/_reindex" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k \
-H "Content-Type: application/json" -d \
'{
  "source": {
    "index": "kibana_sample_data_flights"
  },
  "dest": {
    "index": "kibana_sample_data_flights-2025.01.09-000001"
  }
}'


3) alias 기존 인덱스 삭제 및 새로운 인덱스 추가
curl -X POST "https://192.168.56.10:9200/_aliases" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k \
-H "Content-Type: application/json" -d \
'{
  "actions": [
    {
	  "remove": {
	    "index": "kibana_sample_data_flights",
		"alias": "kibana_sample_data"
	  }
	},
    {
      "add": {
        "index": "kibana_sample_data_flights-2025.01.09-000001",
        "alias": "kibana_sample_data",
		"is_write_index": true
      }
    }
  ]
}'


4) alias 대상 롤 오버 생성
curl -XPOST "https://192.168.56.10:9200/kibana_sample_data/_rollover" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k
>>> 인덱스 명 지정 가능 [롤 오버 대상 alias]/_rollover/[생성할 새 인덱스명]
** 하지만 인덱스명 지정시 동일한 인덱스명으로 두번 실행하면 겹쳐서 오류가 뜸


5) alias 롤 오버 상태 확인
curl -X GET "https://192.168.56.10:9200/_alias/kibana_sample_data?pretty" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k

 

 

 

(3-6) 데이터 스트림

  • 내부적으로 여러 인덱스로 구성되어 있음
  • 데이터 스트림 모든 인덱스 대상 검색을 수행 하며, 색인은 가장 최근 생성된 단일 인덱스에 색인
  • 롤 오버 사용시 최근 생성된 인덱스 숫자 하나를 올린 새로운 인덱스 생성 ( 여러 인덱스 묶고 is_write_true 인덱스 하나를 둔 형태 )
  • 데이터 스트림은 롤 오버 생성시 명시적 인덱스 지정 불가, 인덱스 템플릿과 연계헤 생성, @timestamp 필드가 포함된 문서만 취급
  • 데이터 스트림은 문서 추가만 가능!! ( 삭제나 업데이트 시 update_by_query, delete_by_query 사용 )
### 데이터 스트림 테스트

1) 인덱스 생명주기 관리 정책 생성
curl -XPUT "https://192.168.56.10:9200/_ilm/policy/test-ilm-policy?pretty" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k \
-H "Content-Type: application/json" -d \
'{
  "policy": {
    "phases": {
	  "hot": {
	    "min_age": "0ms",
		"actions": {
		  "rollover": {
		    "max_primary_shard_size": "4gb",
			"max_age": "5m"
		  }
		}
	  },
	  "delete": {
	    "min_age": "3d",
		"actions": {
		  "delete": { }
		}
	  }
	}
  }
}'
>>> 4기가 or 5분 지났을시 새인덱스 생성
>>> 3일 지난 인덱스 삭제
>>> 인덱스 생명주기 관리 정책 조회 : curl -XGET "https://192.168.56.10:9200/_ilm/policy/test-ilm-policy?pretty" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k


2) 인덱스 템플릿 생성 ( 데이터 스트림은 인덱스 템플릿과 연계 해야함 )

- 맵핑 컴포넌트
curl -XPUT "https://192.168.56.10:9200/_component_template/test-mappings?pretty" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k \
-H "Content-Type: application/json" -d \
'{
  "template": {
    "mappings": {
	  "properties": {
	    "@timestamp": {"type": "date"}
	  }
	}
  }
}'

- settings 컴포넌트
curl -XPUT "https://192.168.56.10:9200/_component_template/test-settings?pretty" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k \
-H "Content-Type: application/json" -d \
'{
  "template": {
    "settings": {
	  "index.lifecycle.name": "test-ilm-policy",
	  "number_of_shards": "2",
	  "number_of_replicas": "1"
	}
  }
}'
>>> index.lifecycle.name 으로 생성한 ILM 정책 명 지정


- 컴포넌트 템플릿을 사용하여 인덱스 템플릿 생성
curl -XPUT "https://192.168.56.10:9200/_index_template/test-data-stream-template?pretty" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k \
-H "Content-Type: application/json" -d \
'{
  "index_patterns": ["my-data-stream-*"],
  "data_stream": {},
  "composed_of": ["test-mappings","test-settings"]
}'
>>> data_stream 필드 빈값으로 포함 시켜야 데이터 스트림 전용 템플릿 생성됨
>>> index_patterns는 지정한 데이터 스트림 명을 지정 ( 와일드 카드 가능 )
>>> 인덱스 템플릿 조회 : curl -XGET "https://192.168.56.10:9200/_index_template/test-data-stream-template?pretty" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k


3) 데이터 스트림 생성
curl -XPUT "https://192.168.56.10:9200/_data_stream/my-data-stream-first?pretty" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k


4) 데이터 스트림 문서 색인
curl -XPUT "https://192.168.56.10:9200/my-data-stream-first/_create/1?pretty" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k \
-H "Content-Type: application/json" -d \
'{
  "hello": "sy0218",
  "@timestamp": "2025-01-10T16:32:50"
}'
>>> 색인후 검색 : 데이터 스트림 검색 : curl -XGET "https://192.168.56.10:9200/my-data-stream-first/_search?pretty" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k


5) 데이터 스트림 삭제
curl -XDELETE "https://192.168.56.10:9200/_data_stream/my-data-stream-first?pretty" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k

 

 

(3-7) reindex

  • 원본문서 _source를 읽어 대상 인덱스로 색인 하는 기능
  • reindex source 인덱스는 인덱스 매핑에 _source 가 활성화 되있어야됨
### reindex 테스트
curl -XPOST "https://192.168.56.10:9200/_reindex?pretty" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k \
-H "Content-Type: application/json" -d \
'{
  "source": {"index": "sy_index"},
  "dest": {"index": "reindex_sy_index"},
  "conflicts": "abort"
}'
>>> 작업중 버전충돌 발생시 해당 부분 까지만 재색인 됨
>>> 충돌 무시하고 색인시 conflicts : proceed 로 지정하여 충돌 문서 건너뛸수 있음
>>> curl -XGET "https://192.168.56.10:9200/reindex_sy_index/_search?pretty" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k


### 검색 쿼리를 지정한 reindex
curl -XPOST "https://192.168.219.20:9200/_reindex?pretty" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k \
-H "Content-Type: application/json" -d \
'{
  "source": {
    "index": "kibana_sample_data_logs",
    "query": {
      "term": {
        "host.keyword": "artifacts.elastic.co"
      }
    }
  },
  "dest": {
    "index": "reindex_kibana_sample_data_logs"
  }
}'


### 스크립트 이용행 reindex
1) 테스트 문서 색인
curl -XPUT "https://192.168.219.20:9200/source_index/_doc/1?pretty" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k \
-H "Content-Type: application/json" -d \
'{
  "field_one": "flash",
  "field_two": 1003,
  "field_three": "wonderland"
}'

2) 스크립트 이용한 reindex
curl -XPOST "https://192.168.219.20:9200/_reindex?pretty" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k \
-H "Content-Type: application/json" -d \
'{
  "source": {
    "index": "source_index"
  },
  "dest": {
    "index": "dest_index"
  },
  "script": {
    "lang": "painless",
    "source": "ctx._source.field_one = \"test\"; ctx._source.field_two--; ctx._source.field_three = ctx._source.field_two;"
  }
}'


3) dest 인덱스 확인
curl -XGET "https://192.168.219.20:9200/dest_index/_search?pretty" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k
>>>
"_source" : {
          "field_three" : 1002,
          "field_two" : 1002,
          "field_one" : "test"
        }

 

비동기 실행과 스로틀링, 슬라이싱

  • reindex 작업도 wait_For_completion=false를 지정해 작업을 비동기적 실행 가능
  • 스로틀링, 슬라이싱도 적용 가능하여 유연하게 작업을 처리할수 있다

 

(3-8) shrink로 샤드 갯수 줄이기

  • 샤드 개수를 줄이며 인덱스 새로 생성하는 작업
  • 원본 인덱스 명 +  생성할 인덱스 명 + 샤드 갯수 지정
### shrink 테스트
curl -XPUT "https://192.168.56.10:9200/[ 인덱스 명 ]/_shrink/[ 새로 생성할 인덱스 명 ]?pretty" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k \
-H "Content-Type: application/json" -d \
'{
  "settings": {
    "index.number_of_replicas": 2,
    "index.number_of_shards": 1
  }
}'

reindex, shrink 차이점

목적 데이터를 복사 및 변환 샤드 개수를 줄여 클러스터 최적화
동작 방식 새 인덱스를 생성하고 데이터를 복사 기존 데이터를 병합하여 새로운 인덱스 생성
데이터 수정 가능 여부 원본 데이터 읽기/쓰기 가능 병합된 인덱스는 읽기 전용
인덱스 읽기/쓰기 원본 데이터 읽기/쓰기 가능 병합된 인덱스는 읽기 전용
필요 조건 별도 조건 없음 인덱스는 read-only 상태여야 함

 

 

(3-9) split로 샤드 개수 늘리기

  • 샤드 갯수 늘리며 인덱스를 생성하는 작업
  • 원본 인덱스 명 + 생성할 인덱스 명 + 샤드 갯수 지정
source_index
### split 테스트
curl -XPUT "https://192.168.219.20:9200/source_index/_split/split_index?pretty" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k \
-H "Content-Type: application/json" -d \
'{
  "settings": {
    "index.number_of_shards": 4
  }
}'

 

 

(3-10) 다중 필드

  • 필드 타입을 여러 타입을 적용하고자 할떄 사용
  • 아래와 같이 적용시 my_string_field : keyword 타입, my_string_field.text_standard : text 타입 ( standard 애널라이저 )
  • 인덱스 한번 지정한 매핑은 변경 불가하지만 추가는 가능하기에 운영 도중 다중 필드 추가 가능!!
### 다중 필드 테스트 ( multi-fields-test )
1) 단일 필드 생성
curl -XPUT "https://192.168.219.20:9200/multi-fields-test?pretty" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k \
-H "Content-Type: application/json" -d \
'{
  "mappings": {
    "properties": {
      "my_string_field": {
        "type": "keyword"
      }
    }
  }
}'

2) 다중 필드 적용
curl -XPUT "https://192.168.219.20:9200/multi-fields-test/_mapping?pretty" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k \
-H "Content-Type: application/json" -d \
'{
  "properties": {
    "my_string_field": {
      "type": "keyword",
      "fields": {
        "text_standard": {
          "type": "text",
          "analyzer": "standard"
        },
        "text_whitespace": {
          "type": "text",
          "analyzer": "whitespace"
        }
      }
    }
  }
}'

3) 메핑 확인
curl -XGET "https://192.168.219.20:9200/multi-fields-test/_mapping?pretty" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k
>>>
"my_string_field" : {
          "type" : "keyword",
          "fields" : {
            "text_standard" : {
              "type" : "text",
              "analyzer" : "standard"
            },
            "text_whitespace" : {
              "type" : "text",
              "analyzer" : "whitespace"
            }
          }
        }

 

 

(3-11) 타입이 계속 변경 되는 데이터

  • 서비스 상 타입이 계속 변하는 필드는 매핑 타입을 object로 지정후 endabled: false를 지정하는 방법을 사용
  • 타입 충돌은 발생하지 않지만 해당 필드에 대한 검색은 포기 해야됨

 

(3-12) 루씬 컴 길이 제약

  • string 필드는 길이가 긴 데이터가 들어오면 루씬 텀 길이 제약에 걸려 문서 색인이 거부됨 ( 루씬 최대 텀 : 32766 바이트 )
  • 매핑시 ignore_above를 지정해 수치보다 긴 텀을 역색인에 넣지 않게하는 속성
### 텀 길이 제약 테스트
"mappings": {
  "properties": {
    "my_string_field": {
      "type": "keyword",
      "ignore_above": 1000
    }
  }
}

 

 

(3-13) 대량 색인 필요시

  • 대량 색인 도중 데이터 조회를 하지 않을시 refresh를 끄고 + 복제본 샤드 개수를 0으로 지정
  • 작업 이후 원래 설정으로 복구해야됨
### 대량 색인시 settings 지정 테스트
curl -XPUT "https://192.168.219.20:9200/my_index?pretty" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k \
-H "Content-Type: application/json" -d \
'{
  "settings": {
    "refresh_interval": "-1",
    "number_of_replicas": 0
  }
}'

 

 

 

4. 샤드 운영 전략

  • 샤드 갯수는 변경 불가
  • 샤드 갯수가 많으면 : 성능이 저하됨, 샤드 하나당 루씬 인덱스가 뜨며 힙을 차지, 복제본 샤드로 늘어남
  • 샤드 갯수가 적으면 : 클러스터 안정성이 떨어짐, 샤드 복구, 복제본 샤드 생성에 오랜시간 소요, 재 기동시 샤드 복구 과정이 무거워 다시 죽을수도 있음

 

(4-1) 샤드 크기와 개수 조정

  • 샤드 크기를 기준 크기 이하로 유지하는 선에서, 전체 샤드 개수를 줄이는 방법으로 접근
  • 샤드 크기는 20~40GB가 적당하다 함 ( 현재 환경에 맞춰 조정 필요 )
  • 힙 1GB당 20개 이하 샤드가 적절하다고 함
### 샤드 크기 및 샤드 갯수 확인 _cat api
1) 샤드 크기 확인
curl -XGET "https://192.168.219.20:9200/_cat/shards?v&s=store:desc" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k

2) 샤드 갯수 확인
curl -XGET "https://192.168.219.20:9200/_cat/health?v" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k
curl -XGET "https://192.168.219.20:9200/_cat/allocation?v" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k

 

 

(4-2) 모든 노드가 충분히 일을 하고 있는지

  • 샤드가 모든 노드에 적절히 퍼져 있어야됨 ( 노드가 3대면 샤드로 3의 배수로 하는게 좋음 )

 

 

(4-3) 미래 데이터가 커질 것 고려

  • 인덱스 명에 시간을 넣어 정기적으로 인덱스를 생성하는 데이터인 경우 템플릿을 설정해 number_of_shards 값을 적절히 봐가며 변경하여 유연한 대처 가능
  • 단일 인덱스 일 경우 미리 넉넉히 설정해야 하지만 어쩔수 없는 경우 reindex 진행.. ( reindex 전 미리 alias를 설정 )

 

(4-4) 테스트 수행

  • 가장 확실한 방법은 실제 서비스 조건과 유사한 조건으로 테스트를 수행 해보고 해당 결과를 참고해 개수를 지정

 

 

5. 롤링 리스타트

  • 노드를 재기동 하기위해 수행
  • 롤링 리스타트 순서 : 샤드 할당 비활성화 >>> flush 수행 >>> 노드 재기동 >>> 샤드 할당 활성화 >>> green 상태

 

(5-1) 샤드 할당 비활성화

  • 롤링 리스타트 전 불필요한 샤드 할당을 막기 위해 사드를 비활성화
### 샤드 할당 비활성화
curl -XPUT "https://192.168.56.10:9200/_cluster/settings?pretty" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k \
-H "Content-Type: application/json" -d \
'{
  "transient": {
    "cluster.routing.allocation.enable": "primaries"
  }
}'
>>> 주 샤드만 할당하는 설정
>>> 변경 확인 : curl -XGET "https://192.168.56.10:9200/_cluster/settings?pretty" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k

all : 모든 종류 샤드 할당
primaries : 주 샤드만 할당
none : 모든 샤드 할당 불허

 

 

(5-2) flush 수행

  • flush를 수행해 translog를 비우고 데이터를 디스크에 안전하게 기록
### flush 수행
curl -XPOST "https://192.168.56.10:9200/_flush" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k

 

 

(5-3) 노드 재기동

  • 샤드 할당을 비 활성화 + flush 완료시 노드 재기동 
  • 로그를 확인해 해당 노드 기동 확인 ( [o.e.n.Node               ] [slave2] started )

 

(5-4) 샤드 할당 활성화

  • 노드 재기동 후 샤드 할당을 활성화
curl -XPUT "https://192.168.56.10:9200/_cluster/settings?pretty" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k \
-H "Content-Type: application/json" -d \
'{
  "transient": {
    "cluster.routing.allocation.enable": "all"
  }
}'

 

 

(5-5) green 상태 까지 대기

  • green 상태가 되면 다음 롤링 리스타트를 위해 샤드 할당 비활성화 후 해당 작업 반복
### 노드 재시작 후 green 상태 확인
curl -XGET "https://192.168.56.10:9200/_cat/health?v" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k

 

 

 

6. 스냅샷과 복구

  • 스냅샷 : 동작중인 엘라스틱서치 클러스터의 인덱스를 백업하는 방법

 

(6-1) 스냅샷 저장소 등록과 설정

  • 스냅샷을 찍으려면 저장소를 등록해야됨
  • 기본적으로 공유 파일 시스템 타입 지원, 이외 다른 저장소는 플러스인 설치가 필요

 

공유 파일 시스템 저장소

### 공유 파일 시스템 저장소 생성
curl -XPUT "https://192.168.219.20:9200/_snapshot/bk_up_test?pretty" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k \
-H "Content-Type: application/json" -d \
'{
  "type": "fs",
  "settings": {
    "location": "/my/nfs/mount/path"
  }
}'
>>> location애 경로를 입력하는데 해당 경로는 사전에 elasticsearch.yml에 path.repo 설정으로 등록해야됨
>>> 스냅샷 저장소 정보 확인 : curl -XGET "https://192.168.219.20:9200/_snapshot/bk_up_test?pretty" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k

 

 

HDFS 저장소

### hdfs 저장소 테스트
1) 엘라스틱서치 공식 플러그인 모든 노드 설치 ( 설치후 노드 재기동 )
bin/elasticsearch-plugin install repository-hdfs

2) 저장소 생성
curl -XPUT "https://192.168.219.20:9200/_snapshot/hdfs_backup?pretty" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k \
-H "Content-Type: application/json" -d \
'{
  "type": "hdfs",
  "settings": {
    "uri": "hdfs://myname" # hdfs 주소
    "path": "/path/to/repo/file" # hdfs 경로
    "conf": { # 하둡 설정을 넣을수 있음
      "dfs.nameservices": "myname"
    }
  }
}'

 

 

소스 전용 저장소

  • 최소 크기 스냅샷을 찍는 소스 전용 저장소
  • 데이터 필드와 인덱스 메타 데이터만 저장 ( 색인, doc_values 구조는 저장 안함 )
  • 인덱스 정보가 없기에 정상 사용을 위해서는 reindex 작업을 수행해 일반 인덱스로 만들어야됨
### 소스 전용 저장소 테스트

curl -XPUT "https://192.168.219.20:9200/_snapshot/source_backup?pretty" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k \
-H "Content-Type: application/json" -d \
'{
  "type": "source",
  "settings": {
    "delegate_type": "fs",
    "location": "/my/nfs/mount/path"
  }
}'

 

 

저장소 분리

  • 엘라스틱서치 스냅샷은 증분 백업 방식으로 동작 ( 이전 스냅샷과 비교하며 변경된 데이터만 저장 )
  • 스냅샷 작업 시작시 저장소 내 모든 스냅샷 정보를 메모리로 올리고 작업 시작
  • 즉, 스냅샷이 많으면 무거워짐 ㅠㅠ 대량의 스냅샷 관리가 필요하다면 다른 저장소를 추가해 스냅샷을 나눠 관리 하도록 해야됨

 

(6-2) 스냅샷 생성하고 조회

  • 스냅샷 백업시 백업할 인덱스를 지정, 복수 지정 가능 ( 와일드 카드, ',' 가능 )
  • wait_for_completion 매개변수로 작업을 비동기 요청 가능
  • but, 스냅샷 비동기 요청은 tasks 작업에 등록하지 않음
  • 작업 진행 상황 확인시 스냅샷 조회 요청을 통해 확인
### 스냅샷 백업
curl -XPUT "https://192.168.219.20:9200/_snapshot/[저장소 명]/[스냅샷 이름]?pretty&wait_for_completion=false" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k \
-H "Content-Type: application/json" -d \
'{
  "indices": "my-index-20*, my-index-21*"
}'
>>> 응답의 state 부분을 확인해 작업 여부 확인
>>> indices 부분은 해당 스냅샷이 어떤 인덱스 데이터를 포함하고 있는지 나타냄

 

 

전역 상태와 feature

  • 스냅샷 찍을떄 요청 본문에 include_global_state 라는 설정을 지정가능 ( 현재 persistent 클러스터 설정, 내부 시스템 인덱스, 전역상태.. 등을 스냅샷에 저장할 것인지 )
  • include_global_state 전역 상태 종류 ( persistent, 인덱스 템플릿, 레거시 템플릿, 인제스트 파이프라인, 인덱스 생명 주기 정책, 내부 시스템 인덱스의 데이터 )
### features api를 통해 엘라스틱서치 어떤 feature들이 있는지 확인 가능

curl -XGET "https://192.168.219.20:9200/_features?pretty" -H "Authorization:
 Basic ZWxhc3RpYzpzeTAyMTg=" -k

 

 

스냅샷 상태 상세 조회

  • 스냅샷 조회 api로 정보를 얻을수 있지만 _status를 붙여 스냅샷이 몇개 파일을 포함한지, 크기, 증분 파일 개수등 상세한 정보 확인 가능
### 스냅샷 상태 상세 조회

curl -XGET "https://192.168.219.20:9200/_snapshot/[저장소 명]/[스냅샷 명]/_status?pretty" -H "Authorization:
 Basic ZWxhc3RpYzpzeTAyMTg=" -k

 

 

(6-3) 스냅샷 인덱스 복구하기

  • 스냅샷 백업 데이터로 인덱스 복구가능
  • 스냅샷 인덱스 복구 작업도 wait_for_completion=false를 지정해 비동기로 요청가능
### 스냅샷 인덱스 복구하기
curl -XPOST "https://192.168.219.20:9200/_snapshot/[저장소 명]/[스냅샷 명]/_restore?pretty" -H "Authorization:
 Basic ZWxhc3RpYzpzeTAyMTg=" -k \
 -H "Content-Type: application/json" -d \
 '{
   "indices": "some-index-202501*",
   "include_global_state": false,
   "feature_states": ["kibana"]
 }'
 >>> indices에 스냅샷 포함 인덱스 중 복구할 인덱스 지정 ( 미지정시 전체 복구 )
 >>> include_global_state는 전역상태 복구 여부
 >>> feature_state는 복구 원하는 feature 목록 지정

 

 

스냅샷 하위 호환성

  • 엘라스틱서치는 둘 이상 차이나는 클러스터 생성된 인덱스는 호환 지원하지 않음 ( es 버전이 올라가면 인덱스 내부 구조도 변경 )
  • 한 버전 씩 마이그레이션 해야됨

 

(6-4) 스냅샷 삭제하기

  • 너무 많은 스냅샷이 쌓이면 성능이 저하, 주기적 으로 스냅샷을 삭제하며 관리 필요
  • IN_PROGRESS 상태로 작업 중인 스냅샷을 삭제하려면 작업을 취소하고 삭제 진행해야됨
### 스냅샷 삭제하기
curl -XDELETE "https://192.168.219.20:9200/_snapshot/[저장소 명]/[스냅샷 명]/?pretty" -H "Authorization:
 Basic ZWxhc3RpYzpzeTAyMTg=" -k
 >>> ES 스냅샷은 증분 백업.. 즉, 다른 스냅샷이 영향을 주지 않는 파일만 삭제!!

 

 

 

(6-5) 스냅샷 생명 주기 관리 ( SLM )

  • 지정시간에 지정한 내용의 스냅샷을 찍고, 오래된 스냅샷을 삭제하는 작업을 자동화하는 정책을 등록해 스냅샷을 관리하는 기능
### 스냅샷 생명주기 관리
curl -XPUT "https://192.168.219.20:9200/_slm/policy/[스냅샷 정책 명]/?pretty" -H "Authorization: Basic ZWxhc3RpYzpzeTAyMTg=" -k \
-H "Content-Type: application/json" -d \
'{
  "name": "<daily-snapshot-{now/d}>",
  "schedule": "0 30 17 * * ?"
  "repository": "fs-repo0",
  "config": {
    "indices": [
      "<my-idx-{now/d-2d}-*>"
    ],
    "include_global_state": false
  },
  "retention": {
    "expire_after": 7d",
    "max_count": 100
  }
}'

1) repository : 스냅샷 저장소 명
2) name : 자동 생성 스냅샷 명 지정
3) schedule : 스냅샷 찍을 시간 지정
4) config.indices : 스냅샷 찍을 인덱스 지정
5) config.include_global_state : 스냅샷 전역상태 찍을지 여부
6) 스냅샷 유지 정책 ( 유지기간, 스냅샷 갯수 )