본문으로 건너뛰기
0
r/jeffnews HN 약 4분

dial9 — Tokio 런타임의 블랙박스 레코더, 프로덕션에서 5% 미만 오버헤드로 이벤트 타임라인 기록

backend

요약

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 아키텍처가 데이터 집약 앱에 유리한 이유를 직관적으로 보여주는 사례

중요

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

바로 써볼 수 있음

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

💡

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

핵심 포인트

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

인사이트

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

댓글

댓글

댓글을 불러오는 중...

backend

Redis 8.0 출시 — I/O 스레딩 갈아엎고 처리량 3배, 2.1M ops/sec 달성

Redis 8.0이 I/O 스레딩 모델을 완전히 재설계해서 16코어 기준 2.1M ops/sec를 달성함 (7.4 대비 3배). Hash field expiration, Vector search HNSW, Client-side caching v2, Redis Functions 2.0 async 실행 등 굵직한 기능이 추가되고, jemalloc 통합으로 메모리 fragmentation도 25% 줄어듦.

backend

칩셋 레이턴시를 측정해봤더니 — 쓸모는 없지만 재밌는 실험

Vulkan GPU 벤치마크로 여러 세대 마더보드 칩셋의 PCIe 레이턴시를 측정한 실험. CPU 직결 대비 칩셋 경유 시 수백 ns 레이턴시가 추가되며, 의외로 2012년 Skylake Z170이 가장 낮은 추가 레이턴시를 보임.

backend

ForgeKV — Rust로 만든 멀티코어 Redis 대체제

Rust로 만든 Redis 드롭인 대체제. 64-샤드 잠금 아키텍처로 멀티코어 스케일링 지원. 2코어 환경에서 Redis 7 대비 41% 빠른 SET 처리량(158K ops/s). 고동시성에서는 약점 있음. Source-available 라이선스.

backend

AI 바이브 코딩에 Go를 쓰는 이유 — Rust도 Python도 아닌

AI가 코드의 90%를 쓰는 바이브 코딩 시대에 Go가 최적의 언어라는 주장. Python은 안전장치가 없고, Rust는 언어 자체의 문제까지 인간에게 떠넘기지만, Go는 중요한 것만 잡고 비켜준다는 논리. 실제로 한 세션에 3도메인 풀스택 블로그를 7커밋으로 완성한 사례 제시.

backend

rsloop: Rust로 만든 Python asyncio 이벤트 루프 (io_uring 지원)

PyO3 기반으로 Python asyncio 이벤트 루프를 Rust로 재구현한 rsloop. Linux에서 compio + io_uring을 사용하고, asyncio 호환 표면이 넓어 drop-in 교체가 가능하다. uvloop과는 다른 접근으로 이벤트 루프 성능을 노리는 프로젝트.