IL-0587 Elastic · 2019-01-18databaseawsnetworking
Elastic Cloud AWS eu-west-1 리전의 클러스터 접속이 약 3시간 심하게 저하되고 20분 동안 완전히 끊겼다
Elastic Cloud 의 리전마다 백엔드는 세 계층으로 이루어진다. allocator 계층은 Elasticsearch 와 Kibana 인스턴스를 올리는 호스트다. 조정 계층은 3노드 Apache ZooKeeper 앙상블이고, 시스템 상태와 각 클러스터 노드와 Kibana 인스턴스의 실제 위치를 담고 있다. 프록시·라우팅 계층은 클러스터의 가상 호스트 이름을 보고 트래픽을 보내고, 그 앞에는 여러 프록시 인스턴스로 부하를 나누는 로드 밸런서가 있다. 프록시는 Apache Curator 프레임워크로 ZooKeeper 에 직접 붙는 클라이언트다. 프록시는 모든 배포와 그 노드를 나타내는 znode 하위 트리 전체를 TreeCache 로 감시한다.
TreeCache 는 ZooKeeper 와의 연결이 끊겼다가 다시 붙으면 미러 트리 전체를 돌면서 노드마다 데이터를 다시 읽고 watch 를 다시 거는 요청을 한꺼번에 큰 묶음으로 보낸다. TreeCache 하나에 znode 가 수만 개일 수 있고, 새로 고침 도중 연결이 또 끊기면 같은 묶음을 다시 보낸다. 클라이언트는 정해진 시간 안에 heartbeat 를 받지 못하면 연결이 끊긴 것으로 보므로, ZooKeeper 서버가 과부하로 긴 GC 멈춤을 겪어도 연결이 불안정해진다. 그러면 프록시가 요청을 쏟아내 서버의 요청 큐가 차고 GC 가 더 나빠진다. 서버가 응답을 못 보내는 사이에는 클라이언트의 크기 제한 없는 송신 큐에 요청이 쌓여 클라이언트가 메모리 부족에 빠진다. 이번 장애에서는 09:09 UTC 에 리더 서버의 CPU 가 높은 임계치에 닿아 클라이언트 연결이 끊겼고, 09:35 UTC 부터 프록시가 쌓인 새로 고침 요청 때문에 자원이 바닥나 메모리 부족 상태가 됐다. 이 악순환이 12:42 UTC 의 완전 중단으로 이어졌다.
SRE 들은 12:42 UTC 부터 13:02 UTC 까지의 완전 중단 동안 프록시 계층을 수직과 수평으로 늘리고, 리더 선출을 일으켜 ZooKeeper 앙상블을 안정시켰다. 13:03 UTC 에 클러스터 가용성이 돌아왔고, 지켜보는 시간을 거친 뒤 장애를 해결로 닫았다. Elastic 은 사고 몇 달 전부터 TreeCache 와 API 가 호환되도록 새로 쓴 TreeWatcher 를 만들고 있었다. TreeWatcher 는 재개된 세션에서는 트리를 새로 고치지 않고, 부모 노드의 응답을 받은 뒤에만 자식 노드의 요청을 보낸다. 또 새로 고침 도중 세션을 잃으면 진행 중인 새로 고침을 취소하고 새로 시작한다. Elastic 은 TreeWatcher 를 2018년 12월부터 관리 플레인과 컨트롤 플레인, 그다음 데이터 플레인 순서로 배포하고 있었고, 프록시 계층의 전환은 2019년 1월 21일 주로 잡혀 있었다.
- 심각도
- –
- 영향 범위
- Access to Elastic Cloud deployments (Elasticsearch clusters and Kibana instances): severely degraded for about 3 hours, and all deployments in the region unavailable for about 20 minutes
- 영향 사용자
- Elastic Cloud customers with deployments in AWS eu-west-1
- 지역
- AWS eu-west-1 (Ireland)
- 감지까지
- 26m
- 복구까지
- 3h 54m
증상
2019년 1월 18일 09:35 UTC 에 Elastic Cloud 의 당번 SRE 들이 AWS eu-west-1 리전 조정 계층의 서비스 저하 알림을 받았다. 10:08 UTC 무렵부터 이 리전에 배포를 둔 고객은 약 3시간 동안 자기 클러스터에 접속하기가 매우 어려워졌다.
조정 계층은 3노드 Apache ZooKeeper 앙상블이다. 09:09 UTC 에 이 앙상블의 리더 서버에 CPU 부하가 크게 걸려 높은 CPU 임계치에 닿았고, ZooKeeper 클라이언트들의 연결이 끊기기 시작했다.
트래픽을 각 클러스터 노드로 보내는 프록시·라우팅 계층은 ZooKeeper 와의 연결이 붙었다 끊겼다를 반복했고, 프록시가 쓰는 클라이언트 라이브러리는 이 상황을 제대로 다루지 못했다. 프록시는 연결이 다시 붙을 때마다 큰 묶음의 데이터 새로 고침 요청을 ZooKeeper 로 보냈고, 응답을 받지 못한 요청이 프록시 안에 쌓여 메모리 부족 오류가 났다.
장애는 시간이 갈수록 나빠졌다. 10:08 UTC 에 프록시·라우팅 계층이 저하 상태에 들어갔고 10:30 UTC 부터 더 나빠졌다. 12:42 UTC 부터 13:02 UTC 까지 20분 동안 리전의 모든 배포를 쓸 수 없었고, 13:03 UTC 에 클러스터 가용성이 돌아왔다.
SRE 들은 클라이언트가 다시 연결하지 못하게 막고 초기화 단계를 다시 밟게 했다. 그러나 이 조치로는 ZooKeeper 쿼럼이 안정되지 않았다.
원인
원인 소프트웨어 결함
- 촉발
- 09:09 UTC 에 ZooKeeper 앙상블 리더 서버의 CPU 사용량이 높은 임계치에 닿으면서 클라이언트 연결이 끊긴 것이 시작이었다.
감지
09:35 UTC 에 당번 SRE 들이 조정 계층의 서비스 저하 알림을 받았고, 내부 절차에 따라 운영 장애를 열었다.
조치
- 급증한 클라이언트 트래픽을 받도록 프록시 계층을 수직과 수평으로 늘렸다.
- 리더 선출을 일으켜 조정 계층의 ZooKeeper 앙상블을 안정시켰다.
후속 조치
- 모든 Elasticsearch Service 제공자와 리전 거점에서 TreeCache 를 TreeWatcher 로 바꾼다. 2019년 1월 24일에 교체를 마쳤다.
- 운영에서 검증된 TreeWatcher 를 Apache Curator 프로젝트에 기여할 계획이다.
- 다음 버전의 프록시 계층은 ZooKeeper 에 덜 의존하고, 라우팅 테이블을 버전을 매긴 로컬 파일에 캐시해 ZooKeeper 연결이 끊기거나 불안정해도 트래픽을 보낼 수 있게 한다. 앞으로 몇 달에 걸쳐 모든 리전에 차례로 배포한다.
교훈
–
출처
관련 사례
같은 원인 · 공통 코디네이션 키-값 저장소, 서비스 디스커버리
IL-0271서비스 디스커버리에 잘못된 항목이 들어가 Elixir 서비스들이 한꺼번에 죽으면서 Discord 가 대부분의 사용자에게 한 시간 동안 열리지 않았다Discord · 2020 · sev1같은 원인 · 공통 코디네이션 키-값 저장소, 서비스 디스커버리
같은 원인 · 공통 서비스 디스커버리
IL-0277Elastic Cloud us-east-1 의 ZooKeeper 조정 계층이 쿼럼을 잃어 Elasticsearch 배포에 6시간 넘게 접속하지 못하고 Kibana 는 18:44 UTC 까지 불안정했다Elastic · 2019같은 원인 · 공통 코디네이션 키-값 저장소
같은 원인 · 공통 코디네이션 키-값 저장소
내 클러스터에도 있는지 확인하기
AI 도구와 스크립트용
- 이 사례의 JSON: https://incidentlib-api.benchlet.com/cases/IL-0587
- 가장 비슷한 사례들: https://incidentlib-api.benchlet.com/cases/IL-0587/similar
- MCP 서버(Streamable HTTP, 키 없음):
https://incidentlib-mcp.benchlet.com/mcp
API 는 키가 필요 없습니다. MCP 서버는 search_incidents, get_incident, list_incidents, get_topic, vocab 도구를 내놓습니다. 사용법은 API 와 MCP.