Parca

2편. Parca 아키텍처 한눈에 보기 – Server, Agent, Storage 구조

SysBPF 2025. 12. 18. 19:39

Parca 아키텍처 한눈에 보기

Server · Agent · Storage 구조 완전 해부

Parca를 이해하는 가장 빠른 방법은
**“무엇을 수집하고, 어디로 보내며, 어떻게 저장·조회하는가”**를 명확히 구분하는 것이다.

Parca는 구조적으로 매우 단순하다.

Agent는 수집만 하고
Server는 저장과 질의만 한다

이 단순함이 Parca의 가장 큰 장점이다.

 

Parca 전체 구조 개요

Parca는 크게 3가지 구성 요소로 나뉜다.

  1. parca-agent
  2. Parca Server
  3. Profile Storage

각각의 역할은 명확히 분리되어 있으며,
Agent는 최대한 가볍게, Server는 분석에 집중하도록 설계되어 있다.


1. parca-agent

“아무 말도 하지 않는 관측자”

parca-agent는 Parca의 핵심이지만,
의외로 가장 단순한 역할을 맡고 있다.

parca-agent의 책임

  • eBPF 기반 CPU profiling 수행
  • 주기적으로 stack trace 샘플링
  • 수집된 데이터를 즉시 서버로 전송
  • 로컬 저장, 분석, 해석은 하지 않음

즉,

Agent는 생각하지 않는다.
오직 수집하고 전달할 뿐이다.


내부 동작 흐름

  1. perf_event 기반 샘플링 트리거
  2. eBPF 프로그램이 커널/유저 스택 캡처
  3. stack trace → 프로파일 샘플 변환
  4. protobuf 포맷으로 직렬화
  5. Parca Server로 push

이 구조 덕분에 agent는 다음과 같은 특성을 갖는다.

  • 매우 낮은 오버헤드
  • 장애 시 영향 최소화
  • 컨테이너 환경에서도 안정적

parca-agent 실행 예시

parca-agent \ --node=$(hostname) \ --store-address=parca-server:7070 \ --sampling-frequency=19 \ --log-level=info
 
 

여기서 중요한 포인트는 다음이다.

  • sampling-frequency
    → 초당 샘플링 횟수 (높을수록 정밀, 낮을수록 오버헤드 감소)
  • Agent에는 저장 경로 옵션이 없다
  • 모든 데이터는 서버로 즉시 전송된다

왜 Pull이 아니라 Push인가?

Prometheus와 달리 Parca는 Push 모델이다.

이유는 명확하다.

  • 프로파일 데이터는 크고 복잡하다
  • Flamegraph 생성에 필요한 구조를 유지해야 한다
  • 서버가 agent를 주기적으로 긁는 구조는 비효율적

즉,
**“수집 주체가 가장 잘 아는 데이터를 직접 보내는 구조”**가 선택된 것이다.


2. Parca Server

“시간을 저장하고 비교하는 엔진”

Parca Server는 단순한 수집 서버가 아니다.

Server의 역할은 다음과 같다.

  • 프로파일 데이터 수신
  • 시간 축 기준 저장
  • 쿼리 요청 처리
  • Flamegraph 생성
  • UI 및 API 제공

Agent가 보내는 데이터는
“그 자체로는 아무 의미가 없다”.

의미는 Server에서 만들어진다.


Server가 하는 핵심 작업

  • 여러 agent로부터 받은 프로파일 병합
  • 시간 범위 기반 aggregation
  • diff flamegraph 생성
  • label(node, pod, container 등) 기반 필터링

이 때문에 Server는 CPU와 메모리를 상대적으로 더 사용한다.


Parca Server 실행 예시

parca \ --http-address=:7070 \ --storage-path=/var/lib/parca \ --log-level=info
 

여기서 주목할 점:

  • Server만이 storage를 가진다
  • Agent는 disk I/O를 거의 사용하지 않는다
  • 분석 부하는 Server에 집중된다

3. Profile Storage

“메트릭이 아닌, 시간의 기록”

Parca가 저장하는 것은 단순한 수치가 아니다.

저장되는 것은:

  • 함수 호출 스택
  • 커널 + 유저 스택 결합 정보
  • 시간 구간별 샘플 분포

즉,
“CPU 시간이 흘러간 경로” 자체다.


왜 TSDB가 아닌가?
(Time Series Database)

Prometheus 같은 TSDB는 다음에 적합하다.

  • 숫자 값
  • 고정된 label
  • 단순 집계

하지만 Parca의 데이터는:

  • 트리 구조 (call stack)
  • 동적 심볼
  • 비교(diff)가 중요

그래서 Parca는 자체 스토리지 포맷을 사용한다.


데이터 흐름 정리

[ Application / Kernel ]
              ↓
          eBPF
              ↓
       parca-agent
             
(protobuf, gRPC) Parca 
Server
              
      Profile 
Storage
              
     Web UI / API
 

이 구조 덕분에 다음이 가능해진다.

  • “지금”뿐 아니라 “과거”를 볼 수 있음
  • 배포 전/후 성능 비교
  • 특정 시간대만 골라 분석

이 구조가 실무에서 의미하는 것

이 아키텍처는 다음 철학을 반영한다.

  • 수집은 가볍게
  • 해석은 중앙에서
  • 에이전트 장애는 서비스 장애가 아니다
    ( 관측을 담당하는 에이전트가 멈추거나 실패해도,
    실제 서비스(애플리케이션)는 영향을 받지 않아야 한다
    는 뜻)

특히 대규모 환경에서:

  • agent는 DaemonSet으로 무차별 배포
  • server는 소수 인스턴스로 집중 운영
  • 문제 발생 시 server만 스케일

이 모델은 Kubernetes 환경에서 특히 강력하다.


다음 편 예고

다음 편에서는
이 구조의 핵심인 parca-agent 내부,
eBPF 기반 수집 메커니즘을 더 깊게 파고든다.

  • 어떤 eBPF 프로그램이 올라가는가
  • perf_event는 어떻게 사용되는가
  • 커널 스택과 유저 스택은 어떻게 합쳐지는가
  • 오버헤드는 왜 낮은가

다음 편

3편. parca-agent 내부 구조 분석 – eBPF 기반 수집 메커니즘