본문으로 건너뛰기
mcpd
데몬 없음

릴레이와 리전

에이전트 곁의 컬렉터, 그리고 재시도와 함께 건너는 리전 사이의 연결.

릴레이란

mcpd relay는 같은 바이너리를 스스로는 아무것도 저장하지 않는 컬렉터로 실행합니다. 데몬이 받는 모든 HTTP 수집 요청을 받아 디스크의 스풀에 쓰고, 보낸 쪽에 응답한 다음, --upstream이 지정한 데몬으로 그 요청을 보냅니다. 저장소는 열지 않습니다.

에이전트가 도는 리전마다 하나씩 실행하십시오. 그러면 보낸 쪽은 몇 밀리초 거리에 있는 컬렉터와 이야기하고, 리전 사이의 연결은 에이전트마다 따로가 아니라 릴레이가 재시도와 함께 건넙니다.

업스트림 두 개를 둔 엣지 릴레이

mcpd relay \ --ingest-key $INGEST_KEY \ --upstream http://mcpd.eu.internal:4317 \ --upstream http://mcpd.us.internal:4317
릴레이
$ MCPD_UPSTREAMS=http://mcpd.eu.internal:4317,http://mcpd.us.internal:4317 mcpd --data /data/mcpd.db config | grep ^relayrelay           2 upstream(s) in order, http://mcpd.eu.internal:4317, http://mcpd.us.internal:4317; each sender's key passed on; spool at /data/mcpd.spool/relay, 1024 MiB$ curl -s -D - -o /dev/null localhost:4317/v1/ingest -H "content-type: application/json" -d @batch.json | grep -e ^HTTP -e mcpd-relayHTTP/1.1 202 Acceptedmcpd-relay: spooled$ curl -s localhost:4317/v1/ingest -H "content-type: application/json" -d @batch.json{"accepted":0,"duplicate":0,"rejected":0}

릴레이의 응답

프로브를 뺀 어느 경로로 오든 POST는 모두 받습니다. OTLP 경로인 /v1/traces, /v1/logs, /v1/metrics는 OTLP partialSuccess와 함께 200으로 응답하며, 이것이 OpenTelemetry 익스포터가 기대하는 응답입니다. 그 밖의 경로는 mcpd-relay: spooled 헤더와 {"accepted":0,"duplicate":0,"rejected":0} 본문으로 202를 응답합니다. 요청은 보관되어 있고 전달될 것이며, 실제 건수는 아직 그 요청을 보지 못한 업스트림의 몫입니다. 모든 SDK는 2xx를 성공으로 읽습니다.

릴레이는 무엇이든 쓰기 전에 --ingest-key를 직접 확인하고, --max-body-bytes와 --request-timeout-seconds를 데몬과 똑같이 적용합니다. 응답을 보내기 전에 요청은 이미 스풀 <spool-dir>/relay에 들어 있습니다.

전달과 장애 조치

워커 네 개가 스풀을 보냅니다. 요청은 --upstream 순서에서 쉬고 있지 않은 첫 번째 업스트림으로 갑니다. 재시도할 수 있는 실패가 나면 그 업스트림은 백오프와 지터에 따라, 또는 그 Retry-After가 말하는 동안 쉬고, 요청은 곧바로 다음 업스트림으로 갑니다. 쉬는 시간이 끝나면 다시 기본 업스트림부터 시도하므로, 트래픽은 저절로 그쪽으로 돌아갑니다.

400 같은 최종 거부는 다음 업스트림으로 보내지 않습니다. 다음 업스트림도 같은 바이트를 거부할 것이기 때문입니다. 요청은 스풀 디렉터리의 dead/로 옮겨지고 집계됩니다.

두 번 세지 않습니다

전달은 최소 한 번이고, 다시 보낸 것은 한 번만 저장됩니다. 모든 요청에는 Idempotency-Key 헤더가 붙습니다. 보낸 쪽이 직접 붙였으면 그 값이고, 아니면 relay- 뒤에 경로, 콘텐츠 인코딩, 본문의 다이제스트를 이은 값입니다. 데몬의 모든 수집 입구가 이 헤더를 따르며, 네이티브 배치 본문 안의 키가 있으면 그것이 헤더를 이깁니다. 릴레이가 타임아웃 뒤에 다시 보낸 요청이나, 기본 업스트림이 받았지만 응답을 잃어 보조 업스트림으로 보낸 요청은 알아보고 중복으로 보고됩니다.

키

--upstream-key를 주면 릴레이는 모든 업스트림에 그 키를 Bearer 토큰으로 제시합니다. 주지 않으면 보낸 쪽의 Authorization이나 x-mcpd-key 헤더를 스풀에 넣은 요청과 함께, 릴레이를 실행하는 사용자만 읽을 수 있는 파일에 보관했다가 그대로 넘깁니다. 두 번째 방식에서는 업스트림이 보는 프로젝트와 스코프가 보낸 쪽마다 그대로 유지됩니다.

배압과 레디니스

