🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

이미지 로딩 중...

Elasticsearch 클러스터 운영 완벽 가이드 - 슬라이드 1/7
A

AI Generated

2025. 11. 29. · 23 Views

Elasticsearch 클러스터 운영 완벽 가이드

Elasticsearch 클러스터를 안정적으로 운영하기 위한 핵심 기술들을 다룹니다. 모니터링부터 백업, 장애 복구까지 실무에서 꼭 알아야 할 내용을 초급자도 이해할 수 있게 설명합니다.


목차

  1. 클러스터_상태_모니터링
  2. _cat_API_활용
  3. 노드_추가와_제거
  4. 샤드_재배치
  5. 스냅샷_백업
  6. 장애_복구_절차

1. 클러스터 상태 모니터링

어느 날 김개발 씨는 운영 중인 Elasticsearch 서비스가 갑자기 느려졌다는 알림을 받았습니다. 대시보드를 열어봤지만 어디서부터 확인해야 할지 막막했습니다.

선배 박시니어 씨가 다가와 말했습니다. "클러스터 상태부터 확인해봤어요?"

클러스터 상태 모니터링은 Elasticsearch 운영의 첫걸음입니다. 마치 자동차 계기판을 보며 연료와 엔진 상태를 확인하는 것처럼, 클러스터의 건강 상태를 실시간으로 파악하는 것입니다.

이를 통해 문제가 발생하기 전에 미리 대응할 수 있습니다.

다음 코드를 살펴봅시다.

// 클러스터 전체 상태 확인
GET /_cluster/health

// 응답 예시
{
  "cluster_name": "my-cluster",
  "status": "green",           // green, yellow, red 중 하나
  "number_of_nodes": 3,        // 현재 노드 수
  "active_primary_shards": 10, // 활성 프라이머리 샤드
  "active_shards": 20,         // 전체 활성 샤드
  "unassigned_shards": 0       // 미할당 샤드 (0이 정상)
}

// 특정 인덱스만 확인
GET /_cluster/health/my-index?level=shards

김개발 씨는 입사 후 처음으로 Elasticsearch 클러스터 운영을 맡게 되었습니다. 수백만 건의 로그 데이터를 저장하고 검색하는 중요한 시스템이었습니다.

하지만 어느 날 갑자기 검색 속도가 현저히 느려지기 시작했습니다. 선배 박시니어 씨가 자리로 다가왔습니다.

"클러스터 상태부터 확인해봤어요? Elasticsearch 운영의 기본은 항상 상태 모니터링부터 시작하는 거예요." 그렇다면 클러스터 상태란 정확히 무엇일까요?

쉽게 비유하자면, 클러스터 상태는 마치 병원에서 받는 건강검진 결과표와 같습니다. 의사가 혈압, 맥박, 체온을 확인하듯이, Elasticsearch도 자신의 건강 상태를 색깔로 알려줍니다.

green은 완전히 건강한 상태, yellow는 주의가 필요한 상태, red는 즉시 조치가 필요한 위험 상태입니다. 클러스터 상태를 확인하지 않으면 어떤 일이 벌어질까요?

문제가 서서히 커지고 있는데도 모르고 지나칠 수 있습니다. 어느 날 갑자기 서비스가 멈추고 나서야 부랴부랴 원인을 찾게 됩니다.

더 큰 문제는 장애 원인을 파악하는 데 시간이 오래 걸린다는 것입니다. 미리 모니터링했다면 막을 수 있었던 장애를 속수무책으로 겪게 됩니다.

이런 문제를 방지하기 위해 _cluster/health API가 존재합니다. 이 API를 호출하면 클러스터의 전반적인 상태를 한눈에 파악할 수 있습니다.

status 필드가 가장 중요합니다. green이면 모든 프라이머리 샤드와 레플리카 샤드가 정상적으로 할당되어 있다는 뜻입니다.

위의 코드를 살펴보겠습니다. 첫 번째 요청 GET /_cluster/health는 전체 클러스터 상태를 반환합니다.

응답에서 number_of_nodes는 현재 클러스터에 참여 중인 노드 수를 보여줍니다. unassigned_shards가 0이 아니라면 어딘가에 문제가 있다는 신호입니다.

실제 현업에서는 어떻게 활용할까요? 대부분의 회사에서는 이 API를 주기적으로 호출하는 모니터링 시스템을 구축합니다.

