본문 바로가기

SearchDeveloper/엘라스틱서치 바이블

[7] 운영 도중 발생하는 장애 대응

장애 탐지를 위한 지표 수집 및 모니터링

지표 수집

메트릭비트: 여러 서비스의 메트릭 데이터를 주기적으로 수집해 ES, logstash, kafka 등으로 넘김)

각 노드마다 메트릭비트 있는 것보다 한 클러스터에 한 메트릭비트로 수집하는것을 공식문서에서는 추천한다.

※ 메트릭비트 설치는 책 참고

모니터링용 클러스터 구축

모니터링용 ES 와 키바나를 별도로 구성한다.

 

메트릭비트 + 키바나

그 다음에 보안 적용을 위해 elasticsearch-xpack, kibana-xpack 어쩌고 하는데 잘 모르겠다..

메트릭비트 + 키바나 조합 사용하면 키바나에 자동으로 모니터링 대시보드가 생성되는 것 같다.

키바나 얼럿이나 웹훅은 유료 버전이다.

메트릭비트 + 그라파나

-얼럿이나 웹훅 무료로 사용 가능

-지표는 메트릭비트로 수집해 ES 에 저장하고 그라파나에서 ES 인덱스를 등록해 알람 등록하는 구조

-메트릭비트에 elasticsearch.cluster.stats.nodes.jvm.memory.heap.used.bytes 같은 속성이 있다.

장애 대응

샤드 할당 비활성화클라이언트의 트래픽 차단로그 확인 및 대응 조치샤드 복구 대기상세 원인 분석 프로세스

 

샤드 할당 비활성화

GET _cat/healthGET _cat/nodes 했을 때 노드 수가 원래 수보다 적다면 바로 샤드 할당 꺼야 한다.

왜?

클러스터에서 노드 하나 빠지면 number_of_replicas 수 맞추기 위해 새 레플리카 할당하고 데이터 복사 작업을 수행하는데, 부하 때문인 장애 상황 경우가 많고 가뜩이나 노드 적은데 부하 가중되면 더 힘들어질 수 있다.

어떻게?

PUT _cluster/settings
{"transient": {"cluster.routing.allocation.enable": "primaries"}}

none, primaries, new-primaries 중 하나 하고 해소되면 all 로 바꿔주기

만약 마스터 선출 실패나 (STW) stop-the-world 로 인해 샤드 비활성화 요청 실패해도 일단 다음 단계로 넘어간다.

클라이언트 트래픽 차단

샤드 비활성화 뒤 트래픽 차단하는 것이 좋다.

왜?

노드 재시작 같은 거 했을 때 샤드 복구 과정 중 변경이 있으면 변경 작업을 전파해서 재처리하는데 재처리 작업이 많으면 전체 샤드 복구 시간이 늦어지고 추가 부하 받으므로

어떻게?

조정 전용 노드만 내린다.

(그럼 클라 쪽은 계속 에러 나겠네?)

로그 확인 및 대응 조치

[case 1] health 요청 응답은 빠른데 GET _cat/nodes 요청에 오래 걸리거나 타임아웃 나면?

일부 노드가 STW 로 먹통일 수도 있다.

재기동으로 해결한다. (kill -15, 안되면 kill -9)

[case 2] health, node 응답 모두 빠른데 합류 못한 노드가 있다면?

단순 OOM 으로 죽은 것일 수도 있다.

재기동으로 해결한다.

샤드 복구 대기

샤드 할당 다시 all 로 하고 green 으로 돌아올 때까지 대기한다.

자주 발생하는 장애 유형

키바나에서 과도한 요청 인입

임시로 키바나 내리거나 조정 전용 노드 내려서 키바나가 원인인지 확인한다.

GC 로 인한 STW

full gc 로 인해 stw 인 경우 샤드 할당 비활성화, 트래픽 차단, 재기동해야 한다.

신버전은 G1GC 도입하고 서킷 브레이커 추가돼서 발생 빈도가 많이 낮아졌다.

Disk Full

7.5 버전 이상

-디스크 사용량 기본 95% 넘으면 인덱스에 워터마크 붙여서 더 이상 색인 못하게 막는다.

-디스크 여유 생기면 자동으로 워터마크 해제한다.

index block setting

index.blocks.read_only (index setting 불가 - metadata 변경 불가) index.blocks.read_only_allow_delete (blocks.write 랑 비슷한데 삭제 추가로 가능) ``index.blocks.read
index.blocks.write (index setting - metadata 변경 가능)`` ```index.blocks.metadata` ``

7.4 버전 이하

-워터마크를 수동으로 해제해줘야 한다.

PUT [인덱스명]/_settings
{"index.blocks.read_only_allow_delete": false}

미할당 샤드 남았는데 샤드 할당 진행 안 됨

green 되기를 기다리는데 샤드 할당이 더 이상 진행되지 않고 yellow 나 red 에서 남아있을 때

원인 파악

GET _cluster/allocation/explain?pretty

이유 종류

-최대 재시도 횟수 차서, 서킷 브레이커 걸려서, too many open files, 댕글링 인덱스라서

재할당 진행

POST _cluster/reroute?retry_failed=true

최대 재시도 횟수에 걸려 할당 안 된 경우

Dangling Index

노드가 합류할 때 로컬 data directory 에는 샤드 데이터가 있는데 클러스터 메타데이터에는 해당 인덱스와 샤드 정보가 없는 경우

댕글링 인덱스가 생성되는 시나리오

  • [1번] 노드 제외 후 인덱스 삭제, 노드 다시 인입
  • 마스터 노드 문제로 메타데이터 깨지고 로컬 데이터와 맞지 않을 때

