콘텐츠로 이동

Dataway 꼬리 샘플링


기능

Dataway는 꼬리 샘플링 기능을 제공하며, 외부 인터페이스는 다음과 같습니다.

  • /v1/tail_sampling(raw payload; Datakit 2.10의 헤더 없는 zstd payload와 호환)
  • /v1/tail_sampling_v2(이전 raw 호환 경로)
  • /v2/tail_sampling(zstd payload)
  • /v1/tail_sampling_config

꼬리 샘플링은 먼저 Dataway 측에서 그룹별로 패킹된 데이터를 수신한 다음, 샘플링 규칙에 따라 보관 또는 폐기 여부를 결정하고, 최종적으로 보관된 데이터를 중앙으로 전송합니다.

현재 지원되는 데이터 유형은 세 가지입니다.

  • tracing
  • logging
  • rum

기본 처리 흐름은 다음과 같습니다.

sequenceDiagram
autonumber

participant dk as Datakit/Client
participant dw as Dataway
participant ts as TailSamplingProcessor
participant kodo as Kodo

dk ->> dw: POST /v2/tail_sampling(zstd) 또는 /v1/tail_sampling(raw)
alt config ready
    dw ->> ts: ingest packet
    ts ->> dw: kept packets
    dw ->> kodo: write tracing/logging/rum
else config not ready
    dw ->> dw: pending cache
    dw -->> dk: 412 Precondition Failed
    dk ->> dw: POST /v1/tail_sampling_config
    dw ->> ts: update config and drain pending
end

작업 모드

꼬리 샘플링과 집계는 동일한 모드 구성을 공유합니다.

  • standalone
  • proxy

standalone

standalone 모드에서는 현재 Dataway가 꼬리 샘플링 데이터를 직접 처리합니다.

  • protobuf로 인코딩된 aggregate.DataPacket 수신
  • token + data_type을 기준으로 꼬리 샘플링 구성 조회
  • 구성이 준비된 경우 TailSamplingProcessor에 직접 전송
  • 주기적으로 만료된 그룹을 가져와 해당 데이터 유형 쓰기 인터페이스로 전송

현재 구현에서:

  • 샘플링 윈도우 진행 주기는 1초
  • 파생 메트릭 새로고침 주기는 1분
  • 전송 단계에서는 worker pool을 사용하여 비동기로 기록

proxy

proxy 모드에서는 현재 Dataway가 로컬 꼬리 샘플링 상태를 유지하지 않습니다.

  • /v1/tail_sampling, /v1/tail_sampling_v2, /v2/tail_sampling은 백엔드 노드로 전달
  • /v1/tail_sampling_config는 모든 백엔드 노드에 브로드캐스트

따라서 proxy 모드에서는:

  • aggregator_endpoint를 반드시 구성해야 함
  • 클라이언트는 유효한 Guance-Pick-Key를 전달해야 함
  • 백엔드 노드가 실제 샘플링 및 상태 유지를 담당
Warning

Kubernetes 배포에서 프런트엔드 Dataway가 꼬리 샘플링 요청을 특정 백엔드 노드에 안정적으로 전달해야 하는 경우, aggregator_endpoint에는 변경되지 않는 안정적인 백엔드 주소를 입력해야 합니다. 이 경우 백엔드 Dataway는 StatefulSet으로 배포하여 Pod 주소와 DNS 이름이 안정적으로 유지되도록 하는 것이 좋습니다. 이를 통해 프런트엔드 Dataway가 고정적으로 전달할 수 있습니다.

로컬 구성

Dataway 로컬에는 별도의 꼬리 샘플링 YAML 구성 항목이 없습니다. 꼬리 샘플링은 집계와 동일한 모드 구성을 사용합니다.

aggregator_mode: standalone
aggregator_endpoint:
  - http://dataway-0:9528
  - http://dataway-1:9528

환경 변수:

DW_AGGREGATOR_MODE=standalone
DW_AGGREGATOR_ENDPOINTS=http://dataway-0:9528,http://dataway-1:9528

설명:

  • standalone: 현재 노드가 꼬리 샘플링 상태를 직접 보유
  • proxy: 현재 노드는 전달 또는 브로드캐스트만 수행

Kubernetes에서 프런트엔드 Dataway가 진입 계층 역할을 하고 백엔드 Dataway가 실제 꼬리 샘플링을 담당하는 경우, 백엔드 노드는 StatefulSet을 사용하여 배포하고 StatefulSet Pod의 안정적인 주소를 aggregator_endpoint에 작성하는 것이 적합합니다.

