스토리지

스토리지 (Storage)

프로메테우스가 시계열 데이터를 어떻게 로컬에 저장하고, 원격 스토리지와 어떻게 연동하는지 설명하는 문서예요. 운영 관점에서 가장 중요한 내용이 담겨 있어요: 디스크 레이아웃, 보존(retention) 정책, 컴팩션, 백업, 그리고 대용량 데이터를 미리 채워 넣는 백필링(backfilling)까지. 프로메테우스 디스크 사용량을 계획하거나 데이터가 손상됐을 때 어떻게 대처할지 알고 싶다면 여기를 보면 돼요.

프로메테우스는 로컬 디스크 기반 시계열 데이터베이스를 포함하지만, 선택적으로 원격 스토리지 시스템과도 통합해요. 로컬 스토리지는 프로메테우스가 직접 관리하는 핵심 저장소이고, 원격 스토리지는 확장성·내구성을 위해 붙이는 옵션이에요. 구조부터 하나씩 뜯어볼게요.

출처: 문서

본문

프로메테우스는 로컬 디스크 기반 시계열 데이터베이스를 포함하지만, 선택적으로 원격 스토리지 시스템과도 통합해요.

로컬 스토리지 (Local storage)

프로메테우스의 로컬 시계열 데이터베이스는 로컬 스토리지에 맞춤형의 매우 효율적인 형식으로 데이터를 저장해요.

디스크 레이아웃 (On-disk layout)

수집된 샘플은 2시간 블록으로 그룹화돼요. 각 블록은 해당 시간 윈도우의 모든 시계열 샘플을 담은 chunks 하위 디렉토리, 메타데이터 파일, 그리고 (메트릭 이름과 레이블을 chunks 디렉토리의 시계열에 매핑하는) 인덱스 파일을 포함하는 디렉토리로 구성돼요. chunks 디렉토리의 샘플은 하나 이상의 세그먼트 파일로 구성되며, 각각 기본적으로 최대 512MB예요. API를 통해 시리즈가 삭제되면 삭제 기록은 chunk 세그먼트에서 즉시 제거되는 대신 별도의 tombstone 파일에 저장돼요.

수신 샘플의 현재 블록은 메모리에 유지되며 완전히 영속화되지 않아요. 이는 프로메테우스 서버가 재시작될 때 재생할 수 있는 write-ahead log(WAL)로 크래시로부터 보호돼요. WAL 파일은 wal 디렉토리에 128MB 세그먼트로 저장돼요. 이 파일들은 아직 컴팩트되지 않은 원시 데이터를 포함하므로 일반 블록 파일보다 훨씬 커요. 프로메테우스는 최소 3개의 WAL 파일을 유지해요. 트래픽이 많은 서버는 최소 2시간의 원시 데이터를 유지하기 위해 3개 이상의 WAL 파일을 유지할 수 있어요.

프로메테우스 서버의 데이터 디렉토리는 대략 다음과 같아요:

./data
├── 01BKGV7JBM69T2G1BGBGM6KB12
│   └── meta.json
├── 01BKGTZQ1SYQJTR4PB43C8PD98
│   ├── chunks
│   │   └── 000001
│   ├── tombstones
│   ├── index
│   └── meta.json
├── 01BKGTZQ1HHWHV8FBJXW1Y3W0K
│   └── meta.json
├── 01BKGV7JC0RY8A6MACW02A2PJD
│   ├── chunks
│   │   └── 000001
│   ├── tombstones
│   ├── index
│   └── meta.json
├── chunks_head
│   └── 000001
└── wal
    ├── 000000002
    └── checkpoint.00000001
        └── 00000000

로컬 스토리지의 한계는 클러스터링이나 복제를 하지 않는다는 점이에요. 따라서 임의로 확장 가능하지 않고 드라이브나 노드 장애에 대해 내구성이 있지도 않으며, 다른 단일 노드 데이터베이스처럼 관리해야 해요. 적절한 아키텍처로 로컬 스토리지에 수년간의 데이터를 보존할 수는 있어요.

백업에는 스냅샷(Snapshots)을 권장해요. 스냅샷 없이 만든 백업은 마지막 TSDB 블록이 생성된 이후 기록된 데이터를 잃을 위험이 있는데, 이는 보통 2시간마다 발생하며 마지막 3시간의 샘플을 포함해요. 백업이나 복원에서 WAL 파일(storage.tsdb.pathchunks_head/, wal/, wbl/ 디렉토리)을 제외하면 어떤 경우든 일관된 백업이 보장되지만, WAL 파일이 다루는 시간 범위를 잃는 대가가 있어요.

