IL-0212 Slack · 2022-02-22database
캐시 적중률이 떨어지며 채널 멤버십 Vitess 키스페이스가 과부하에 빠져 많은 사용자가 Slack 에 접속하지 못했다
Slack 클라이언트는 새 세션을 시작할 때 부팅 과정에서 채널 목록, 설정, 최근 대화를 서버에서 가져와 캐시하고, 부팅하지 못하면 쓸 수 없다. Slack 은 데이터를 MySQL 수평 확장 시스템인 Vitess 에 두고, 자주 쓰는 데이터는 Memcached 캐시 계층에서 읽는다. Mcrouter 는 정상 memcached 호스트 목록으로 만든 설정을 받아 일관 해싱으로 캐시 요청을 보낸다. 캐시 제어 계층인 Mcrib 는 서비스 디스커버리 시스템 Consul 을 지켜보다가 빠진 memcached 인스턴스를 예비 인스턴스로 바꾸고 다시 들어온 인스턴스는 비운 뒤 활성으로 올린다. Consul 에이전트가 내려가면 노드와 그 위의 서비스가 서비스 카탈로그에서 빠진다.
2월 22일 Consul 에이전트 업그레이드를 비율 단위로 롤아웃하는 단계에서 전체 에이전트의 25% 를 차례로 재시작했다. 앞 주의 25% 단계 두 번은 문제가 없었지만, 이번에는 하루 최대 트래픽과 겹쳤다. memcached 노드가 차례로 빠졌다 들어오며 Mcrib 가 빈 노드를 올리고 다시 들어온 노드를 비웠고, 캐시 적중률이 떨어졌다. 클라이언트 부팅 중 그룹 DM 멤버 목록은 사용자 기준으로 샤딩한 키스페이스에서 모든 샤드를 조회하는 scatter query 로 읽었는데, 평소에는 채널 ID 로 오래 캐시되어 문제가 없었다. 캐시가 비자 이 쿼리가 폭증해 키스페이스가 과부하에 빠졌고, 쿼리가 타임아웃되어 캐시를 채우지 못하는 연쇄 장애가 이어졌다. 클라이언트 재시도도 부하를 보탰다. 이전 방식보다 빠르고 효율적으로 캐시 설정을 고치는 Mcrib 가 캐시 계층의 교체를 늘려 장애를 키웠다.
대응 팀은 Consul 재시작을 멈췄고, 클라이언트 부팅 요청에 속도 제한을 걸어 이미 부팅한 사용자의 서비스를 지켰다. 제한을 한 번에 너무 많이 풀었다가 부하가 다시 올라 제한을 되돌리고 작은 폭으로 풀었다. 쿼리는 memcached 에 없는 데이터만 Vitess 에서 읽게 바꿨고, 그룹 DM 데이터는 바뀌지 않으므로 Vitess 프라이머리뿐 아니라 복제본에서도 읽게 했다. 캐시가 다시 차며 적중률이 오르고 데이터베이스 부하가 내려갔고, 부팅 속도 제한을 천천히 정상 수준까지 올려 서비스를 완전히 되살렸다.
- 심각도
- –
- 영향 범위
- Slack client boot: many users could not connect to Slack, and requests from users with booted clients also failed until boot requests were throttled
- 영향 사용자
- many Slack users, including internal users
- 지역
- –
- 감지까지
- –
- 복구까지
- –
증상
2022년 2월 22일 태평양 시간 오전 6시 직후 Slack 에 접속하지 못한다는 사용자 티켓과 내부 사용자의 문제 보고가 들어왔고, 여러 엔지니어링 팀에 호출과 알림이 거의 동시에 왔다. 많은 사용자가 Slack 에 접속하지 못했다. 클라이언트는 부팅 과정에서 채널 목록, 설정, 최근 대화를 서버에서 가져오는데, 부팅하지 못하면 Slack 은 오류 페이지를 보였다.
가장 크게 영향받은 API 작업은 클라이언트 부팅이었다. 부팅 요청은 평소보다 훨씬 오래 걸리고 자주 실패했으며, 느린 요청이 데이터베이스 계층의 자원을 바닥내 이미 부팅한 사용자의 요청까지 실패하게 만들었다.
데이터베이스 시스템 일부에 평소보다 큰 부하가 걸렸다. 사용자 기준으로 샤딩한 채널 멤버십 Vitess 키스페이스에 심한 과부하가 걸렸고, 부하의 상당 부분은 사용자별 그룹 DM 대화 목록을 조회하는 쿼리였다. 이 쿼리는 캐시 계층 뒤에 있었으므로 대응 팀은 캐시에 문제가 있다고 봤다.
사용자 기준으로 샤딩한 테이블에서 그룹 DM 의 멤버를 찾으려면 키스페이스의 모든 샤드에 scatter query 를 보내야 했다. 캐시의 상당 부분이 비자 거의 모든 사용자가 모든 샤드를 조회해야 했고, 읽기 부하는 캐시 미스 비율보다 가파르게 늘었다. 채널 멤버십 테이블 쿼리 대부분이 타임아웃되어 캐시를 다시 채울 수 없었다.
대응 팀은 초기에 문제를 촉발한 Consul 에이전트 재시작 작업을 멈췄다. 그때는 재시작이 장애와 관련 있다고 의심하지 않았고, 이미 연쇄 장애 상태라 멈춰도 달라지지 않았다. 클라이언트의 자동 재시도는 지수 백오프와 지터를 썼지만 여전히 부하를 보탰다.
부팅 요청에 엄격한 제한을 걸자 오류가 줄고 이미 부팅한 사용자의 Slack 은 비교적 정상에 가깝게 동작했다. 처음 제한을 너무 크게 풀자 데이터베이스 부하가 다시 감당할 수 없는 수준으로 오르고 실패한 요청이 늘었다.
원인
- 촉발
- 2월 22일 Consul 에이전트 업그레이드를 비율 단위로 롤아웃하는 단계에서 전체 에이전트의 25% 를 차례로 재시작했다. memcached 노드의 에이전트가 재시작될 때마다 캐시 제어 계층인 Mcrib 가 그 노드를 비어 있는 예비 노드로 바꾸거나 다시 들어온 노드를 비웠고, 하루 중 트래픽이 가장 많은 시간에 캐시 적중률이 떨어졌다.
감지
태평양 시간 오전 6시 직후 Slack 에 접속하지 못한다는 사용자 티켓, 내부 사용자의 문제 제기, 여러 엔지니어링 팀의 호출과 알림이 거의 동시에 들어왔다.
조치
- 대응 초기에 장애를 촉발한 Consul 에이전트 재시작 작업을 멈췄다. 그때는 재시작이 장애와 관련 있다고 의심하지 않았다.
- 느린 부팅 요청이 데이터베이스 자원을 바닥내 이미 부팅한 사용자의 요청까지 막자 클라이언트 부팅 요청에 엄격한 속도 제한을 걸었다.
- 처음 제한을 너무 많이 풀어 데이터베이스 부하와 실패한 요청이 다시 늘자 부팅 속도 제한을 다시 낮췄고, 그 뒤로는 작은 폭으로 올렸다.
- 캐시 미스마다 모든 샤드를 읽던 쿼리를 memcached 에 없는 데이터만 Vitess 에서 읽도록 바꿨다.
- 그룹 DM 데이터는 바뀌지 않아 조금 오래된 값을 써도 되므로 쿼리가 Vitess 프라이머리뿐 아니라 복제본에서도 읽도록 바꿨다.
- 캐시가 다시 차고 적중률이 오르자 데이터베이스 처리량을 최대로 유지하면서 클라이언트 부팅 속도 제한을 천천히 정상 트래픽 수준까지 올렸다.
후속 조치
- Consul 롤아웃 절차를 바꿔 업그레이드 중에 같은 장애가 다시 촉발되지 않게 했다.
- 캐시 노드에 짧은 네트워크 단절이 생겨도 같은 연쇄 장애가 나지 않도록 Mcrib 제어 루프의 해당 부분을 바꿔 배포한다.
- 문제가 된 scatter query 를 채널 기준으로 샤딩한 테이블에서 읽도록 바꿨다.
- 캐시 계층 뒤에 있는 다른 데이터베이스 쿼리를 분석해 비슷한 위험이 있는 대량 scatter query 가 있는지 찾는다.
- 장기 프로젝트로 캐시 계층의 복원력을 높이는 다른 방법을 찾는다.
교훈
Slack 은 성능 병목, 연쇄 장애, 데워진 캐시에 기대는 구조, 촉발 요인이 된 변경이 장애에서 자주 보이는 패턴이라고 봤다. 이번 장애는 여러 시스템의 경계를 넘는 상호작용이었고 그중 일부 시스템은 최근에 바뀌었다. 큰 소프트웨어 시스템에서 복잡성과 변경은 피할 수 없고, 그만큼 시스템이 예측하지 못한 방식으로 움직일 위험도 커진다.
Mcrib 는 틀리거나 비효율적이어서가 아니라 오히려 빠르고 효율적이어서 장애를 키웠다. 빠진 memcached 인스턴스를 더 빨리 찾아 설정을 고치면서 캐시 계층의 교체가 늘었고, 더 나은 구성 요소가 전체 시스템을 덜 안전하게 만들었다. 캐시 노드에 짧은 네트워크 단절이 생겨도 같은 연쇄 장애가 날 수 있다는 위험도 드러났다. 연쇄 장애에 빠진 시스템은 부하를 크게 줄이거나 용량을 늘리는 외부 개입 없이는 안정 상태로 돌아오지 않는다.
출처
관련 사례
같은 원인 · 공통 인메모리 캐시, 데이터베이스
같은 원인 · 공통 인메모리 캐시, 데이터베이스
IL-0202갑자기 몰린 쿼리와 데이터베이스 쓰기로 Honeycomb 수집 호스트가 메모리 부족으로 죽었고, 쿠버네티스 CrashLoopBackOff 가 용량 회복을 막아 US1 이벤트 수집이 한 시간 넘게 불안정했다Honeycomb · 2023 · sev1같은 원인 · 공통 인메모리 캐시, 데이터베이스
IL-0386Google Cloud 로 옮긴 뒤 GKE 노드에서 Postgres 연결 타임아웃과 memcached i/o timeout 이 간헐적으로 튀었다incident.io · 2023같은 원인 · 공통 인메모리 캐시, 데이터베이스
IL-0206GKE 파드 안의 Consul 에이전트가 메모리 급증으로 거듭 OOM kill 되어 Rails 파드가 데이터베이스 복제본을 찾지 못했고, 모든 쿼리가 primary 로 몰려 GitLab.com 이 느려졌다.GitLab · 2022같은 원인 · 공통 서비스 디스커버리, 데이터베이스
같은 원인 · 공통 인메모리 캐시, 데이터베이스
같은 원인 · 공통 인메모리 캐시
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 서비스 디스커버리
IL-0290GitLab.com 의 Redis Sidekiq 클러스터에서 노드 여러 대가 메모리를 다 써 멈추고 쿼럼을 잃어, 웹과 Git 과 CI 전반에서 500 오류가 늘었다GitLab · 2026 · sev1같은 원인 · 공통 인메모리 캐시
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
IL-0288CDN77 의 ClickHouse 데이터 파이프라인에서 이중화된 인스턴스 세 곳의 ZooKeeperWait 가 수천 초로 치솟아 복제가 한 시간 넘게 느려졌다CDN77 · 2026같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
IL-0305Intercom 의 PlanetScale 샤드 하나에서 복제본이 CPU 100% 로 주 데이터베이스를 따라가지 못해 받은편지함에 최대 2.2시간 전의 데이터가 보였다Intercom · 2026같은 원인 · 공통 데이터베이스
IL-0390PostHog US Cloud 의 Persons Postgres 데이터베이스 쓰기가 크게 느려져 이벤트와 persons 수집이 최대 2일 지연됐다PostHog · 2025같은 원인 · 공통 데이터베이스
같은 원인 · 공통 인메모리 캐시
IL-0287Atlas 와 Cloud Manager 의 모니터링을 받치는 내부 데이터베이스 클러스터의 샤드 하나가 과부하되어 지표 수집과 클러스터 작업이 늦어졌다MongoDB · 2025같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
IL-0067Redis 마스터의 50Mi 영구 볼륨이 가득 차 AOF 가 깨졌고, Redis 파드가 크래시 루프에 빠져 Klamm 운영 서비스가 멈췄다BC Government · 2025 · sev1같은 원인 · 공통 인메모리 캐시
같은 원인 · 공통 데이터베이스
IL-0298Wikimedia sessionstore 의 Cassandra 노드가 디스크가 가득 차 잇따라 죽고 쿼럼을 잃어 편집이 실패했다Wikimedia Foundation · 2025같은 원인 · 공통 데이터베이스
IL-0312max_connections 를 올리려고 재시작한 주 PostgreSQL 데이터베이스가 다시 올라오지 않아 Gadget 의 모든 앱 요청이 멈췄다Gadget · 2024같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
IL-0110Grafana Agent 파드가 메모리를 많이 쓰던 노드에 Hangfire 파드가 함께 올라가 시스템 OOM 으로 CrashLoopBackOff 를 반복했고, 노드가 응답을 멈추고 NotReady 가 됐다.DFDS · 2024같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 인메모리 캐시
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
IL-0496전역 복제 Cassandra 클러스터에서 모든 리전의 인스턴스 CPU 가 100% 로 치솟아 쿼리가 타임아웃됐고, 같은 부하가 이틀 저녁 더 찾아왔다Ably · 2020같은 원인 · 공통 데이터베이스
IL-0443Aurora MySQL reader 가 이유 없이 재시작한 뒤 writer 의 insert latency 가 7배쯤 오르고 replication lag 가 하루 넘게 이어졌다Repro · 2019같은 원인 · 공통 데이터베이스
IL-0037imagePullPolicy가 Always인 DaemonSet이 크래시 루프를 돌며 이미지를 계속 받아, NAT 세 대를 같이 쓰던 리전 전체가 이미지 레지스트리에서 429로 막혔다Datadog · 2019같은 원인 · 공통 데이터베이스
IL-0211Mandrill 의 PostgreSQL 샤드 하나가 트랜잭션 ID 랩어라운드를 막으려고 쓰기를 멈춰 약 40시간 동안 메일 발송이 줄었다Mailchimp · 2019같은 원인 · 공통 데이터베이스
IL-0064CPU 를 많이 쓰는 파드가 Google Cloud 노드 하나에 몰려 노드가 커널 패닉으로 죽었고, 다시 배치된 파드가 다음 노드를 또 죽이며 웹사이트와 API 가 멈췄다.Moonlight · 2019같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
IL-0334RDS MySQL 의 bookmarks 테이블이 2TB 파일 크기 한도에 닿아 INSERT 가 실패하고 Instapaper 가 31시간 동안 멈췄다Instapaper · 2017같은 원인 · 공통 데이터베이스
IL-0333사양을 낮춘 RDS PostgreSQL 인스턴스가 피크 부하를 못 버텨 헬스 체크가 실패하고 Buildkite 대시보드가 몇 시간 동안 내려갔다Buildkite · 2016같은 원인 · 공통 데이터베이스
같은 원인 · 공통 인메모리 캐시
같은 원인 · 공통 인메모리 캐시
IL-0282US-East 리전의 DynamoDB 스토리지 서버들이 멤버십 정보를 받지 못해 스스로 요청 처리에서 빠지면서 고객 요청의 약 55% 가 실패했다Amazon Web Services · 2015같은 원인 · 공통 데이터베이스
IL-0275Kafka 브로커들이 네트워크 한계에 닿아 줄줄이 쓰러지면서 Parse.ly 의 데이터 처리가 멈추고 대시보드에 몇 시간 동안 새 데이터가 나오지 않았다Parse.ly · 2015같은 원인 · 공통 서비스 디스커버리
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
내 클러스터에도 있는지 확인하기
AI 도구와 스크립트용
- 이 사례의 JSON: https://incidentlib-api.benchlet.com/cases/IL-0212
- 가장 비슷한 사례들: https://incidentlib-api.benchlet.com/cases/IL-0212/similar
- MCP 서버(Streamable HTTP, 키 없음):
https://incidentlib-mcp.benchlet.com/mcp
API 는 키가 필요 없습니다. MCP 서버는 search_incidents, get_incident, list_incidents, get_topic, vocab 도구를 내놓습니다. 사용법은 API 와 MCP.