상태가 yellow나 red로 바뀌면 즉시 슬랙이나 이메일로 알림을 보냅니다. 이렇게 하면 문제가 커지기 전에 빠르게 대응할 수 있습니다.

하지만 주의할 점도 있습니다. 초보 운영자들이 흔히 하는 실수는 yellow 상태를 무시하는 것입니다.

yellow는 당장 서비스에 문제가 없어 보이지만, 노드 하나가 죽으면 데이터 유실로 이어질 수 있습니다. 따라서 yellow 상태도 반드시 원인을 파악하고 해결해야 합니다.

다시 김개발 씨의 이야기로 돌아가 봅시다. 클러스터 상태를 확인해보니 unassigned_shards가 5개나 있었습니다.

"아, 이래서 느렸군요!" 원인을 찾은 김개발 씨는 안도의 한숨을 쉬었습니다.

실전 팁

💡 - 클러스터 상태를 1분 주기로 모니터링하는 것을 권장합니다

  • yellow 상태가 10분 이상 지속되면 반드시 원인을 조사하세요

2. cat API 활용

김개발 씨가 클러스터 상태를 확인하려고 JSON 응답을 눈으로 읽고 있었습니다. 박시니어 씨가 지나가다 말했습니다.

"그거 눈 아프지 않아요? _cat API 쓰면 훨씬 보기 편해요." 김개발 씨는 처음 듣는 이야기였습니다.

_cat API는 Elasticsearch의 상태 정보를 사람이 읽기 쉬운 텍스트 형식으로 보여주는 API입니다. 마치 터미널에서 ls 명령어로 파일 목록을 보는 것처럼, 클러스터 정보를 표 형태로 깔끔하게 출력해줍니다.

운영자가 빠르게 상황을 파악하는 데 필수적인 도구입니다.

다음 코드를 살펴봅시다.

// 노드 목록과 상태 확인
GET /_cat/nodes?v
// ip           heap.percent cpu load_1m node.role master name
// 192.168.1.1  45           12  0.25    cdfhilmrstw *   node-1
// 192.168.1.2  38           8   0.15    cdfhilmrstw -   node-2

// 인덱스 목록과 용량 확인
GET /_cat/indices?v&s=store.size:desc
// health status index      docs.count store.size
// green  open   logs-2024  15000000   25gb
// green  open   users      50000      100mb

// 샤드 분배 현황 확인
GET /_cat/shards?v&s=index
// index    shard prirep state   docs store node
// logs     0     p      STARTED 5000 50mb  node-1
// logs     0     r      STARTED 5000 50mb  node-2

김개발 씨는 매일 아침 클러스터 상태를 점검하는 것이 일과가 되었습니다. 하지만 JSON 응답을 읽는 것은 생각보다 피곤한 일이었습니다.

중첩된 중괄호 사이에서 원하는 정보를 찾아 헤매야 했습니다. 어느 날 박시니어 씨가 터미널에서 무언가를 입력하는 것을 봤습니다.

화면에 깔끔한 표 형태의 데이터가 출력되었습니다. "이게 뭐예요?" 김개발 씨가 물었습니다.

_cat API는 Elasticsearch가 제공하는 특별한 API 시리즈입니다. 이름이 재미있는데, cat은 리눅스의 cat 명령어에서 따온 것입니다.

파일 내용을 그대로 출력하는 것처럼, 클러스터 정보를 가공 없이 바로 보여준다는 의미입니다. JSON 대신 탭으로 구분된 텍스트 형태로 결과를 반환합니다.

왜 이런 API가 필요할까요? 일반적인 API는 프로그램이 처리하기 좋은 JSON 형식으로 응답합니다.

하지만 운영자가 터미널에서 빠르게 상태를 확인할 때는 JSON이 오히려 불편합니다. _cat API는 사람의 눈으로 바로 읽을 수 있도록 설계되었습니다.

코드를 하나씩 살펴보겠습니다. /_cat/nodes는 클러스터에 참여 중인 모든 노드 정보를 보여줍니다.

?v 옵션을 붙이면 각 컬럼이 무엇인지 헤더가 표시됩니다. v는 verbose의 약자입니다.

master 컬럼에서 별표(*)가 있는 노드가 현재 마스터 노드입니다. /_cat/indices는 모든 인덱스 목록을 보여줍니다.

