Incident Library

IL-0296 Transloadit · 2016-05-30 (게시일)databaseaws

Transloadit 의 us-east 리전 Redis 클러스터가 대역폭에 막혀 작업과 하트비트를 잃었다

Transloadit 의 Uploader 는 파일을 받아 Assembly 를 조율하고 Drone 은 인코딩 작업을 실행한다. 둘은 리전별 Redis 클러스터의 Job 대기열과 하트비트로 이어져 있다. WORKER_JOB_ERROR 가 늘었다는 신고가 들어오자 팀은 Twitter 와 transloaditstatus.com 에 알리고 조사했다. us-east 리전 Redis 클러스터에서 Job 과 하트비트가 사라지고 있었다. 먼저 잃은 메시지를 다시 넣고 하트비트 감시를 느슨하게 하는 임시 조치를 했다. 이 조치는 증상만 막을 뿐이었고 Assembly 실행 시간도 늘었다. 팀은 놓친 Redis 패치를 찾아 최신 안정 버전으로 올렸고, 클라이언트 라이브러리를 전부 점검했으며, 모니터링과 지표, 알림, 로그를 보강했다. 쓰던 Redis 버전에는 [FIX] Fixed data loss 로 표시된 버그를 포함해 여러 버그가 남아 있었고, 클라이언트 라이브러리에서는 문제를 찾지 못했다. 대역폭은 지켜보지 않았는데, 노드 세 대의 네트워크 카드가 모두 포화돼 있었다.

대역폭 제한에 걸린 것을 알고 클러스터를 여섯 대로 늘려 읽기 처리량이 약 6Gbit/s 가 되기를 기대했지만, 클러스터는 곧 다시 포화됐다. 세 대를 더 붙이자 더 나빠졌고, 리더 혼자 약 4Gbit/s 를 내보내고 있었다. 원인은 복제였다. 모든 쓰기가 리더로 가고, 리더는 쓴 데이터를 replica 둘이 아니라 여덟 대에 동기화해야 해서 일과 나가는 트래픽이 네 배가 됐다. 데이터는 쓰기가 많고 금방 쓸모가 없어지는 성격이라 복사한 뒤 곧 다시 지워야 했다. 잃은 데이터를 다시 넣을 수 있으니 팀은 복제가 꼭 필요한지 다시 따져 봤다. AWS ElastiCache 에서는 자동 장애 조치를 쓰려면 복제가 필수라서 읽기 replica 를 하나로 줄였다. 로그에서 트래픽과 실패율이 바로 떨어졌고 Assembly 도 다시 빨라졌다.

갑작스러운 포화를 설명할 코드나 인프라 변경은 찾지 못했지만, HLS 트래픽이 가파르게 늘었다. HLS 는 큰 영상을 작은 조각 여러 개로 나누기 때문에 영상 하나에 오가는 메타데이터가 천 배까지 늘 수 있다. 여기에 Drone 을 더 많이 띄울 수 있게 되면서 중앙 노드가 바빠졌고, 두 변화가 겹쳐 병목이 드러났다. 팀은 Redis 노드를 늘린 것이 잘못된 판단이었다고 밝혔다. 그사이 리전마다 Drone 확장에 상한을 두었고, 리전별 샤딩에 더해 Uploader 별 샤딩을 준비했다. 크게 영향받은 고객에게는 일주일 무료 서비스를 제안했다.

심각도
–
영향 범위
Job queueing and heartbeats between Uploaders and Drones in the us-east region; slower Assemblies and some that could not be replayed
영향 사용자
81 customers
지역
us-east
감지까지
–
복구까지
–

증상

WORKER_JOB_ERROR 오류가 늘었다는 신고가 들어왔다. 이 오류는 파일을 받아 Assembly 를 조율하는 Uploader 와 인코딩을 실행하는 Drone 사이의 통신에 문제가 있다는 뜻이다.

재시도 덕분에 Assembly 대부분은 데이터 손실 없이 다시 실행할 수 있었지만, 몇몇은 다시 실행되지 않았고 많은 Assembly 가 지수 백오프 재시도 때문에 훨씬 느려졌다. 고객 81곳이 영향을 받았다.

로그를 뒤지고 코드를 디버깅해 보니 us-east 리전 Redis 클러스터에 넣은 Job 이 사라지고 있었고, Uploader 와 Drone 사이의 하트비트도 사라지고 있었다. 시스템은 하트비트를 지켜보다가 Drone 이 하트비트를 멈추면 그 Job 을 다른 Drone 에 넘긴다.

Redis 명령 수, 연결 수, 스왑 사용량은 보고 있었지만 대역폭은 보지 않았다. 미국의 Redis 클러스터는 노드 세 대였고 그 네트워크 카드를 모두 채울 리 없다고 여겼지만, 실제로는 세 대 모두 대역폭이 가득 차 있었다.

클러스터를 여섯 대로 늘리자 대역폭 사용량은 바로 늘었지만 곧 다시 포화됐고 Assembly 는 여전히 느렸다. 세 대를 더 붙이자 상황이 더 나빠졌다. 바깥으로 나가는 트래픽 대부분을 클러스터 리더가 내보내고 있었고, 리더는 약 4Gbit/s 로 Amazon 이 안내하는 한도보다 많은 트래픽을 내보낸 반면 다른 노드의 트래픽은 한도 안에 있었다.

증상 오류율 상승지연 시간 증가부하 불균형

원인

촉발
HLS 트래픽이 가파르게 늘었고, 같은 양을 더 빨리 처리하려고 Drone 을 더 많이 띄울 수 있게 되면서 중앙 노드가 바빠졌다. 이를 설명할 코드나 인프라 변경은 찾지 못했고, 이 두 변화가 겹쳐 Redis 병목이 드러났다.

감지

WORKER_JOB_ERROR 오류가 늘었다는 신고가 들어와 문제를 알았다. 모니터링은 Redis 명령 수, 연결 수, 스왑 사용량을 보고 있었지만 대역폭은 보지 않아 포화를 잡지 못했다.

조치

후속 조치

교훈

Redis 노드를 늘린 것은 잘못된 판단이었다. 모든 쓰기를 리더 한 대가 받는 구조에서는 노드가 늘수록 리더가 복제로 내보낼 트래픽이 늘어, 더 많은 트래픽을 감당하려면 노드를 오히려 줄여야 했다. 잃은 데이터를 다시 넣을 수 있으므로 팀은 복제가 꼭 필요한지 다시 따져 봤다. 지표는 이미 많이 지켜보고 있었지만 알림을 제대로 걸 수 있는 지표는 몇 개뿐이어서, 고른 지표가 모자랐을 수 있다. 대역폭도 빠져 있었다. 쓰기를 받는 Redis 노드가 하나뿐이면 replica 를 줄이거나 노드를 키워도 시간을 조금 벌 뿐이고, 성장을 버티려면 트래픽을 나눠야 한다.

출처

관련 사례

내 클러스터에도 있는지 확인하기

kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이 사례와 같은 상태를 점검합니다. 이 사례의 구성 요소: 인메모리 캐시, 데이터베이스 복제. 점검 항목의 근거는 이 사례 같은 공개 보고서입니다.

AI 도구와 스크립트용

API 는 키가 필요 없습니다. MCP 서버는 search_incidents, get_incident, list_incidents, get_topic, vocab 도구를 내놓습니다. 사용법은 API 와 MCP.