---
title: "dial9 — Tokio 런타임의 블랙박스 레코더, 프로덕션에서 5% 미만 오버헤드로 이벤트 타임라인 기록"
published: 2026-03-19T23:34:23.000Z
canonical: https://jeff.news/article/739
---
# dial9 — Tokio 런타임의 블랙박스 레코더, 프로덕션에서 5% 미만 오버헤드로 이벤트 타임라인 기록

Tokio 런타임의 개별 이벤트를 타임라인 로그로 기록하는 텔레메트리 도구 dial9이 공개됨. 커널 스케줄링 딜레이, fd_table 컨텐션 등 집계 메트릭으로는 찾을 수 없는 프로덕션 성능 문제를 실제로 해결한 사례를 소개.

## dial9: Tokio 런타임의 블랙박스 레코더가 나왔음

- Tokio용 런타임 텔레메트리 도구 dial9이 공개됨. 핵심은 기존의 집계 메트릭(aggregate metrics)이 아니라 **개별 poll, park, wake 이벤트를 타임라인 로그로 기록**한다는 점
- Tokio 런타임 이벤트 + 애플리케이션 span/로그 + Linux 커널 이벤트를 통합해서, 앱 ↔ Tokio ↔ OS 간 상호작용의 전체 그림을 보여줌

## 탄생 배경: 프로덕션에서만 재현되는 성능 문제

- 수천 개의 호스트에 동시 연결하는 Rust 서비스에서 CPU 90% 넘어가면 성능이 급락하는 문제가 있었음. CPU 여유는 있는데 왜 느려지는지 알 수 없었음
- Tokio 런타임 메트릭을 보면 워커는 유휴 상태인데 큐는 가득 차 있는 모순적 상황
- dial9을 붙여보니 원인이 바로 보였음: **10ms 이상의 커널 스케줄링 딜레이**가 빈번하게 발생하고 있었음. 5-10ms 레이턴시를 유지해야 하는 서비스에서 이건 치명적

## 실제 프로덕션 디버깅 사례들

- **커널 스케줄링 딜레이 감지**: 워커 47을 깨우려고 했는데 커널이 실제로 스케줄링하기까지 18ms 걸림. 그 동안 트래픽을 단일 워커가 처리하고 있었음
- **fd_table 컨텐션 발견**: 서비스 시작 시 대량의 동시 연결을 열 때 fd_table 리사이징에 락이 걸려서 100ms+ poll이 발생. 집계 메트릭만으로는 절대 못 찾는 유형의 문제
- **태스크가 워커 사이를 계속 옮겨다니는 현상**: I/O 드라이버 특성상 소켓 대기 후 다음에 픽업하는 워커가 사실상 랜덤임. 2ms 동안 하나의 태스크가 5개 워커를 옮겨다니는 걸 실제로 시각화해서 보여줌. runtime-per-core 아키텍처가 데이터 집약 앱에 유리한 이유를 직관적으로 보여주는 사례

> [!IMPORTANT]
> dial9으로 dial9 자체의 버그를 발견한 에피소드가 있음. backtrace::trace에 **글로벌 락**이 있어서 태스크 덤프 기능을 켜면 오버헤드가 5% → 50%로 뛰었고, 워커 수가 늘수록 악화됨. 모든 워커가 하나의 뮤텍스에서 대기하고 있었던 거임.

## 바로 써볼 수 있음

- `cargo add dial9-tokio-telemetry`로 설치하고, `TracedRuntime`으로 런타임을 감싸면 끝
- `RotatingWriter`가 디스크 사용량을 제한해줘서 프로덕션에 그냥 켜둘 수 있음. S3 직접 쓰기도 지원
- **오버헤드는 보통 5% 미만**이라고 함. 이미 AWS 내부 팀들이 프로덕션에서 사용 중

> [!TIP]
> 트레이스 뷰어가 웹으로 제공되고, 데모 트레이스도 있으니 설치 전에 먼저 확인해볼 수 있음. TokioConf에서 라이트닝 토크도 예정돼 있음.

## 핵심 포인트

- Tokio 런타임 이벤트 + 앱 span + Linux 커널 이벤트를 통합 타임라인으로 기록
- 프로덕션 오버헤드 5% 미만, AWS 팀에서 이미 사용 중
- 커널 스케줄링 딜레이 18ms, fd_table 락 컨텐션 100ms+ 등 실제 디버깅 사례 제시
- backtrace::trace의 글로벌 락 문제를 dial9 자체로 발견한 에피소드

## 인사이트

집계 메트릭의 한계를 넘어서는 이벤트 레벨 텔레메트리가 비동기 런타임 디버깅의 새 표준이 될 수 있음