&s=store.size:desc 옵션을 추가하면 용량이 큰 순서대로 정렬됩니다. 어떤 인덱스가 디스크를 많이 차지하는지 한눈에 파악할 수 있습니다.

/_cat/shards는 샤드가 어떤 노드에 분배되어 있는지 보여줍니다. prirep 컬럼에서 p는 프라이머리, r은 레플리카를 의미합니다.

샤드가 특정 노드에 몰려있지 않은지 확인할 때 유용합니다. 실제 현업에서는 이런 식으로 활용합니다.

매일 아침 출근하면 /_cat/health로 전체 상태를 확인합니다. 그 다음 /_cat/indices로 어제 생성된 인덱스가 정상인지 점검합니다.

문제가 있으면 /_cat/shards로 어떤 샤드에 문제가 있는지 추적합니다. 이 세 가지만 알아도 대부분의 일상적인 점검은 가능합니다.

하지만 주의할 점이 있습니다. _cat API의 출력 형식은 버전에 따라 바뀔 수 있습니다.

따라서 자동화 스크립트에서는 JSON API를 사용하는 것이 안전합니다. _cat API는 어디까지나 사람이 직접 확인할 때 쓰는 도구입니다.

김개발 씨는 _cat API를 알고 나서 업무 효율이 크게 올랐습니다. "이제 JSON 파싱하느라 시간 낭비 안 해도 되겠네요!" 박시니어 씨가 웃으며 답했습니다.

"운영자의 필수 도구죠."

실전 팁

💡 - ?v 옵션은 항상 붙이세요. 컬럼 의미를 알 수 있습니다

  • ?help 옵션으로 사용 가능한 모든 컬럼을 확인할 수 있습니다

3. 노드 추가와 제거

서비스가 성장하면서 검색 트래픽이 두 배로 늘었습니다. 김개발 씨는 노드를 추가해야 한다는 것을 알았지만, 운영 중인 클러스터에 노드를 붙이는 것이 걱정되었습니다.

"서비스 중단 없이 가능할까요?" 박시니어 씨가 답했습니다. "당연하죠, Elasticsearch가 알아서 해줘요."

노드 추가와 제거는 Elasticsearch 클러스터를 확장하거나 축소하는 작업입니다. 마치 레고 블록을 끼우고 빼는 것처럼, 운영 중에도 노드를 자유롭게 추가하거나 제거할 수 있습니다.

Elasticsearch는 자동으로 샤드를 재분배하여 균형을 맞춥니다.

다음 코드를 살펴봅시다.

// 노드 추가: elasticsearch.yml 설정
cluster.name: my-cluster
node.name: node-4
network.host: 192.168.1.4
discovery.seed_hosts: ["192.168.1.1", "192.168.1.2", "192.168.1.3"]

// 노드 제거 전 안전하게 샤드 이동
PUT /_cluster/settings
{
  "persistent": {
    "cluster.routing.allocation.exclude._name": "node-3"
  }
}

// 샤드 이동 완료 확인 후 노드 종료
GET /_cat/shards?v&h=index,shard,prirep,node
// node-3에 샤드가 없으면 안전하게 종료 가능

// 제외 설정 해제 (노드 제거 완료 후)
PUT /_cluster/settings
{
  "persistent": {
    "cluster.routing.allocation.exclude._name": null
  }
}

서비스가 성공하면 기쁜 일이지만, 운영자에게는 새로운 과제가 생깁니다. 트래픽이 늘어나면 서버를 증설해야 합니다.

김개발 씨도 이런 상황에 직면했습니다. 현재 3대의 노드로 운영 중인데, 2대를 더 추가해야 했습니다.

"혹시 노드 추가하려면 서비스를 잠시 내려야 하나요?" 김개발 씨가 걱정스럽게 물었습니다. 박시니어 씨가 고개를 저었습니다.

"아니요, Elasticsearch의 장점 중 하나가 바로 무중단 확장이에요." 노드 추가는 생각보다 간단합니다. 새 서버에 Elasticsearch를 설치하고, 설정 파일에서 cluster.name을 기존 클러스터와 동일하게 맞춰주면 됩니다.

그리고 discovery.seed_hosts에 기존 노드들의 주소를 넣어줍니다. 새 노드를 시작하면 자동으로 클러스터에 합류합니다.