대안으로 원격 읽기/쓰기 API를 통해 외부 스토리지를 사용할 수 있어요. 이 시스템들은 내구성, 성능, 효율성에서 크게 다양하므로 신중한 평가가 필요해요.

파일 형식에 대한 자세한 내용은 TSDB format을 참조하세요.

컴팩션 (Compaction)

초기 2시간 블록은 결국 백그라운드에서 더 긴 블록으로 컴팩트돼요.

컴팩션은 보존 시간의 최대 10% 또는 31일 중 더 작은 값을 포함하는 더 큰 블록을 만들어요. 소스 블록과 새 컴팩트 블록이 모두 디스크에 공존해야 하므로, 디스크 상 크기는 일시적으로 storage.tsdb.retention.size를 초과할 수 있어요. 초과분은 다음 보존 정리에 소스 블록이 제거될 때 해제돼요.

운영 측면 (Operational aspects)

프로메테우스는 로컬 스토리지를 구성하는 여러 플래그가 있어요. 가장 중요한 것들:

  • --storage.tsdb.path: 프로메테우스가 데이터베이스를 쓰는 위치. 기본값은 data/
  • --storage.tsdb.retention.time: 스토리지에 샘플을 보존하는 기간. 이 플래그와 storage.tsdb.retention.size가 모두 설정되지 않으면 보존 시간은 기본값 15d로 설정돼요. 지원 단위: y, w, d, h, m, s, ms
  • --storage.tsdb.retention.size: 보존할 스토리지 블록의 최대 바이트 수. 가장 오래된 데이터가 먼저 제거돼요. 기본값은 0 또는 비활성화. 지원 단위: B, KB, MB, GB, TB, PB, EB. 예: "512MB". 2의 거듭제곱 기반이므로 1KB는 1024B예요. 이 보존을 지키기 위해 영속 블록만 삭제되지만 WAL과 m-mapped 청크는 총 크기에 계산돼요. 따라서 디스크의 최소 요구사항은 wal(WAL과 Checkpoint)과 chunks_head(m-mapped Head 청크) 디렉토리를 합친 피크 공간(2시간마다 피크)이에요
  • --storage.tsdb.wal-compression: write-ahead log(WAL) 압축 활성화. 데이터에 따라 약간의 추가 CPU 부하로 WAL 크기가 절반이 될 것으로 기대할 수 있어요. 이 플래그는 2.11.0에서 도입되었고 2.20.0에서 기본 활성화됐어요. 활성화한 후 2.11.0 미만 버전으로 다운그레이드하려면 WAL을 삭제해야 한다는 점에 유의하세요

프로메테우스는 샘플당 평균 1-2바이트만 저장해요. 따라서 프로메테우스 서버의 용량을 계획할 때 대략적인 공식을 사용할 수 있어요:

needed_disk_space = retention_time_seconds * ingested_samples_per_second * bytes_per_sample

수집 샘플의 속도를 낮추려면 스크레이프하는 시계열 수를 줄이거나(타깃 수를 줄이거나 타깃당 시리즈 수를 줄임), 스크레이프 간격을 늘릴 수 있어요. 다만 시리즈 내 샘플의 압축 덕분에 시리즈 수를 줄이는 것이 더 효과적일 가능성이 높아요.

로컬 스토리지가 프로메테우스가 시작되지 않을 정도로 손상되면 스토리지 디렉토리를 백업한 다음 백업에서 손상된 블록 디렉토리를 복원하는 것이 좋아요. 백업이 없으면 마지막 수단으로 손상된 파일을 제거해요. 예를 들어 개별 블록 디렉토리나 WAL 파일을 제거해 볼 수 있어요. 이는 그 블록이나 WAL이 다루는 시간 범위의 데이터를 잃는다는 뜻임을 유의하세요.

주의: 프로메테우스 로컬 스토리지에는 POSIX 비준수 파일시스템이 지원되지 않아 복구 불가능한 손상이 발생할 수 있어요. NFS 파일시스템(AWS의 EFS 포함)은 지원되지 않아요. NFS는 POSIX 준수가 가능하지만 대부분의 구현은 그렇지 않아요. 안정성을 위해 로컬 파일시스템을 사용하는 것이 강력히 권장돼요.

시간과 크기 보존 정책이 모두 지정된 경우 먼저 트리거되는 쪽이 사용돼요.

만료된 블록 정리는 백그라운드에서 발생해요. 만료된 블록을 제거하는 데 최대 2시간이 걸릴 수 있어요. 블록은 완전히 만료된 후에야 제거돼요.

보존 크기 적정화 (Right-Sizing Retention Size)

