INFRA

[ELK] Elastic Search ILM 정책 (+추가 에러 핸들링)

jeonyoungseo 2023. 9. 25. 17:52

Can’t log into Elastic (self hosted) “Oops! Error. Try again.”

[lens_merge_tables] > [esaggs] > EsError

TOO_MANY_REQUESTS/12/disk usage exceeded flood-stage watermark ..

해당 에러들은 모두 Elastic disk 가 가득차서 생기는 오류이다. free -h 명령어로 Elastic server에서 몇 퍼센트를 사용하고 있는지 확인할 수 있다. 아래 /elk 메모리가 90퍼센트 이상 사용하게 되면 주로 해당 오류들이 발생한다.

[**@n**** config]# df -h
Filesystem               Size  Used Avail Use% Mounted on
dev****                 
t**                      
t**s                    
t**                      
/dev/***/c**t       
/dev/***/***-elk   1.0T  922G  103G  90% /elk
t***

1. 일시적인 해결 방법

운영 중인 엘라스틱서치 순차적 재시작 ( Rolling-Restart )

  • curl -u {id}:{password} -X PUT "<https://***:9200/_cluster/settings>" -H "Content-Type: application/json" -d '{
       "persistent": {
         "cluster.routing.allocation.enable": null
       }
     }'
  •  

해당 시간동안 운영되었던 index 기록 삭제

DELETE /metricbeat-***-2023.09.08-000001

2. ILM 생명주기를 이용하여 지속적으로 관리하여 해결하기

아래는 가장 기본적으로 쓰이는 ILM 정책으로, 이 정책을 적용해주면 30일 후 또는 인덱스의 크기가 50gb에 도달하면(기본 샤드를 기준으로) 인덱스를 롤오버하고 새 인덱스에 쓰기 시작한다.

아래와 같이 Dev Tools에 curl 명령어를 이용해 할당할 수도 있고 

PUT /_ilm/policy/my_policy
{
  "policy":{
    "phases":{
      "hot":{
        "actions":{
          "rollover":{
            "max_size":"50gb",
            "max_age":"30d"
          }
        }
      },
      "delete":{
      	"min_age": "7d",
        "actions": {}
      }
    }
  }
}

아래와 같이 Index LifeCycle Policy를 이용하여 GUI로 할당시킬 수도 있다.

이해를 돕기위한 사진 - Hot phase에서 rollover 지정
이해를 돕기 위한 사진 - Delete phase에서 delete timing 7일로 지정

해당 policy를 사용하는 index의 크기가 50gb가 되거나 또는 수명이 30d일 때 rollover하도록 설정하고, 이후 index의 age가 7일이 지나면 삭제하겠다는 것을 의미한다.

  • Hot phase : 최근 데이터를 저장하는 단계로, 빠른 검색과 실시간 분석을 지원한다
  • Warm phase : 중간기간의 데이터를 저장하는 단계로, 검색 속도는 상대적으로 느리지만 비용을 절감할 수 있다.
  • Cold phase : 오래된 데이터를 저장하는 단계로, 저장 공간을 저렴하게 유지하면서 데이터를 장기 보존한다.
  • Delete phase : 가장 오래된 데이터를 삭제하는 단계로, 저장 용량을 유지 관리하며 더 이상 필요하지 않은 데이터를 삭제한다.

 index 당 age 보기(해당 index가 생성된 날짜 확인하기)

추가로 index당 age를 자세히 보고 싶다면 아래와 같이 format을 할당하여 하루마다 바뀌는 index를 확인해 볼 수 있다. 아래 사진에서 -000001은 위에서 우리가 지정한 rollback에 따라 000002, 000003 ... 으로 증가하는데 index의 크기가 50gb가 넘지 않아서 아래 날짜에서는 롤백하지 않았다.

날짜 설정을 위해서는 아래의 방법을 따르자 !

yml파일에서 index이름을 아래 형식으로 변환해준 후 

output.elasticsearch:
  hosts: ***
  protocol: "https"
  username: ***
  password: ****
  index: "metric-example-%{+yyyy.MM.dd}"

 

아래와 같이 ilm 정책의 policy_name을 위에서 만든 정책으로 설정한다.

metricbeat.config.modules:
  path: ${path.config}/modules.d/*.yml
  reload.enabled: false
  reload.period: 10s

setup.template.settings:
  index.number_of_shards: 1
  index.codec: best_compression
setup.template.name: "metric-secret"
setup.template.pattern: "metric-secret-*"
setup.template.overwrite: false
setup.ilm.enabled: true
setup.ilm.policy_name: "my_policy"

 

트러블슈팅

만약 해당 index에 alias 별칭( ex. setup.ilm.rollover_alias: "hellometrics” )을 설정했다면/하고 싶다면 여기 공식문서 에서 말하는 것처럼 해당 alias에 is_write_index: true로 지정하여 해당 별칭에 날짜와 rollover이 적히도록 따로 지정해야 함에 주의하자 !

# PUT <my-index-{now/d}-000001>
PUT %3Cmy-index-%7Bnow%2Fd%7D-000001%3E
{
  "aliases": {
    "my-alias": {
      "is_write_index": true
    }
  }
}