마치 새 친구가 동아리에 가입하는 것과 같습니다. 동아리 이름(cluster.name)을 알고, 기존 회원(seed_hosts) 연락처만 있으면 자연스럽게 합류할 수 있습니다.

가입 후에는 동아리 일(샤드)을 나눠서 맡게 됩니다. 노드 제거는 조금 더 신중해야 합니다.

노드를 그냥 종료하면 해당 노드에 있던 샤드가 갑자기 사라집니다. 물론 레플리카가 있다면 데이터는 보존되지만, 클러스터가 복구하느라 부하가 걸립니다.

계획된 작업이라면 더 우아한 방법이 있습니다. 코드를 살펴보겠습니다.

cluster.routing.allocation.exclude._name 설정은 특정 노드에 더 이상 샤드를 할당하지 말라는 의미입니다. 이 설정을 적용하면 Elasticsearch가 해당 노드의 샤드를 다른 노드로 천천히 옮기기 시작합니다.

/_cat/shards로 확인하면서 해당 노드에 샤드가 모두 빠질 때까지 기다립니다. 샤드가 0개가 되면 그때 안전하게 노드를 종료할 수 있습니다.

이렇게 하면 클러스터에 전혀 충격을 주지 않습니다. 실제 현업에서는 Decommission 절차라고 부릅니다.

새벽에 긴급하게 노드를 빼야 하는 상황이 아니라면, 항상 이 절차를 따릅니다. 대형 서비스에서는 노드 하나를 빼는 데 몇 시간이 걸리기도 합니다.

샤드 이동이 완료될 때까지 인내심을 갖고 기다려야 합니다. 주의할 점도 있습니다.

노드를 제거한 후에는 반드시 exclude 설정을 해제해야 합니다. 그렇지 않으면 나중에 같은 이름의 노드를 추가해도 샤드가 할당되지 않는 문제가 생길 수 있습니다.

김개발 씨는 두 대의 새 노드를 성공적으로 추가했습니다. 클러스터가 자동으로 샤드를 재분배하는 것을 보며 감탄했습니다.

"정말 레고 블록 끼우는 것처럼 쉽네요!"

실전 팁

💡 - 노드 추가 후 샤드 재분배에는 시간이 걸립니다. 급하게 다음 작업을 하지 마세요

  • 마스터 노드는 최소 3대, 홀수로 유지하는 것이 좋습니다

4. 샤드 재배치

클러스터에 새 노드를 추가했는데, 기존 노드에만 샤드가 몰려있었습니다. 김개발 씨가 물었습니다.

"새 노드가 놀고 있는 것 같은데요?" 박시니어 씨가 설명했습니다. "샤드 재배치 설정을 확인해봐야겠네요."

샤드 재배치는 클러스터 내 노드들 사이에서 샤드를 옮기는 작업입니다. 마치 창고 관리자가 물건을 여러 창고에 골고루 분산시키는 것처럼, Elasticsearch도 샤드를 노드들에 균등하게 배치합니다.

수동으로 특정 샤드를 원하는 노드로 이동시킬 수도 있습니다.

다음 코드를 살펴봅시다.

// 현재 샤드 분배 상태 확인
GET /_cat/allocation?v
// shards disk.used disk.avail disk.percent node
// 10     50gb      100gb      33           node-1
// 10     45gb      105gb      30           node-2
// 0      0b        150gb      0            node-3

// 특정 샤드를 수동으로 이동
POST /_cluster/reroute
{
  "commands": [
    {
      "move": {
        "index": "logs-2024",
        "shard": 0,
        "from_node": "node-1",
        "to_node": "node-3"
      }
    }
  ]
}

// 샤드 재배치 속도 조절 (대역폭 제한)
PUT /_cluster/settings
{
  "persistent": {
    "indices.recovery.max_bytes_per_sec": "100mb"
  }
}

김개발 씨가 새로 추가한 노드를 확인해보니 이상한 점이 있었습니다. 분명 클러스터에 정상적으로 합류했는데, 샤드가 하나도 없었습니다.

기존 노드들은 여전히 바쁜데, 새 노드는 한가하게 쉬고 있었습니다. "왜 자동으로 분배되지 않는 거죠?" 김개발 씨가 의아해했습니다.

박시니어 씨가 차근차근 설명했습니다. "Elasticsearch는 기본적으로 자동 재배치를 하지만, 몇 가지 조건이 있어요." 샤드 재배치를 이해하려면 먼저 Elasticsearch의 샤드 할당 정책을 알아야 합니다.