인덱스 묘비

-[1번] 시나리오에서 노드 합류 후 댕글링 인덱스를 수동으로 재삭제 하지 않기 위해 클러스터에서 인덱스 삭제할 때 마다 인덱스 묘비(index tombstones) 를 세운다.

  • index tombstones: 특정 인덱스 삭제됐다고 클러스터에 명시적으로 남기는 기록
  • cluster.indices.tombstones.size (디폴트 500개)

-댕글링 인덱스 판단 전에 묘비 살피고 있으면 삭제 취급을 하고 댕글링 인덱스를 발생시키지 않는다.

 

댕글링 인덱스 복구

7.9 버전 미만

자동으로 일반 인덱스로 복구해 적재했는데 모든 샤드가 남아있지 않은 경우가 많아 yellow, red 를 발행시키게 된다.

그래서 7.9 이상부터는 자동 적재는 비활성화 되었고 댕글링 인덱스를 복구할지 말지 선택할 수 있다.

GET _dangling

DELETE _dangling/[인덱스명]?accept_data_loss=true 댕글링 삭제

POST _dangling/[인덱스명]?accept_data_loss=true 댕글링 적재

→ 최신 상태 반영 여부는 알 수 없고 남은 데이터를 최대한 복구해보는 작업에 불과하다. 샤드 다 댕글링 인덱스에 없다면 yellow, red 뜬다. 동일한 인덱스명이 이미 있다면 재대로 수행되지 않는다.

장애 복구 중 새 인덱스 생성됨

새 인덱스 생성되면 제일 적은 수의 샤드 할당된 노드에 새 샤드를 할당하는데, 장애 복구 위해 방금 재시작된 노드에 쏠릴 수 있다.

해결

임시로 샤드 할당 균형을 잡지 않는다.

PUT _cluster/settings
{"transient": {"cluster.routing.allocation.balance.shard": 0}}

0 일 수록 균형을 신경 쓰지 않는다.

장애 복구 후 다시 돌려놔야 한다.

이미 샤드 할당이 불균형이라면?

명시적으로 샤드 재할당을 한다.

_cluster/reroute

POST /_cluster/reroute?metric=none
{"commands": [{
      "move": {"index": "test", "shard": 0, "from_node": "node1", "to_node": "node2"}
  }]}

장애 복구 중 다음 날 넘어가서 일단위 인덱스 대량 생성될 때

샤드 할당 균형 하지 않게 설정하고 수동으로 미리 인덱스 생성한다.

PUT _cluster/settings
{"transient": {"cluster.routing.allocation.balance.shard": 0}}

특정 노드 성능 떨어질 때

-STW 나 무거운 요청으로 인한 일시적인 상황이라면 - 재기동한다.

-지속적이라면

  • 샤드가 그 노드에 몰려있진 않은지 확인
  • 클라가 조정 노드가 아니라 그 노드에만 요청하고 있진 않은지 확인
  • 하드웨어 문제는 아닌지 확인 (iostat)

샤드 복구

-샤드 복구 시간은 중요하다! 전체 장애 처리 완료 시간을 좌우하고 서비스 안정성에도 영향을 미치기 때문에.

-너무 큰 샤드를 만들지 않도록 주의한다.

-조정 노드 트래픽을 차단한다. (아니면 변경 사항을 레플리카 샤드에도 재처리해 늦어질 수 있음)

-샤드 복구 진행 사항 확인 GET [인덱스명]/_recovery/?human

  • stage: INIT, INDEX, VERIFY_INDEX, TRANSLOG, FINALIZE, DONE

샤드 복구 속도 조정

네트워크를 통한 동시에 수행하는 샤드 복구 작업 수 조정

  • 다른 노드에 샤드 복제해 주는 작업 다른 노드로부터 샤드 복제받는 작업 혹은 프라이머리 샤드 위치 옮기는 경우
  • 한 값으로 복제해주는 작업수, 복제 받는 작업 수 동시에 설정된다. (기본값 2)
    • PUT _cluster/settings
      {"transient": {"cluster.routing.allocation.node_concurrent_recoveries": 4}}

네트워크 통하지 않는 로컬 디스크 읽어 복구할 프라이머리 샤드 수

네트워크 안 타서 빠르기도 하고 프라이머리는 빠른 복구가 중요해서 일시적으로 높이기도 한다. (기본값 4)

  • PUT _cluster/settings
    {"transient": {"cluster.routing.allocation.node_initial_primaries_recoveries": 8}}

네트워크 트래픽 속도 설정

  • PUT _cluster/settings
    {"transient": {"index.recovery.max_bytes_per_sec": "512mb"}}

조정 노드 내렸다면 좀 더 올려도 된다.

샤드 복구 우선순위 조정

PUT [인덱스명]/_settings
{"index.priority": 10}

숫자 높을 수록 먼저 복구 됨 > 인덱스 생성 시간 최신순 > 인덱스명 내림차순

원활한 장애 복구 위한 서비스 구조

클라 → [[메시지 큐]] → ES 색인

메시지 큐를 앞에 놓으면 장점

  • ES 장애 상황에서 큐에서 색인 하는 프로세스만 내리면 돼서 데이터 생산에는 문제 없다.
  • 일부 데이터 재처리 가능 (offset)
  • reindex 하는 동안 최신 데이터 변경분 반영 방법 - reindex 작업 시간 이전으로 offset 을 뒤감아 reindex 한 새 인덱스에 추가 색인

kafka-connect-elasticsearch

클러스터 분리: 서비스용, 서비스 로그용, 지표 등 데이터 분석용

 

레퍼런스

엘라스틱서치 바이블 7장