스풀의 크기는 --spool-max-bytes로 묶이며, 따로 정하지 않으면 릴레이는 1 GiB입니다. 가득 차면 요청은 503과 Retry-After: 5로 거부됩니다. 모든 SDK와 OpenTelemetry 익스포터가 이것을 재시도하므로, 릴레이가 데이터를 버리는 대신 보낸 쪽이 데이터를 들고 있게 됩니다.

/healthz는 언제나 200을 응답합니다. /readyz의 응답은 이렇습니다.

  • 닿을 수 있는 업스트림이 있으면 200 ok.
  • 지난 30초 동안 어느 업스트림도 자기 /readyz에 응답하지 않았고 전달도 받지 않았으면, detail과 함께 200 degraded. 업스트림은 5초마다 확인합니다.
  • 스풀이 가득 찼거나, 닿을 수 있는 업스트림이 없고 스풀이 80% 이상 찼으면 503.

그래서 로드 밸런서는 버퍼링 중인 릴레이에는 계속 보내고, 더는 받을 수 없는 릴레이에서는 트래픽을 옮깁니다.

릴레이 메트릭

메트릭유형의미
mcpd_relay_accepted_totalcounter스풀에 쓴 요청
mcpd_relay_refused_full_totalcounter스풀이 가득 차서 503으로 거부한 요청
mcpd_relay_failovers_totalcounter첫 번째가 아닌 업스트림으로 전달된 요청
mcpd_relay_dead_letter_totalcounter업스트림이 최종 거부해 dead/로 옮겨진 요청
mcpd_relay_spool_entriesgauge스풀에서 기다리는 요청
mcpd_relay_spool_bytesgauge스풀이 담고 있는 바이트
mcpd_relay_spool_oldest_secondsgauge기다리는 요청 중 가장 오래된 것의 나이, 또는 0
mcpd_relay_delivered_totalcounter업스트림이 받은 요청. upstream과 order 레이블이 붙습니다
mcpd_relay_failed_attempts_totalcounter업스트림이 받지 않은 시도. 레이블은 같습니다
mcpd_relay_upstream_upgauge업스트림이 지난 30초 안에 응답했으면 1, 아니면 0
mcpd_uptime_secondsgauge이 프로세스가 시작된 뒤 지난 초

mcpd_relay_failovers_total이 늘고 있다면 기본 업스트림이 실패하고 있고 보조 업스트림이 그 트래픽을 나르고 있다는 뜻입니다. mcpd_relay_spool_oldest_seconds는 전달이 얼마나 뒤처졌는지를 나타냅니다.

여러 리전

데몬 레플리카 여러 개를 리전 하나 또는 여럿에서 Postgres나 ClickHouse 저장소 하나에 붙여 실행하고, 실행은 Postgres에 두거나 (--runs-data postgres://...) 끄십시오. 내장 실행 저장소는 프로세스 하나에 속합니다. 각 레플리카의 /readyz는 이미 저장소에 닿을 수 있는지를 반영합니다. 리전마다 그 앞에 릴레이를 두고, --upstream에는 가장 가까운 데몬을 먼저, 다른 리전의 데몬을 두 번째로 나열하십시오.

레플리카가 둘 이상이 되면 네 가지 설정이 다르게 동작합니다.

  • 멱등성 키는 공유 저장소에 보관되므로, 다른 레플리카에 도착한 재전송도 알아봅니다. Postgres는 배치와 같은 트랜잭션에서 키를 기록합니다.
  • 분당 할당량 상한은 레플리카마다 따로 셉니다. 원하는 상한을 레플리카 수로 나누십시오.
  • 실시간 채점, 테일 샘플링, 모니터 알림은 한 번에 레플리카 하나에서만 돕니다. 레플리카들은 공유 저장소의 리스로 차례를 나눕니다. 리스를 쥔 레플리카는 처리할 때마다 리스를 갱신하고, 종료할 때 내려놓습니다. 그 레플리카가 멈추면 세 번의 처리 안에 다른 레플리카가 넘겨받습니다. 모든 레플리카가 자기 모니터와 목표를 평가하므로 어느 레플리카든 모니터 API에 답하고, 웹훅은 리스를 쥔 레플리카만 보냅니다. 모든 레플리카에 같은 설정을 두십시오.
  • 관점 분석은 그것이 설정된 모든 레플리카에서 돕니다. 레플리카 하나에만 설정하십시오.

배포 예제

deploy/docker/docker-compose.multi-region.yml은 머신 하나에서 Postgres, 데몬 두 개, 릴레이 하나를 시작합니다. 전체 구성을 직접 시험해 볼 수 있는 형태입니다.

Helm 차트는 mode: relay를 받습니다. deploy/helm/examples/ 아래의 values 파일 세 개가 각각 리전 하나를 기술합니다. region-core.yaml, region-standby.yaml, 그리고 릴레이만 도는 리전을 위한 region-edge-relay.yaml입니다.

다음

  • 데이터를 다른 벤더로 복사하기: 전달.
  • 프로브, 메트릭, 저장소: 운영하기.
  • 모든 플래그: 설정.