샘플링 구성 전달

꼬리 샘플링 규칙은 dataway.yaml에 작성하는 것이 아니라 인터페이스를 통해 전달됩니다.

POST /v1/tail_sampling_config

요청 본문은 JSON이며, 최상위 구조는 다음과 같습니다.

{
  "version": 1,
  "trace": {},
  "logging": {},
  "rum": {}
}

여기서:

  • trace는 tracing 꼬리 샘플링 구성에 해당
  • logging은 logging 꼬리 샘플링 구성에 해당
  • rum은 rum 꼬리 샘플링 구성에 해당

tracing 구성 예시

{
  "version": 1,
  "trace": {
    "version": 1,
    "data_ttl": "5m",
    "group_key": "trace_id",
    "pipelines": [
      {
        "name": "keep-all",
        "type": "probabilistic",
        "rate": 1
      }
    ],
    "builtin_metrics": [
      {
        "name": "trace_total_count",
        "enabled": true
      }
    ]
  }
}

설명:

  • trace.group_key는 현재 trace_id만 가능
  • trace.data_ttl이 비어 있으면 기본값 5m
  • pipelines는 condition과 probabilistic을 지원
  • condition은 action=keep/drop 사용
  • probabilistic은 rate=0~1 사용

logging 구성 예시

{
  "version": 1,
  "logging": {
    "version": 1,
    "data_ttl": "1m",
    "group_dimensions": [
      {
        "group_key": "service",
        "pipelines": [
          {
            "name": "keep-all",
            "type": "probabilistic",
            "rate": 1
          }
        ]
      }
    ]
  }
}

rum 구성 예시

{
  "version": 1,
  "rum": {
    "version": 1,
    "data_ttl": "1m",
    "group_dimensions": [
      {
        "group_key": "session_id",
        "pipelines": [
          {
            "name": "keep-all",
            "type": "probabilistic",
            "rate": 1
          }
        ]
      }
    ]
  }
}
Info

logging과 rum은 group_dimensions를 사용하여 그룹화 차원을 구성합니다. data_ttl이 비어 있으면 기본값은 모두 1m입니다.

Warning

현재 구현에서는 구성 내용을 검증합니다. trace는 group_key=trace_id만 허용합니다. derived_metrics는 아직 지원되지 않으며, 구성 시 오류가 반환됩니다.

데이터 전송 API

꼬리 샘플링 데이터 인터페이스:

POST /v1/tail_sampling
POST /v1/tail_sampling_v2
POST /v2/tail_sampling

설명:

  • /v1/tail_sampling은 압축되지 않은 PBPoints payload를 수신합니다. 또한 Datakit 2.10에서 전송하는 압축 협상 헤더 없음, PayloadCompression=1인 zstd packet만 호환합니다.
  • /v1/tail_sampling_v2는 이전 raw 호환 경로이며, /v1/tail_sampling과 동일한 처리 로직을 사용합니다. zstd 프로토콜 경로가 아닙니다.
  • /v2/tail_sampling은 zstd payload만 수신합니다. 요청은 다음 조건을 모두 충족해야 합니다.
  • header Guance-Tail-Sampling-Payload-Compression: zstd
  • aggregate.DataPacket.PayloadCompression=1
  • standalone 모드에서는 요청 본문이 protobuf로 인코딩된 aggregate.DataPacket이어야 합니다.
  • proxy 모드에서는 요청이 백엔드 노드로 전달됩니다.

클라이언트는 다음 프로토콜 조합을 사용해야 합니다.

클라이언트 시나리오 요청 경로 압축 협상 header PayloadCompression payload
Datakit 2.10 이전 버전 /v1/tail_sampling 없음 0 raw PBPoints
Datakit 2.10 호환 경로 /v1/tail_sampling 없음 1 zstd PBPoints
Datakit 2.11 이상 기본 경로 /v2/tail_sampling zstd 1 zstd PBPoints
Datakit 2.11 이상 다운그레이드 경로 /v1/tail_sampling 없음 0 raw PBPoints

일반적인 응답 상태 코드:

상태 코드 의미
200 packet이 수신됨
400 protobuf, PBPoints 또는 packet 필드가 유효하지 않음
412 해당 샘플링 구성이 아직 준비되지 않았지만, packet이 pending cache에 입력됨
413 요청 본문이 Dataway 구성의 크기 제한을 초과함
415 압축 방법이 지원되지 않거나, 경로, header 및 packet 압축 필드가 일치하지 않음
503 pending cache가 가득 차서 packet이 수신되지 않음

