{"id":"IL-0488","org":"Kit","date":"2022-12-24","docs":[],"title":{"en":"Kit's RDS MySQL write latency rose 100x and running threads jumped from 9 to 900, backing up Sidekiq job queues","ko":"EBS 성능 저하 뒤 Kit의 RDS MySQL 쓰기 지연이 100배 넘게 늘어 Sidekiq 작업 처리가 느려졌다"},"domain":["database","aws"],"impact":{"scope":"Kit's RDS MySQL primary and the Sidekiq job processing that depends on it slowed for several hours; the service never stopped","users":"unknown","region":"us-east-2 (use2-az1)"},"review":{"written_by":"session","reviewed_at":null,"reviewed_by":null},"lessons":{"en":"Multi-AZ RDS keeps data consistent and durable, but synchronous replication means each write also waits for the standby, so a degraded EBS volume on the standby while it is being replaced slows writes on the primary. Large databases recover more slowly from such events than small ones. A single-AZ instance would not have been hit by a standby problem, but would have suffered hours of downtime if its own zone failed, and that trade-off has to be weighed when deploying production RDS instances.","ko":"AWS Multi-AZ는 동기 복제로 데이터 정합성과 내구성을 지키지만, 모든 트랜잭션을 스탠바이에도 커밋해야 하므로 스탠바이의 EBS 볼륨이 나빠지면 쓰기 지연도 나빠진다. 데이터베이스가 클수록 이런 일에서 회복이 오래 걸린다. 단일 AZ였다면 이번 일은 영향이 없었겠지만, 영향을 받은 가용 영역에 서버가 있었다면 몇 시간 동안 멈췄을 것이다. 운영 RDS의 배치 방식을 정할 때는 이런 득실을 따져야 한다. RDS와 EBS가 어떻게 동작하고 Kit에 어떤 영향을 주는지 이해하는 것이 중요했다."},"related":[],"sources":[{"url":"https://engineering.kit.com/2023/07/31/the-effect-of-database-write-latency-on-performance/","kind":"blog","archived":"https://web.archive.org/web/20260124113056/https://engineering.kit.com/2023/07/31/the-effect-of-database-write-latency-on-performance/"}],"summary":{"en":"Kit runs MySQL on Amazon RDS in High Availability (Multi-AZ) in us-east-2; as of July 2023 the database was 13.75 TB on a db.r6g.16xlarge instance. In Multi-AZ, replication to the standby is synchronous, so every transaction commits on the standby as well as the active instance. After an EBS interruption on the standby, AWS ran a replaceSecondaryHostAndVolumesTask: a snapshot of the primary was restored onto new secondary volumes. Those volumes had a \"first touch penalty\", and while the secondary synced with the primary, write I/O latency rose from 1-2 ms to 140 ms around 09:30 UTC. AWS recorded WriteLatency as raised between 09:34 and 14:56 UTC.\n\nSlow writes held up Kit's Sidekiq jobs, queues grew and Redis memory filled. The manual failover requested at about 13:30 UTC timed out, because a failover does not happen while the secondary is not in sync, and the secondary was not in sync until 14:59:35 UTC. At about 14:30 UTC Kit scaled the RDS storage by 10%, from 12,500 GB to 13,750 GB, which took the instance through the \"optimizing storage\" state in which AWS moves EBS volumes. By about 15:05 UTC write latency was back to 1-2 ms; jobs drained, Redis memory returned to safe levels, and the service had stayed up throughout, only slower.","ko":"Kit은 AWS us-east-2 리전의 RDS에서 MySQL을 Multi-AZ 고가용성 구성으로 운영한다. 2023년 7월 기준으로 크기는 13.75TB, 인스턴스는 db.r6g.16xlarge다. 2022-12-23 오후 9시 50분 EST에 AWS RSS 피드가 use2-az1 가용 영역의 EC2와 EBS 성능 저하를 알렸고, MySQL 프라이머리가 그 가용 영역에 있었다. AWS가 24분 만에 해결됐다고 표시했고 서버를 여러 가용 영역에 두고 있어 팀은 크게 신경 쓰지 않았다.\n\n다음 날 오전 5시 20분 EST에 MySQL 실행 중 스레드가 9에서 900으로 뛰었다는 호출이 왔다. 당번 엔지니어는 먼저 가장 많이 밀린 Sidekiq 큐를 살폈지만 원인을 찾지 못했고, 더 파고들어 RDS 쓰기 지연이 약 1.5ms에서 150~300ms로 늘어난 것을 찾았다. 쓰기가 느려 Sidekiq 작업 처리가 늦어졌고, 큐가 밀리면서 redis 메모리가 빠르게 차올랐다. 오전 8시 33분 EST의 장애 조치 시도는 세컨더리가 동기화되지 않은 상태여서 타임아웃으로 실패했다.\n\n팀은 RDS가 EBS 위에서 돈다는 점에서 전날의 EBS 성능 저하가 원인이라고 판단했다. AWS가 보낸 포스트모템에 따르면 2022-12-24 02:12:47 UTC에 LSE라고 적힌 사건이 일어나 replaceSecondaryHostAndVolumesTask가 돌았고, 이 작업이 스탠바이 볼륨을 프라이머리 스냅숏으로 다시 만들었다. 새 볼륨의 first touch penalty 때문에 쓰기 I/O 지연이 1~2ms에서 140ms로 늘었다. 스토리지를 12.5TB에서 13.75TB로 10% 늘리자 RDS가 optimizing storage 상태를 거치며 쓰기 지연이 1~2ms로 돌아왔고, AWS 기록으로는 15:05 UTC 무렵 안정됐다. 그 뒤 큐가 비고 redis 메모리도 안전한 수준으로 돌아왔다. 서비스는 느려졌지만 멈추지는 않았다."},"trigger":{"en":"An EBS interruption on the standby of the Multi-AZ RDS instance, reported by AWS as an LSE at 02:12:47 UTC on 2022-12-24, started a replaceSecondaryHostAndVolumesTask that replaced the secondary host and volumes.","ko":"스탠바이 서버의 EBS 중단으로 RDS가 replaceSecondaryHostAndVolumesTask를 실행해 스탠바이의 호스트와 볼륨을 교체했다. 새 볼륨은 프라이머리 볼륨의 스냅숏으로 다시 만들어져 AWS가 first touch penalty라고 부른 쓰기 지연이 있었고, 동기 복제 때문에 프라이머리의 쓰기 지연이 함께 늘었다."},"severity":"unknown","symptoms":["database-overloaded","throughput-degraded"],"timeline":{"detected_after":"46m","resolved_after":"5h 22m"},"date_kind":"incident","detection":{"en":"A page fired at 5:20 am EST because MySQL threads running jumped from 9 to 900. An AWS RSS feed alert in Slack about degraded EC2 and EBS in use2-az1 had arrived the evening before and was not acted on.","ko":"2022-12-24 오전 5시 20분 EST에 MySQL 실행 중 스레드 수 급증 알림이 당번 엔지니어를 호출했다. 원인이 된 EBS 성능 저하는 전날 밤 AWS RSS 피드 알림으로 Slack에 들어왔지만 그때는 넘어갔다."},"components":["database","block-storage","database-replication"],"root_cause":"cloud-provider","remediation":[{"text":{"en":"Scaled the RDS storage from 12.5 TB to 13.75 TB, which put the instance through \"optimizing storage\" and brought write latency back to 1-2 ms","ko":"RDS 인스턴스의 스토리지를 12.5TB에서 13.75TB로 늘렸다. 이 과정에서 RDS가 optimizing storage 상태를 거치며 EBS 볼륨을 옮겼고, 쓰기 지연이 1~2ms로 돌아왔다."}}],"action_items":[],"contributing":["early-signal-ignored"],"recurrence_of":null,"symptoms_text":{"en":"At 5:20 am EST on December 24, 2022, Kit's infrastructure team got its first page because the number of MySQL threads running on its RDS MySQL primary in us-east-2 had jumped 100x, from 9 to 900, at a time of day when Kit's traffic is very low. Sidekiq queues were backing up.\n\nKit processes about 5 billion Sidekiq jobs a month, and most of them touch MySQL, so the first suspicion was newly shipped code hurting one queue. The engineer started with the queue that was backed up more than any other and found nothing there. Digging further showed that RDS MySQL write latency had risen more than 100x, from about 1.5 ms to about 150 ms and up to 300 ms, and that slow writes were holding back job processing.\n\nThe backlog became urgent because Sidekiq is backed by Redis and limited by Redis memory: jobs were enqueued faster than they were processed, Redis memory was running out quickly, and a Redis crash would have lost the enqueued jobs. At 8:33 am EST the engineer tried to fail the database over to the standby, expecting some downtime, but the failover itself failed and writes stayed in the hundreds of milliseconds.\n\nThe night before, at 9:50 pm EST on December 23, an alert from the AWS RSS feed in Slack had reported degraded EC2 instances and EBS volumes in the use2-az1 availability zone, where the MySQL primary runs. The team paid little attention to it, because hosts in trouble can be replaced and AWS marked the event resolved after 24 minutes. Only later did the team connect the MySQL slowdown to that EBS degradation.","ko":"2022-12-24 오전 5시 20분 EST에 MySQL 실행 중 스레드 수가 9에서 900으로 100배 뛰었다는 첫 호출이 왔다. 크리스마스이브 새벽이라 트래픽이 아주 적은 시간이었다.\n\nSidekiq 큐가 밀리기 시작했고, 그중 한 큐가 다른 큐보다 훨씬 많이 밀려 있었다. Kit은 한 달에 Sidekiq 작업을 약 50억 개, 초당 약 2,000개 처리하고, 대부분의 작업이 MySQL을 쓴다.\n\nRDS MySQL의 쓰기 지연이 약 1.5ms에서 약 150ms로, 많게는 300ms까지 100배 넘게 늘어 있었다. AWS 내부 조사로는 WriteLatency가 2022-12-24 09:34 UTC부터 14:56 UTC까지 높았다.\n\n큐에 쌓인 작업이 Sidekiq이 쓰는 redis의 메모리를 빠르게 채웠다. 작업을 넣는 속도가 처리 속도보다 빠르면 redis가 메모리 부족으로 죽고 쌓인 작업을 잃게 되는 상황이었다.\n\n처음에는 새로 배포한 코드가 큐 하나에 나쁜 영향을 줬다고 보고 가장 많이 밀린 큐를 살폈지만, 그 큐에서는 원인이 될 만한 것을 찾지 못했다. 전날 밤 9시 50분 EST에 AWS RSS 피드가 use2-az1 가용 영역의 EC2 인스턴스와 EBS 볼륨 성능 저하를 Slack으로 알렸고 MySQL 프라이머리가 그 가용 영역에 있었지만, AWS가 24분 만에 해결됐다고 표시해 팀은 넘어갔다.\n\n오전 8시 33분 EST에 스탠바이로 장애 조치를 시도했지만 실패해 데이터베이스는 원래 인스턴스에 그대로 남았고, 쓰기 지연은 수백 ms에 머물렀다. AWS 조사에 따르면 세컨더리가 프라이머리와 동기화되지 않은 상태여서 장애 조치가 타임아웃됐다."},"updated_at":"2026-11-14T12:34:13.356068Z","url":"https://benchlet.com/incidentlib/app/cases/IL-0488","org_slug":"kit"}