Elasticsearch는 클러스터 균형을 맞추기 위해 끊임없이 샤드 분배를 계산합니다. 하지만 무조건 옮기는 것은 아닙니다.

옮기는 비용(네트워크 전송, 디스크 I/O)과 균형 개선 효과를 비교해서, 이득이 클 때만 옮깁니다. 마치 이사를 결정할 때와 같습니다.

새 집이 조금 넓다고 무조건 이사하지 않습니다. 이사 비용과 수고를 감안해서 충분히 이득이 될 때만 옮기는 것입니다.

코드를 살펴보겠습니다. /_cat/allocation은 각 노드별 샤드 수와 디스크 사용량을 보여줍니다.

이것으로 불균형 상태를 한눈에 파악할 수 있습니다. 위의 예시에서 node-3은 샤드가 0개인 것을 확인할 수 있습니다.

/_cluster/reroute API는 수동으로 샤드를 이동시킵니다. move 명령은 특정 샤드를 지정한 노드에서 다른 노드로 옮깁니다.

대량의 샤드를 옮길 때는 스크립트를 작성해서 순차적으로 처리합니다. indices.recovery.max_bytes_per_sec 설정은 샤드 이동 속도를 제한합니다.

운영 중인 서비스에서 대량의 샤드를 옮기면 네트워크 대역폭을 많이 사용합니다. 이 설정으로 서비스에 영향을 최소화할 수 있습니다.

실제 현업에서는 언제 수동 재배치를 할까요? 주로 새 노드를 추가했는데 자동 분배가 충분히 이루어지지 않을 때 사용합니다.

또는 특정 노드의 디스크가 부족해서 급하게 샤드를 빼야 할 때도 사용합니다. 하지만 대부분의 경우 Elasticsearch의 자동 분배를 믿고 기다리는 것이 좋습니다.

주의할 점이 있습니다. 프라이머리 샤드와 레플리카 샤드는 반드시 다른 노드에 있어야 합니다.

같은 노드에 두면 그 노드가 죽었을 때 데이터를 복구할 수 없습니다. Elasticsearch가 이 규칙을 자동으로 지키지만, 수동 reroute 시에는 개발자가 직접 확인해야 합니다.

김개발 씨는 /_cat/allocation을 보며 상황을 파악했습니다. 자동 분배를 조금 더 기다려보기로 했습니다.

다음 날 확인해보니 샤드가 골고루 분배되어 있었습니다. "역시 기다림도 운영의 일부네요."

실전 팁

💡 - 대량 재배치 시에는 반드시 속도 제한 설정을 사용하세요

  • 프라이머리와 레플리카가 같은 노드에 있으면 안 됩니다

5. 스냅샷 백업

어느 날 김개발 씨가 실수로 중요한 인덱스를 삭제해버렸습니다. 얼굴이 하얗게 질린 김개발 씨에게 박시니어 씨가 물었습니다.

"스냅샷 백업해뒀죠?" 다행히 매일 자동 백업을 설정해둔 덕분에 데이터를 복구할 수 있었습니다.

스냅샷 백업은 Elasticsearch 인덱스의 특정 시점 상태를 저장하는 기능입니다. 마치 게임에서 세이브 포인트를 만드는 것처럼, 문제가 생겼을 때 이전 상태로 돌아갈 수 있습니다.

운영 환경에서는 반드시 정기적인 스냅샷 백업을 설정해야 합니다.

다음 코드를 살펴봅시다.

// 1. 스냅샷 저장소 등록 (S3 예시)
PUT /_snapshot/my_backup
{
  "type": "s3",
  "settings": {
    "bucket": "my-es-backups",
    "region": "ap-northeast-2"
  }
}

// 2. 전체 클러스터 스냅샷 생성
PUT /_snapshot/my_backup/snapshot_20241115
{
  "indices": "*",
  "include_global_state": true
}

// 3. 스냅샷 목록 확인
GET /_snapshot/my_backup/_all

// 4. 스냅샷 상태 확인
GET /_snapshot/my_backup/snapshot_20241115/_status

// 5. 특정 인덱스만 스냅샷
PUT /_snapshot/my_backup/logs_backup
{
  "indices": "logs-*",
  "include_global_state": false
}

데이터 백업의 중요성은 아무리 강조해도 지나치지 않습니다. 하지만 많은 개발자들이 백업을 소홀히 하다가 낭패를 보곤 합니다.