압축 프로토콜과 롤링 업그레이드

Datakit 2.11 이상은 기본적으로 /v2/tail_sampling을 통해 zstd payload를 전송합니다. Dataway는 경로, header 및 packet 압축 필드를 명시적으로 검증합니다.

  • 이전 버전 Dataway는 /v2/tail_sampling을 인식하지 못하며 404를 반환
  • 새 버전 Dataway가 지원되지 않는 압축 방법, 헤더 누락, raw v2 packet 또는 Datakit 2.10 호환 조합에 속하지 않는 v1 zstd packet을 수신하면 415 Unsupported Media Type 반환
  • Datakit이 404 또는 415를 수신하면 현재 packet을 raw로 되돌리고 /v1/tail_sampling을 사용하여 재시도하며, 해당 endpoint의 legacy 기능을 10분간 캐시
  • 다운그레이드 전송 전에 Datakit은 압축 해제된 protobuf 본문 크기로 패킷을 분할하여, 분할 가능한 각 raw packet이 Dataway의 MaxRawBodySize를 초과하지 않도록 보장하여 높은 압축률의 packet이 이전 노드에서 413으로 거부되는 것을 방지
  • Datakit 2.10은 zstd packet을 /v1/tail_sampling으로 직접 전송하고 협상 헤더를 포함하지 않습니다. 새 버전 Dataway는 이 출시 버전과의 정확한 호환성을 유지
  • 2.10 미만 Datakit은 raw v1 데이터를 계속 전송합니다. 새 버전 Dataway는 span 조건자를 추가로 계산하고 시간 휠에 진입하기 전에 수익에 따라 압축 여부를 결정

위의 양방향 호환성을 확보한 후, Datakit 2.11+와 새 버전 Dataway로 업그레이드할 때 혼합 롤링이 가능합니다. Datakit 2.10과 이 호환성을 지원하지 않는 이전 버전 Dataway는 여전히 호환되지 않으므로, 먼저 한쪽 끝을 호환 로직이 포함된 버전으로 업그레이드해야 합니다.

Kept 패킷 전송 및 종료 복구

Dataway는 보관하기로 결정된 packet에 대해 유계 worker pool과 디스크 오버플로우 큐를 사용하여 전송합니다.

  • 전송 실패 시 최대 3회 백오프 재시도; 재시도 소진 시 failure/drop에计入
  • 메모리 큐가 가득 차면 먼저 비동기 overflow 채널로 들어간 다음 디스크 큐에 기록; Dataway 재시작 시 기존 큐를 열어 계속 전송
  • 프로세스 종료 시 overflow, 메모리 큐 및 백오프 중인 packet은 우선적으로 정상 디스크에 기록
  • 디스크를 사용할 수 없는 경우, 종료 단계의 네트워크 폴백 재시도는 5초 예산을 공유; 예산이 소진된 packet은 명시적으로 실패 지표에 포함되고 요약 로그가 출력

412와 Pending Cache

standalone 모드에서 Dataway가 막 시작되었거나 해당 token + data_type의 샘플링 구성이 아직 전달되지 않은 경우:

  • Dataway는 먼저 이 데이터를 로컬 pending cache에 저장
  • 그런 다음 412 Precondition Failed를 반환

현재 동작:

  • pending cache는 메모리 캐시
  • token + data_type별로 임시 저장
  • 구성이 성공적으로 전달되면 자동으로 사용 가능한 데이터를 TailSamplingProcessor로 드레인
  • 현재 기본적으로 최대 100000개의 packet을 캐시

약속된 동작:

  • 클라이언트는 412를 수신하면 이 데이터가 Dataway에 의해 수신된 것으로 간주
  • 클라이언트는 /v1/tail_sampling_config를 계속 전송하기만 하면 됨
  • 클라이언트는 이 데이터를 다시 전송할 필요 없음

예외 상황:

  • pending cache가 가득 차면 Dataway는 503을 반환
  • 이 경우 요청이 수신된 것으로 간주할 수 없음

꼬리 샘플링 메저먼트(tail_sampling)

꼬리 샘플링 구성은 builtin_metrics를 지원합니다. 이 메트릭은 꼬리 샘플링 프로세서가 샘플링 과정에서 생성하고, 주기적인 새로고침 시 중앙에 기록됩니다. 중앙에 기록된 후 메저먼트 이름은 tail_sampling입니다. 예를 들어 Guance에서 field trace_dropped_count, tag stage/decision/data_type을 조회할 수 있습니다.

