Incident Library
적용된 필터 원인용량 한계증상데이터베이스 과부하기여 요인과도한 영향 범위모두 풀기검색어 없이 필터만 적용한 목록입니다. 최근 사례부터입니다.
추천 필터 검색하면 검색어에서 찾은 분류 값이 여기에 나옵니다.

그래프

  • 원인
  • 구성 요소
  • 증상
  • 기여 요인
  • 사례

사례4건

4건 중 1~4번째

  1. 증상

    2022년 3월 16일 14:09 UTC, 최대 부하 시간대에 mysql1 데이터베이스의 부하가 늘면서 데이터베이스 프록시가 최대 연결 수에 닿았다. GitHub 의 모든 쓰기 작업이 동작하지 않았다.

    촉발

    최대 부하 시간대에 공용 MySQL 클러스터 mysql1 의 부하가 늘어 데이터베이스 프록시가 최대 연결 수에 닿았다.

    원인
    구성 요소
    기여 요인
    조치
    • 정상인 복제본으로 페일오버해 3월 16일 장애에서 복구했다.
    • 3월 17일 미리 한 페일오버 뒤 새 주 노드에 생긴 연결 문제를 풀려고 연결을 재설정했다.
    • 3월 17일 장애 중에 부하 패턴을 찾아 인덱스를 추가해 주된 성능 문제를 고쳤다.
    • 3월 22일 클라이언트 연결이 실패하자 다시 주 노드를 페일오버해 복구했다.
    • 3월 23일 같은 부하 특성으로 클라이언트 연결이 실패하자 다시 주 노드를 페일오버해 복구했다.
    • 3월 23일 부하를 줄이려고 웹훅 트래픽을 제한했다.
    후속 조치
    • 다른 대책을 더 찾는 동안 최대 부하 시간대에 웹훅 트래픽 제한을 계속 써서 같은 장애가 다시 나지 않게 한다.
    • 최대 부하 시간대의 mysql1 부하 패턴을 점검하고, 그 결과에 따라 성능 수정을 차례로 한다.
    • 부하를 줄이고 페일오버 시간을 줄이려고 mysql1 의 트래픽을 다른 데이터베이스로 옮긴다.
    • 변경 관리 절차를 검토한다. 특히 운영 환경에 부하가 높을 때의 모니터링과 변경을 살핀다.
    • 플랫폼 성장에 맞춰 데이터베이스 샤딩과 하드웨어 확장을 비롯한 인프라 확장을 이어 간다.
  2. 증상

    2022년 1월 3일부터 17일까지 이어진 100% 할인 이벤트 기간에, 인프런은 1월 3일, 4일, 7일, 17일 오전 9시와 오후 10시 무렵마다 쓸 수 없을 만큼 느려졌다. 트래픽은 평소의 5~20배였고, 매번 데이터베이스의 슬로우 쿼리와 부하가 함께 나타났다.

    촉발

    2022년 1월 강의 125개를 0원에 등록할 수 있는 100% 할인 이벤트가 크게 퍼지면서 평소 대비 5~20배의 트래픽이 들어왔다.

    원인
    구성 요소
    기여 요인
    감지

    모니터링과 슬로우 쿼리 알람으로 문제를 알아챘고, 문제가 되는 쿼리를 30분 안에 찾았다. 1월 17일에는 오후 10시부터 RDS 의 여러 수치가 요동치는 것을 보았다.

    조치
    • 관심회사 조회 API 의 쿼리 일부가 인덱스를 쓰지 않는 것을 로그와 실행계획으로 확인하고 바로 인덱스를 추가했다.
    • 용량이 큰 캐시 행의 캐시 초기화와 재생성 주기를 바꿨다.
    • 쓰기 DB 에 부하를 준 조회용 쿼리부터 읽기 DB 로 옮겼다.
    • 시간을 벌려고 데이터베이스를 r5.8xlarge 8대로 늘렸다.
    • 느린 강의 조회 쿼리에 인덱스를 추가하거나 쿼리를 바꿔 인덱스를 쓰게 했고, 개선할 수 없는 쿼리를 쓰는 기능은 껐다.
    • select * 로 읽던 강의 조회 쿼리에서 실제로 쓰지 않는 고용량 강의 소개 컬럼을 모두 뺐다.
    • IN 절에 담는 강의 ID 를 20개씩 나눠 Promise.all 로 처리하게 바꿔, 쿼리가 다시 인덱스를 쓰게 했다.
    • PostgreSQL 을 10.16 에서 11.13 으로 올렸다.
    • 5초 넘게 도는 쿼리를 강제로 끝내도록 쿼리 타임아웃을 5초로 걸었다.
    • Max Connection 을 늘렸다.
    • 강의 테이블에 수동으로 vacuum 을 돌려 Dead Tuple 을 정리했다.
    • 용량이 큰 강의 소개 컬럼을 강의 테이블에서 떼어 별도 테이블로 옮겼다.
    후속 조치
    • 한 테이블의 장애가 전체 서비스의 장애로 번지는 구조를 개선한다.
    • 성능 개선이 쉽지 않은 테이블과 캐시 구조를 개선한다.
    • 직관적이지 않은 SQL 코드를 개선한다.
    • 타입과 테스트 코드가 없어 안심하고 고치기 어려운 코드를 개선한다.
    • 배치 작업을 안정적으로 돌릴 환경을 갖춘다.
    • 모놀리식 구조는 알맞은 선에서 유지하고, 장애가 잘 번지는 일부 도메인만 따로 분리한다.
    교훈

    그동안 데이터베이스 병목이 모두 읽기 DB 의 슬로우 쿼리로 보여 팀은 읽기 DB 만 모니터링했다. 이 때문에 근본 원인인 쓰기 DB 강의 테이블의 Dead Tuple 을 늦게 찾았다. 원인 쿼리는 빨리 찾았지만, 무분별한 쿼리 추상화와 타입과 테스트 코드가 없는 코드 때문에 수정과 배포가 늦어졌다. 그만큼 장애 시간도 길어졌다. 첫 주 장애를 돌아보면 어느 페이지가 문제가 될지 예상할 수 없었고, 대부분의 페이지가 트래픽이 몰리면 언제든 장애가 날 수 있는 상태였다. 팀은 조직의 구조와 성숙도가 갖춰지지 않은 상태에서 마이크로서비스 아키텍처인 MSA 로 바로 옮기면 더 큰 문제가 생긴다고 보았다. 그래서 모놀리식 구조를 알맞은 선에서 유지하면서 일부 도메인만 분리하기로 했다.

  3. 증상

    2:19am PDT 에 짧은 네트워크 장애가 있은 뒤 DynamoDB 고객 요청의 오류율이 치솟았다. 2:37am PDT 에는 오류율이 지난 3년 동안 겪은 어떤 수준보다 훨씬 높아졌고, 약 55% 에서 머물렀다.

    촉발

    2:19am PDT 의 짧은 네트워크 장애가 DynamoDB 스토리지 서버 일부에 영향을 줬고, 이 서버들이 한꺼번에 메타데이터 서비스에 멤버십 정보를 요청했다.

    원인
    구성 요소
    기여 요인
    감지

    주 문제를 해결한 뒤 남은 낮은 오류율은 월요일에 고객들이 테이블이 updating 이나 deleting 단계에 멈췄다거나 오류율이 높다는 지원 케이스를 열면서 드러났다.

    조치
    • 용량 추가가 여러 번 실패한 뒤 5:06am PDT 에 메타데이터 서비스로 가는 요청을 멈췄다. 재시도가 줄어 메타데이터 서비스의 부하가 크게 덜어졌다.
    • 메타데이터 서비스가 관리 요청에 다시 응답하자 용량을 크게 늘렸다.
    • 메타데이터 서비스로 가는 요청을 다시 열고 스토리지 서버를 고객 요청 경로에 되돌렸다. 7:10am PDT 에 대부분의 고객과 AWS 서비스가 정상 운영을 이어 갈 만큼 오류율이 내려갔다.
    • 받아야 할 만큼 트래픽을 받지 못하던 메타데이터 파티션 하나를 전체 트래픽으로 되돌려 남은 오류를 월요일에 정리했다.
    후속 조치
    • 메타데이터 서비스의 용량을 이미 크게 늘렸다.
    • 멤버십 크기 같은 성능 지표를 더 엄격하게 모니터링해 상태를 파악하고 알맞은 용량을 미리 계획한다.
    • 스토리지 노드가 멤버십 정보를 요청하는 빈도를 줄인다.
    • 메타데이터 서비스가 요청을 처리하는 데 쓸 수 있는 시간을 늘린다.
    • DynamoDB 서비스를 나눠 메타데이터 서비스 인스턴스를 여럿 두고, 각 인스턴스가 스토리지 서버의 일부만 맡게 한다.
    • SQS 의 메타데이터 캐싱을 고쳐 메타데이터 테이블에 오래 접근하지 못해도 메시지 보내기와 받기가 계속되게 한다.
    • Auto Scaling 서버들에 작업을 나누는 방식을 바꿔 쌓인 스케일링 작업을 더 병렬로 처리한다.
    • 더 새로운 작업으로 대체된 오래된 스케일링 작업을 걸러 내는 장치를 넣는다.
    • 스케일링 작업을 처리하는 용량을 늘린다.
    • CloudWatch 가 DynamoDB 의 그룹 멤버십 데이터를 캐싱하는 방식을 바꿔, 갱신이 필요한 지표를 가능한 한 적게 줄인다.
    • write-through 캐싱으로 지표를 더 빨리 전달하는 기능을 개발한다. 이 캐시는 지표를 저장하기 전에 바로 보여 준다.
    • 타임아웃을 줄인 콘솔 로그인 코드를 며칠 안에 배포한다. 이 코드는 이미 테스트 과정에 들어가 있다.
    교훈

    AWS 는 멤버십 크기처럼 성능에 영향을 주는 값을 자세히 보지 않아 메타데이터 서비스에 필요한 용량을 미리 잡지 못했다. 전체 오류율이 낮아도 일부 고객에게는 오류가 몰릴 수 있다. AWS 는 이를 늦게 알아채 월요일에 상태 대시보드 게시가 늦었다. 콘솔 로그인은 성공하지 않아도 되는 API 호출에 아주 긴 타임아웃이 걸려 수십 초씩 막혔다. 이런 호출은 빨리 실패하고 로그인을 이어 가게 했어야 했다.

  4. 증상

    6월 3일 PagerDuty 알림 파이프라인의 성능이 떨어져 일부 알림이 늦게 갔다. 통합 API 로 보낸 이벤트의 약 3% 를 받지 못했고, 1% 에 못 미치는 일부 알림이 늦게 전달됐다.

    촉발

    6월 3일 Cassandra 클러스터의 노드 하나에서 repair 작업이 평소대로 시작됐고, 그때 걸린 높은 부하와 겹쳤다. 6월 4일에는 팀이 전날 미룬 repair 작업을 손으로 다시 시작했다.

    원인
    구성 요소
    기여 요인
    조치
    • 6월 3일 Cassandra 클러스터의 부하를 줄였다.
    • 6월 3일 부하를 줄이면서 repair 작업을 멈췄다.
    • 클러스터를 안정시키려고 일부 노드 사이의 통신을 끊었고, 그 뒤 정상으로 돌아왔다.
    • 6월 4일 알림 파이프라인에서 처리 중이던 데이터를 모두 지웠고, Cassandra 가 바로 회복했다.
    • 새로 비운 상태와 데이터를 맞추도록 일부 하위 시스템을 수동으로 손봤다.
    후속 조치
    • 기존 Cassandra 노드를 더 크고 빠른 서버로 수직 확장한다. 6월 4일 이후 이 작업은 이미 끝냈다.
    • Cassandra 클러스터를 여러 개로 나누고 작업량을 그 클러스터들에 나눠 싣는다. 부하와 사용 방식에 따라 클러스터를 나누는 작업이 진행 중이다.
    • 시스템 부하 기준을 정해 그 기준에 닿으면 기존 Cassandra 클러스터를 미리 수평 확장한다.
    • 기존 클러스터와 새 클러스터를 더 최근 버전의 Cassandra 로 업그레이드한다.
    • 높은 부하에서도 Cassandra 를 통제할 수 있도록 로드 셰딩 기법을 더 넣는다.
    • Cassandra 전문 인력을 사내에 더 둔다.
    교훈

    PagerDuty 는 Cassandra 클러스터의 규모가 모자랐고, 부하와 사용 방식이 서로 다른 너무 많은 서비스가 한 클러스터를 나눠 쓰고 있었다고 밝혔다. 비슷한 문제를 보고 개선을 계획했지만 효율을 기준으로 버전 업그레이드를 먼저 하려 했고, 확장을 먼저 했어야 했다고 적었다.

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

이 4건에서 가장 많이 나오는 구성 요소: 데이터베이스, PostgreSQL vacuum. kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이런 틈을 점검합니다. 점검 항목의 근거는 이 라이브러리와 같은 공개 보고서입니다.

원인별1