김개발 씨도 그런 경험을 할 뻔했습니다. 실수로 인덱스를 삭제한 순간, 머릿속이 하얘졌습니다.

3개월치 로그 데이터가 한순간에 사라진 것입니다. 식은땀이 흘렀습니다.

"스냅샷 백업 설정해뒀죠?" 박시니어 씨의 질문에 김개발 씨는 고개를 끄덕였습니다. 입사 첫날 박시니어 씨가 가장 먼저 알려준 것이 바로 스냅샷 설정이었습니다.

그렇다면 스냅샷이란 정확히 무엇일까요? 쉽게 비유하자면, 스냅샷은 특정 순간을 찍은 사진과 같습니다.

시간이 지나 변화가 생겨도 그 사진을 보면 과거 상태를 정확히 알 수 있습니다. Elasticsearch 스냅샷도 마찬가지로 인덱스의 특정 시점 상태를 저장합니다.

스냅샷의 가장 큰 장점은 증분 백업입니다. 첫 번째 스냅샷은 전체 데이터를 저장합니다.

하지만 두 번째 스냅샷부터는 변경된 부분만 저장합니다. 100GB 인덱스에서 1GB만 바뀌었다면, 두 번째 스냅샷은 1GB만 저장하는 것입니다.

덕분에 저장 공간과 시간을 크게 절약할 수 있습니다. 코드를 살펴보겠습니다.

먼저 /_snapshot/my_backup으로 저장소를 등록합니다. 예시에서는 AWS S3를 사용했습니다.

type에 s3를 지정하고, 버킷 이름과 리전을 설정합니다. 로컬 파일시스템이나 HDFS도 사용할 수 있습니다.

스냅샷 생성은 PUT /_snapshot/저장소명/스냅샷명으로 합니다. indices에 백업할 인덱스 패턴을 지정합니다.

별표(*)는 모든 인덱스를 의미합니다. include_global_state를 true로 설정하면 클러스터 설정까지 함께 백업됩니다.

실제 현업에서는 어떻게 활용할까요? 대부분의 회사에서는 매일 자정에 자동으로 스냅샷을 생성하도록 설정합니다.

Elasticsearch에서 제공하는 SLM(Snapshot Lifecycle Management) 기능을 사용하면 자동화가 가능합니다. 보통 최근 7일 또는 30일치 스냅샷을 보관합니다.

주의할 점도 있습니다. 스냅샷은 생성하는 데 시간이 걸립니다.

대용량 인덱스라면 몇 시간이 소요될 수 있습니다. 따라서 트래픽이 적은 시간대에 스냅샷을 생성하는 것이 좋습니다.

또한 스냅샷 저장소는 반드시 클러스터 외부(S3, NFS 등)에 두어야 합니다. 클러스터 자체가 손상되면 스냅샷도 함께 날아가기 때문입니다.

김개발 씨는 스냅샷에서 삭제된 인덱스를 복원했습니다. 데이터 손실 없이 위기를 넘긴 것입니다.

"백업의 소중함을 뼈저리게 느꼈어요." 그 이후로 김개발 씨는 스냅샷 상태를 매일 확인하게 되었습니다.

실전 팁

💡 - 스냅샷 저장소는 반드시 클러스터 외부에 두세요

  • SLM으로 자동화하고, 오래된 스냅샷은 자동 삭제하도록 설정하세요

6. 장애 복구 절차

새벽 3시, 김개발 씨의 전화가 울렸습니다. "클러스터가 red 상태입니다!" 심장이 쿵쾅거렸지만, 그동안 배운 장애 복구 절차를 떠올리며 차분하게 대응했습니다.

미리 준비된 절차가 있었기에 빠르게 복구할 수 있었습니다.

장애 복구 절차는 클러스터에 문제가 발생했을 때 정상 상태로 되돌리는 일련의 과정입니다. 마치 응급실 의사가 환자를 치료하는 순서가 정해져 있듯이, Elasticsearch 장애도 체계적인 절차에 따라 복구합니다.

미리 절차를 숙지하고 있으면 당황하지 않고 빠르게 대응할 수 있습니다.

다음 코드를 살펴봅시다.

// 1단계: 클러스터 상태 확인
GET /_cluster/health?level=indices