현재 내장 메트릭은 다음과 같습니다.

tracing

  • trace_total_count
  • trace_kept_count
  • trace_dropped_count
  • trace_error_count
  • span_total_count
  • trace_duration

여기서:

  • trace_duration은 지속 시간 분포 메트릭
  • 나머지는 카운트 메트릭

logging

  • logging_total_count
  • logging_error_count
  • logging_kept_count
  • logging_dropped_count

rum

  • rum_total_count
  • rum_kept_count
  • rum_dropped_count

설명:

  • builtin_metrics가 비어 있으면 현재 기본적으로 해당 데이터 유형이 지원하는 모든 내장 메트릭이 활성화
  • 이 메트릭은 꼬리 샘플링 처리 과정 자체에서 비롯된 것이며, Dataway 자체의 실행 메트릭이 아님

Dataway 자동 전송 메트릭(메저먼트 dataway_aggregate)

샘플러 자체의 builtin_metrics(tail_sampling 메저먼트에 기록) 외에도 apis/metrics_special.go는 꼬리 샘플링 API의 처리 상황을 설명하는 Dataway 자체 관측 메트릭 세트를 자동으로 유지 관리합니다. 이 메트릭 세트는 집계되어 중앙의 dataway_aggregate 메저먼트에 들어가며, 필드 접두사는 dataway_http_tail_sampling_*입니다.

현재 꼬리 샘플링과 관련된 메트릭은 다음과 같습니다.

메트릭 이름 유형 태그 설명
dataway_http_api_body_size_bytes_total Counter api, token 꼬리 샘플링 인터페이스 요청 본문 누적 바이트 수
dataway_http_tail_sampling_trace_total Counter token 수신된 tracing 그룹 수
dataway_http_tail_sampling_span_total Counter token 수신된 tracing span 총 수
dataway_http_tail_sampling_packet_stage_total Counter token, data_type, stage, result 각 단계별 그룹 수(receive/ingest/decision/submit/kodo)
dataway_http_tail_sampling_point_stage_total Counter token, data_type, stage, result 각 단계별 포인트 수
dataway_http_tail_sampling_rule_packet_total Counter token, data_type, rule_name, rule_index, rule_type, action, result 일치한 샘플링 규칙별 그룹 수
dataway_http_tail_sampling_rule_point_total Counter 동일 규칙별 포인트 수
dataway_http_tail_sampling_packet_send_total Counter token, data_type, result 전송 결과 통계, result에는 success, failure, drop 포함
dataway_http_tail_sampling_submit_queue_event_total Counter token, data_type, result 제출 큐 진입 결과(memory/wait/overflow/disk/drop/closed)
dataway_http_tail_sampling_submit_queue_depth Gauge - 제출 큐 현재 깊이(백로그)
dataway_http_tail_sampling_submit_queue_capacity Gauge - 제출 큐 용량
dataway_http_tail_sampling_submit_worker_total Gauge - 현재 worker 수
dataway_http_tail_sampling_submit_worker_busy Gauge - 현재 바쁜 worker 수
dataway_http_tail_sampling_submit_disk_depth Gauge - 디스크 오버플로우 큐 깊이
dataway_http_tail_sampling_submit_queue_wait_seconds Summary source 제출 큐 대기 시간(source: memory/wait/overflow/disk)

이 메트릭은:

  • 1분마다 수집
  • dataway_aggregate 메트릭 포인트로 변환
  • Dataway 기본 token을 사용하여 /v1/write/metric으로 전송
  • 전송 후 현재 누적값 재설정
  • 메트릭의 token 태그는 redacted로 고정되며, 원본 token의 어떤 조각도 유지되지 않음

이 메트릭 세트는 Dataway 자체가 꼬리 샘플링 트래픽을 처리하는 실행 상태를 반영하며, 샘플링 규칙 자체의 비즈니스 통계가 아닙니다.

두 중앙 메저먼트의 역할 구분:

  • tail_sampling: 샘플링 규칙의 비즈니스 통계(token별), 예: trace_kept_count / trace_dropped_count
  • dataway_aggregate: Dataway 처리 과정의 실행 상태(Dataway 기본 token으로 집계), 예: 각 단계별 카운트, 전송/백로그, worker 상태

문서 평가

이 페이지가 도움이 되었나요?