본문 바로가기
IT/Cloud

[Prometheus] Label 하나가 시스템을 느리게 만든다 - 1. Metric, Label, TimeSeries

by Jany 2026. 6. 21.
반응형

1편 [Prometheus] 왜 다들 프로메테우스를 사용할까


Prometheus를 운영하다 보면 어느 순간 메모리가 부족해지거나 쿼리가 느려지기 시작한다.

그런데 CPU가 부족한 것도 아니고, 디스크가 꽉 찬 것도 아니다.

문제는 대부분 여기서 시작된다.

Label.

Prometheus에서 Label은 단순한 부가 정보가 아니다.

Label은 TimeSeries를 만드는 기준이다.

그래서 Prometheus를 이해하려면 먼저 이 흐름을 이해해야 한다.

Metric → Label 조합 → TimeSeries

Prometheus는 숫자를 저장하는 시스템처럼 보이지만, 운영 관점에서는 Label 조합을 저장하는 시스템에 가깝다.

1. Metric과 Label

Prometheus에서 가장 먼저 보이는 것은 Metric이다.

예를 들어 HTTP 요청 수를 나타내는 Metric은 이렇게 생겼다.

http_requests_total

이 Metric은 “HTTP 요청이 총 몇 번 발생했는가”를 의미한다.

하지만 실제 운영에서는 전체 요청 수만 보는 경우가 많지 않다.

GET 요청은 몇 개인지, POST 요청은 몇 개인지, 200 응답은 몇 개인지, 500 응답은 몇 개인지를 나눠서 보고 싶다.

이때 사용하는 것이 Label이다.

http_requests_total{method="GET", status="200"}

여기서 Metric 이름은 http_requests_total이다.

Label은 다음 두 개다.

method="GET"
status="200"

Label은 Metric에 차원을 추가한다.

즉 단순히 “HTTP 요청 수”가 아니라 “GET 요청 중 200 응답 수”처럼 데이터를 나눠서 볼 수 있게 해준다.

Label이 있기 때문에 Prometheus에서는 같은 Metric도 다양한 기준으로 쪼개서 볼 수 있다.

 

2. TimeSeries는 어떻게 만들어지는가

Prometheus에서 정말 중요한 개념은 TimeSeries다.

TimeSeries는 시간에 따라 기록되는 하나의 데이터 흐름이다.

다음 Metric과 Label 조합은 하나의 TimeSeries를 만든다.

http_requests_total{method="GET", status="200"}

 

같은 Metric, 다른 Label 조합

http_requests_total{method="POST", status="200"}

이것은 앞의 TimeSeries와 다르다.

Metric 이름은 같지만 Label 조합이 다르기 때문이다.

예를 들면 다음과 같다.

http_requests_total{method="GET",  status="200"} -> TimeSeries A
http_requests_total{method="POST", status="200"} -> TimeSeries B
http_requests_total{method="GET",  status="500"} -> TimeSeries C

즉 Prometheus에서 TimeSeries는 Metric 이름만으로 결정되지 않는다.

Metric 이름과 Label 조합이 함께 TimeSeries를 만든다.

정리하면 이렇다.

Metric → Label 조합 → TimeSeries 생성

이 흐름을 이해하면 Prometheus의 성능 문제도 훨씬 쉽게 이해된다.

 

3. Label 하나가 왜 위험해질 수 있을까

Label은 데이터를 나눠 보는 데 매우 유용하다.

문제는 Label 값이 많아질 때 시작된다.

예를 들어 다음과 같은 Metric이 있다고 하자.

http_requests_total{method, status}

method 값이 3개라고 해보자.

GET
POST
PUT

status 값이 4개라고 해보자.

200
400
404
500

그러면 만들어질 수 있는 TimeSeries는 다음과 같다.

3 × 4 = 12개

여기까지는 괜찮다.

그런데 여기에 path Label을 추가한다고 해보자.

http_requests_total{method, status, path}

만약 path 값이 100개라면 TimeSeries는 이렇게 늘어난다.

3 × 4 × 100 = 1,200개

Label 하나를 추가했을 뿐인데 TimeSeries가 12개에서 1,200개로 늘어났다.

이것이 Prometheus에서 Label을 조심해야 하는 이유다.

 

4. Prometheus는 Label 조합을 저장한다

Prometheus는 숫자를 저장한다.

하지만 운영 관점에서 더 중요한 것은 숫자 자체가 아니다.

그 숫자를 구분하는 Label 조합이다.

다음 두 데이터는 Metric 이름이 같다.

http_requests_total{method="GET", status="200"}
http_requests_total{method="POST", status="200"}

하지만 Prometheus는 이 둘을 서로 다른 TimeSeries로 본다.

왜냐하면 Label 조합이 다르기 때문이다.

그래서 Prometheus를 운영할 때는 Metric 개수만 보면 안 된다.

중요한 것은 이 Metric이 몇 개의 Label 조합을 만들고 있는가다.

즉 질문을 이렇게 바꿔야 한다.

“Metric이 몇 개인가?”

가 아니라

“이 Metric이 몇 개의 TimeSeries를 만들고 있는가?”

 

마무리

Prometheus에서 Label은 단순한 메타데이터가 아니다.

Label은 TimeSeries를 만드는 기준이다.

같은 Metric이라도 Label 조합이 달라지면 다른 TimeSeries가 된다.

Metric → Label 조합 → TimeSeries

이 구조 때문에 Prometheus는 숫자를 저장하는 시스템이라기보다 Label 조합을 저장하는 시스템에 가깝다.

다음 글에서는 이 Label 조합이 많아질 때 발생하는 문제, 즉 Cardinality를 다룬다.

반응형

댓글