storage.tsdb.retention.size를 사용해 크기 제한을 설정한다면 프로메테우스에 할당한 스토리지 대비 이 값의 적절한 크기를 고려해야 해요. 할당된 스토리지가 가득 차기 전에 오래된 항목이 제거되도록, 여유 버퍼를 제공하기 위해 보존 크기를 줄이는 것이 현명해요.

현재는 보존 크기를 할당된 프로메테우스 디스크 공간의 최대 80-85%로 설정할 것을 권장해요. 나머지 15-20% 버퍼는 진행 중인 컴팩션(자세한 내용은 컴팩션 참조)에 필요한 임시 추가 공간을 다루는데, 컴팩션은 이전 블록이 제거되기 전에 소스 블록과 새로 컴팩트된 블록을 동시에 디스크에 유지해요.

원격 스토리지 연동 (Remote storage integrations)

프로메테우스의 로컬 스토리지는 단일 노드의 확장성과 내구성에 제한돼요. 프로메테우스 자체에서 클러스터형 스토리지를 해결하려고 시도하는 대신, 프로메테우스는 원격 스토리지 시스템과 통합할 수 있게 해주는 일련의 인터페이스를 제공해요.

개요 (Overview)

프로메테우스는 네 가지 방식으로 원격 스토리지 시스템과 통합해요:

  • 프로메테우스는 수집한 샘플을 Remote Write 형식으로 원격 URL에 쓸 수 있어요
  • 프로메테우스는 다른 클라이언트로부터 Remote Write 형식으로 샘플을 받을 수 있어요
  • 프로메테우스는 원격 URL에서 Remote Read 형식으로 샘플 데이터를 (다시) 읽을 수 있어요
  • 프로메테우스는 클라이언트가 요청한 샘플 데이터를 Remote Read 형식으로 반환할 수 있어요

remote read와 write 프로토콜은 모두 HTTP 위에서 snappy 압축 protocol buffer 인코딩을 사용해요. read 프로토콜은 아직 안정 API로 간주되지 않아요.

write 프로토콜은 1.0 버전의 안정 사양2.0 버전의 실험 사양을 가지며, 둘 다 프로메테우스 서버가 지원해요.

클라이언트로서 프로메테우스에서 원격 스토리지 연동을 구성하는 방법에 대한 자세한 내용은 프로메테우스 구성 문서의 remote writeremote read 섹션을 참조하세요.

읽기 경로에서 프로메테우스는 레이블 셀렉터와 시간 범위 세트에 대한 원시 시리즈 데이터만 원격 측에서 가져온다는 점에 유의하세요. 원시 데이터에 대한 모든 PromQL 평가는 여전히 프로메테우스 자체에서 발생해요. 이는 모든 필요한 데이터를 먼저 쿼리하는 프로메테우스 서버에 로드한 다음 거기서 처리해야 하므로 remote read 쿼리에 일부 확장성 한계가 있음을 의미해요. 다만 완전히 분산된 PromQL 평가를 지원하는 것은 당분간 실행 불가능한 것으로 간주됐어요.

프로메테우스는 또한 두 프로토콜을 모두 서비스해요. 내장 remote write 수신자는 --web.enable-remote-write-receiver 커맨드라인 플래그를 설정해 활성화할 수 있어요. 활성화되면 remote write 수신자 엔드포인트는 /api/v1/write예요. remote read 엔드포인트는 /api/v1/read에서 사용할 수 있어요.

기존 연동 (Existing integrations)

원격 스토리지 시스템과의 기존 연동에 대해 더 알아보려면 Integrations 문서를 참조하세요.

OpenMetrics 형식에서 백필링 (Backfilling from OpenMetrics format)

개요 (Overview)

OpenMetrics 형식의 데이터에서 TSDB로 블록을 만들고 싶다면 백필링을 사용해 할 수 있어요. 다만 프로메테우스가 아직 변형 중인 현재 head 블록과 시간 범위가 겹칠 수 있으므로 지난 3시간(현재 head 블록)의 데이터를 백필하는 것은 안전하지 않다는 점에 주의하세요. 백필링은 각각 2시간의 메트릭 데이터를 포함하는 새 TSDB 블록을 만들어요. 이는 블록 생성의 메모리 요구사항을 제한해요. 2시간 블록을 더 큰 블록으로 컴팩트하는 것은 나중에 프로메테우스 서버 자체가 해요.

일반적인 사용 사례는 다른 모니터링 시스템이나 시계열 데이터베이스에서 프로메테우스로 메트릭 데이터를 마이그레이션하는 것이에요. 그러려면 사용자는 먼저 소스 데이터를 아래에서 설명하는 백필링의 입력 형식인 OpenMetrics 형식으로 변환해야 해요.