// 2단계: 문제 있는 인덱스 확인
GET /_cat/indices?v&health=red

// 3단계: 미할당 샤드 원인 파악
GET /_cluster/allocation/explain
{
  "index": "logs-2024",
  "shard": 0,
  "primary": true
}

// 4단계: 노드 상태 확인
GET /_cat/nodes?v&h=name,heap.percent,disk.percent,cpu

// 5단계: 레플리카로부터 복구 시도
POST /_cluster/reroute?retry_failed=true

// 6단계: 스냅샷에서 복원 (최후 수단)
POST /_snapshot/my_backup/snapshot_20241115/_restore
{
  "indices": "logs-2024",
  "rename_pattern": "(.+)",
  "rename_replacement": "restored_$1"
}

장애는 예고 없이 찾아옵니다. 중요한 것은 당황하지 않고 체계적으로 대응하는 것입니다.

김개발 씨는 새벽 알림을 받고 노트북을 열었습니다. 손이 떨렸지만, 메모해둔 복구 절차를 보며 하나씩 실행했습니다.

첫 번째로 할 일은 상황 파악입니다. 클러스터가 red라는 것은 일부 프라이머리 샤드를 사용할 수 없다는 뜻입니다.

하지만 어떤 인덱스의 어떤 샤드가 문제인지 알아야 합니다. /_cluster/health?level=indices로 인덱스별 상태를 확인합니다.

두 번째로 문제 인덱스를 특정합니다. /_cat/indices?health=red는 red 상태인 인덱스만 필터링해서 보여줍니다.

보통 한두 개 인덱스만 문제인 경우가 많습니다. 전체가 빨간색이라면 더 심각한 문제일 수 있습니다.

세 번째로 원인을 파악합니다. /_cluster/allocation/explain API는 왜 샤드가 할당되지 못했는지 상세히 알려줍니다.

디스크 부족인지, 노드가 죽었는지, 설정 문제인지 등을 확인할 수 있습니다. 이 정보가 복구 방향을 결정합니다.

코드를 순서대로 살펴보겠습니다. 1단계에서 전체 상태를 파악한 후, 2단계에서 문제 인덱스를 찾습니다.

3단계 allocation/explain이 가장 중요합니다. 여기서 "node_1 has insufficient disk space" 같은 메시지가 나오면 디스크 정리가 필요합니다.

"no active copy found" 라면 데이터 유실 가능성이 있습니다. 4단계에서는 노드 자원 상태를 점검합니다.

디스크 사용률이 90%를 넘으면 새 샤드 할당이 차단됩니다. 5단계 retry_failed=true는 실패한 샤드 할당을 다시 시도합니다.

일시적인 문제였다면 이것으로 해결되기도 합니다. 6단계는 최후의 수단입니다.

프라이머리와 레플리카 모두 유실된 경우, 스냅샷에서 복원해야 합니다. _restore API로 스냅샷의 인덱스를 복원합니다.

rename_replacement를 사용하면 기존 인덱스와 이름이 충돌하지 않도록 할 수 있습니다. 실제 현업에서는 이 절차를 문서화해둡니다.

장애 상황에서는 생각보다 침착하기 어렵습니다. 미리 절차를 정리해두고, 정기적으로 모의 훈련을 하는 회사도 있습니다.

김개발 씨도 이날 이후 복구 절차서를 작성하고 팀에 공유했습니다. 주의할 점이 있습니다.

복구 과정에서 서두르다가 상황을 더 악화시킬 수 있습니다. 예를 들어 문제 노드를 급하게 재시작하면 복구 중인 샤드가 다시 초기화될 수 있습니다.

항상 현재 상태를 충분히 파악한 후 행동해야 합니다. 새벽 4시, 김개발 씨는 클러스터를 정상화시켰습니다.

원인은 한 노드의 디스크 부족이었습니다. 오래된 인덱스를 삭제하고 공간을 확보하니 샤드가 자동으로 복구되었습니다.

"절차대로 했더니 생각보다 빨리 끝났네요." 안도의 한숨을 쉬며 다시 잠자리에 들었습니다.

실전 팁

💡 - 장애 복구 절차를 문서화하고 팀원들과 공유하세요

  • 정기적으로 복구 훈련을 해보면 실제 상황에서 당황하지 않습니다

이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!

#Elasticsearch#Cluster#Monitoring#Backup#Recovery#Elasticsearch,Search,Backend

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.