Node가 예기치 않게 이탈될 경우 shard allocation 지연시키기

# 클러스터에서 노드가 제외되는 현상

ElasticSearch 에서는 Fault Detection을 위해 master->nodes, nodes->master 양방향으로 주기적으로 ping을 날립니다.
아무 설정을 하지 않았다면 1초마다 ping을 날리고, 30초 동안 응답이 없으면 3번 재시도 후 최종적으로 fault라고 단정짓고 해당 노드를 클러스터에서 제외 시킵니다.

운영중인 클러스터에서는 이런 상황이라면 문제가 심각해 질 수 있습니다. 이유는

  • 클러스터에서 노드가 한개 빠짐 ->
  • 빠진 노드가 가지고 있던 shard 들이 unassigned shards 로 변경됨 ->
  • unassigned shards 를 기존 노드들이 나눠갖는 shard allocation 발생 ->
  • 데이터 량이 많은 인덱스의 경우 shard allocation 작업은 굉장히 비싼 작업이므로 CPU load 높아짐 ->
  • 서비스 지연이 발생 가능

위와같은 상황이 발생되지 않도록 예방하기 위해서는 두가지 솔루션이 있습니다.

  1. ** 노드가 클러스터에서 이탈되지 않도록 Fault Detection 을 느슨하게 변경 **
  2. ** 노드가 클러스터에서 이탈 되더라도 unassigned shards 를 바로 allocation 이 일어 나지 않도록 설정 변경**

# Fault Detection

첫번째로 Fault Detection을 느슨하게 변경 하는 방법을 알아보겠습니다.

아래 표와 같이 ping_interval, ping_timeout, ping_retries 관련 값을 조정함으로서 느슨하게 변경 할 수 있습니다.
** ※ 해당 값의 변경은 Elastic 에서 권장하는 방법은 아닙니다. **

Setting Description
discovery.zen.fd.ping_interval How often a node gets pinged. Defaults to 1s.
discovery.zen.fd.ping_timeout How long to wait for a ping response, defaults to 30s.
discovery.zen.fd.ping_retries How many ping failures / timeouts cause a node to be considered failed. Defaults to 3.

< elasticsearch.yml 에 설정 할 수 있는 fault detection 관련 설정값>
출처 : https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-discovery-zen.html

위 설정은 dynamic setting 으로 바로 적용하기는 어렵고 (바로 반영 시키려면 인덱스를 close 한 상태로는 가능) elasticsearch.yml 파일에 설정 후 재기동 하는것이 좋겠습니다.
인덱스 close가 가능한 상황이라면 아래 명령어를 바로 날려도 됩니다.

fault detection ping retries 를 6번으로 변경하는 예

1
2
3
4
5
6
curl -XPUT 'localhost:9200/_all/_settings?pretty' -H 'Content-Type: application/json' -d'
{
"settings": {
"discovery.zen.fd.ping_retries": 6
}
}'

# allocation 지연

두번째로 unassigned shards의 allocation을 지연시키는 방법을 알아 보겠습니다.

이유를 정확히 알 수 없지만 GC가 오래 걸려서 Stop the world가 길게 된다던지 하면 첫번째 방법으로 fault detection을 느슨하게 했더라도 노드가 클러스터에서 빠질 수 있습니다.

노드가 빠졌더라도 shard allocation만 일어나지 않는다면 서버에 무리를 주지는 않으므로 (replica가 1 이상 설정 되어 있어서 노드 한개가 빠지더라도 서비스에 영향이 없다는 가정하에) 빠진 노드를 재시작 하고 다시 클러스터에 join 시킬때까지 시간을 좀 벌려는 목적으로 아래 설정을 적용 시킵니다.

unassigned shards 를 5분이 지날때 까지 unassigned 상태로 유지하는 예

1
2
3
4
5
6
curl -XPUT 'localhost:9200/_all/_settings?pretty' -H 'Content-Type: application/json' -d'
{
"settings": {
"index.unassigned.node_left.delayed_timeout": "5m"
}
}'

저렇게 되면 노드 하나가 빠져서 cluster health 가 yellow로 변경 된 이후 5분의 여유가 생기므로 shard allocation을 none 으로 바꾼 후 분석을 한다던지 복구를 한다던지 하는 선택지를 가질수 있게 됩니다.

Share