네이티브 히스토그램과 staleness 마커는 OpenMetrics 형식으로 표현할 수 없기 때문에 이 절차에서 지원되지 않는다는 점에 유의하세요.

사용법 (Usage)

백필링은 promtool 커맨드라인으로 사용할 수 있어요. promtool은 블록을 디렉토리에 써요. 기본적으로 이 출력 디렉토리는 ./data/이며, 하위 명령에서 원하는 출력 디렉토리 이름을 선택적 인자로 사용해 변경할 수 있어요.

promtool tsdb create-blocks-from openmetrics <input file> [<output directory>]

블록 생성 후 프로메테우스의 데이터 디렉토리로 이동하세요. 프로메테우스의 기존 블록과 겹치면 v2.38 이하 버전에서는 --storage.tsdb.allow-overlapping-blocks 플래그를 설정해야 해요. 백필된 모든 데이터는 프로메테우스 서버에 구성된 보존(시간 또는 크기)의 적용을 받는다는 점에 유의하세요.

더 긴 블록 기간 (Longer Block Durations)

기본적으로 promtool은 블록에 기본 블록 기간(2h)을 사용해요. 이 동작이 가장 일반적으로 적용 가능하고 정확해요. 다만 긴 시간 범위의 데이터를 백필할 때는 더 큰 블록 기간 값을 사용하는 것이 백필을 더 빠르게 하고 나중에 TSDB의 추가 컴팩션을 방지하는 데 유리할 수 있어요.

--max-block-duration 플래그를 사용하면 사용자가 블록의 최대 기간을 구성할 수 있어요. 백필링 도구는 이보다 크지 않은 적절한 블록 기간을 선택할 거예요.

더 큰 블록이 대용량 데이터셋의 백필링 성능을 향상시킬 수 있지만 단점도 있어요. 시간 기반 보존 정책은 (잠재적으로 큰) 블록의 샘플 하나라도 보존 정책 내에 있으면 전체 블록을 유지해야 해요. 반대로 크기 기반 보존 정책은 TSDB가 크기 제한을 아주 조금만 넘어도 전체 블록을 제거해요.

따라서 적은 수의 블록으로 백필하고, 즉 더 큰 블록 기간을 선택하는 것은 주의해서 수행해야 하며 프로덕션 인스턴스에는 권장되지 않아요.

기록 규칙용 백필링 (Backfilling for Recording Rules)

개요 (Overview)

새 기록 규칙이 생성되면 그에 대한 과거 데이터가 없어요. 기록 규칙 데이터는 생성 시점부터만 존재해요. promtool은 과거 기록 규칙 데이터를 만들 수 있게 해줘요.

사용법 (Usage)

모든 옵션을 보려면 $ promtool tsdb create-blocks-from rules --help를 사용하세요.

예시 사용법:

$ promtool tsdb create-blocks-from rules \
    --start 1617079873 \
    --end 1617097873 \
    --url http://mypromserver.com:9090 \
    rules.yaml rules2.yaml

제공된 기록 규칙 파일은 일반적인 프로메테우스 규칙 파일이어야 해요.

promtool tsdb create-blocks-from rules 명령의 출력은 기록 규칙 파일의 모든 규칙에 대한 과거 규칙 데이터를 포함하는 블록이 담긴 디렉토리예요. 기본적으로 출력 디렉토리는 data/예요. 이 새 블록 데이터를 사용하려면 블록을 실행 중인 프로메테우스 인스턴스 데이터 디렉토리 storage.tsdb.path로 이동해야 해요 (v2.38 이하 버전의 경우 --storage.tsdb.allow-overlapping-blocks 플래그를 활성화해야 함). 이동하면 새 블록은 다음 컴팩션이 실행될 때 기존 블록과 병합돼요.

제한 사항 (Limitations)

  • 겹치는 start/end 시간으로 규칙 백필러를 여러 번 실행하면 규칙 백필러가 실행될 때마다 같은 데이터를 포함하는 블록이 생성돼요
  • 기록 규칙 파일의 모든 규칙이 평가돼요
  • 기록 규칙 파일에 interval이 설정되어 있으면 규칙 백필 명령의 eval-interval 플래그보다 우선해요
  • 기록 규칙 파일에 경고가 있으면 현재 무시돼요
  • 같은 그룹의 규칙은 이전 규칙의 결과를 볼 수 없어요. 즉 백필되는 다른 규칙을 참조하는 규칙은 지원되지 않아요. 해결 방법은 여러 번 백필하고 의존 데이터를 먼저 만드는 것(그리고 의존 데이터를 프로메테우스 서버 데이터 디렉토리로 이동해 프로메테우스 API에서 접근 가능하게 하는 것)이에요

더 알아보기 (Learn more)