아날로그 인시던트 샌드 테이블: 연쇄 장애를 미리 눈으로 보기
옛 아이디어인 물리적 샌드 테이블이 어떻게 현대 엔지니어링 팀이 복잡한 시스템에서 연쇄 장애를 이해하고 예방하는 데 도움이 될 수 있는지 살펴봅니다.
소개
대부분의 엔지니어링 팀은 연쇄 장애(cascading failure)를 처음 만나는 순간이 늘 그렇듯 최악의 상황입니다. 새벽 2시에 터지는 장애 말이죠.
어느 한 서비스가 느려지기 시작합니다. 재시도가 걸립니다. 큐가 밀리기 시작합니다. 다운스트림 데이터베이스가 thrashing(과도한 I/O로 허우적거림)을 시작합니다. 대시보드는 일제히 빨갛게 변하고, 온콜(온콜 담당자)의 휴대폰이 동시에 울리며, 처음엔 국소적인 작은 문제가 어느새 전체 장애로 번져버립니다.
우리는 흔히 이런 장애를 그래프, 트레이스, 메트릭 같은 걸로 말로 설명합니다. 하지만 연쇄 장애를 이해하는 또 다른 의외로 강력한 방법이 있습니다. 바로 실제로 물리적인 “흐름용 모래(flow sand)” 테이블—즉 아날로그 인시던트 샌드 테이블(analog incident sand table)—을 만들어, 연쇄 장애가 물리적으로 커지고, 넘치고, 전파되는 현상으로 눈앞에서 보이게 만드는 것입니다.
이 글에서는 샌드 테이블의 역사, 그것이 어떻게 현대 분산 시스템에 놀랍도록 잘 대응되는지, 그리고 이를 활용해 연쇄 장애를 이해하고 예방하는 방법을 살펴보겠습니다.
그리스의 아박스부터 현대 샌드 테이블까지
추상적인 문제를 생각하기 위해 물리적인 매체를 사용하는 아이디어는 아주 오래되었습니다.
그리스의 아박스: 손으로 만지는 계산
**아박스(abax)**는 고대 그리스에서 사용되던, 모래나 먼지를 깔아 둔 평평한 판으로, 초기 계산 도구였습니다. 사람들은 여기에 선을 긋고 조약돌을 옮기면서 숫자를 표현했습니다. 머릿속으로 하기엔 복잡한 산술도, 눈앞에 물리적으로 펼쳐 놓으면 훨씬 명확해졌습니다.
이게 중요한 이유는, 하나의 패턴을 보여주기 때문입니다. 시스템이 머릿속으로만 이해하기엔 너무 복잡해지는 순간, 우리는 물리적인 표현에 손을 뻗는다는 것입니다.
계획·워게임용 샌드 테이블
시간을 훌쩍 건너뛰어 봅시다. 샌드 테이블은 군사 계획과 교육을 위한 물리적 모델로 등장했습니다.
- 모래로 지형(산, 계곡, 강 등)을 만듭니다.
- 부대와 장비는 말판 조각이나 마커로 표현합니다.
- 이동 경로, 사선(line of fire), 보급로, 취약 지점을 테이블 위에 직접 시각화합니다.
지휘관들은 이런 모델을 사용해 다양한 시나리오를 탐색하고, 병목지점을 찾고, 한 곳의 작은 변화가 전장 전체에 어떤 파급 효과를 만들어낼지 미리 상상해 봅니다.
오늘날의 소프트웨어 시스템도 이 전장과 많이 닮았습니다. 수많은 참여자(서비스), 복잡한 상호작용, 코드나 다이어그램만 봐서는 직관적으로 이해하기 힘든 결과들까지요.
아날로그 인시던트 샌드 테이블이란?
**아날로그 인시던트 샌드 테이블(analog incident sand table)**은 이런 오래된 아이디어를 현대적으로 재해석한 것입니다. 산과 강을 모델링하는 대신, 다음을 모델링합니다.
- 서비스: 모래 위의 영역이나 도형으로 표현
- 의존성(dependency): 서비스 간을 잇는 채널, 경로, 파이프
- 부하 또는 요청(load/requests): 시스템을 흐르는 색 모래나 토큰
잘 흐르는 flow sand(입자가 곱고 잘 움직이는 모래나 작은 비드 등)를 사용하면, 부하가 어디에 쌓이고, 어디서 정체되며, 작은 막힘이 어떻게 전체 시스템에 영향을 주는 대규모 체증으로 번지는지를 눈으로 추적할 수 있습니다.
결국 이것은 아키텍처와 장애 양상을 실제로 손댈 수 있는 물리적·동적 다이어그램으로 바꾸는 셈입니다.
디지털 세상에 왜 굳이 아날로그?
엔지니어들은 이미 다음과 같은 도구를 갖고 있습니다.
- 서비스 의존성 그래프
- 트레이스와 로그
- 대시보드와 SLO(Service Level Objective)
그런데 왜 여기에 모래까지 들고 올까요?
물리적 모델은 다음과 같은 장점이 있기 때문입니다.
- 다른 종류의 직관을 자극 – 병목과 정체, 전파가 물리적인 흐름으로 눈에 보입니다.
- 집단적 사고를 이끕니다 – 팀이 테이블을 둘러싸고 서서 직접 조각을 옮기며 시나리오를 함께 토론할 수 있습니다.
- 추상 개념을 구체화 – “bounded retries(재시도 상한)”나 “backpressure(역압)”를, 실제 흐름을 막거나 부하를 제한해 보이면서 설명할 수 있습니다.
이건 관측(Observability) 도구나 시뮬레이션의 대체재가 아니라, 설계 리뷰, 인시던트 포스트모텀, 교육을 위한 **사고 도구(thinking aid)**에 가깝습니다.
연쇄 장애: 샌드 테이블 위의 도미노 효과
**연쇄 장애(cascading failure)**는 보통 아주 작은 데서 시작해 점점 커집니다.
- 한 컴포넌트가 느려지거나 장애가 납니다.
- 그 컴포넌트로 가는 호출이 재시도되거나 대기열에 쌓입니다.
- 업스트림 서비스의 스레드, 커넥션, 큐가 포화됩니다.
- 다운스트림 서비스도 과부하, 타임아웃, 크래시를 겪습니다.
- 장애가 도미노처럼 시스템 전반으로 퍼집니다.
이걸 샌드 테이블로 시각화하면 매우 강력합니다. 다음을 상상해 봅시다.
- 각 서비스에는 모래(요청)가 들어오는 **입구(inlet)**와, 다음 곳으로 넘어가는 **출구(outlet)**가 있습니다.
- 서비스 사이의 채널이 모래가 흐를 수 있는 경로를 결정합니다.
- 각 서비스에는 작은 용기나 제한된 부피의 영역으로 표현한 **용량(capacity)**이 있습니다.
이제 어떤 서비스의 출구를 부분적으로 막아(높은 레이턴시나 의존성 장애를 시뮬레이션) 보면, 모래가 쌓이기 시작합니다.
- 막힌 영역은 가득 차고, 넘치기 시작합니다.
- 모래가 빠져나갈 곳이 없으니 업스트림 영역도 점점 차오릅니다.
- 다운스트림 영역은 반대로, 모래가 도달하지 못해 굶주리게 됩니다.
몇 분 만에, 실제 프로덕션에서라면 타임아웃, 재시도 폭증, 큐 포화, CPU 스파이크로 보였을 상황을, 눈앞에서 그대로 재현하게 됩니다.
샌드 테이블로 예방 기법 모델링하기
진짜 가치는 장애를 보기만 하는 것이 아니라, 모두가 이해할 수 있는 방식으로 예방 기법을 실험해 보는 것에 있습니다.
1. Bounded retries (재시도 상한)
개념: 각 요청이 재시도될 수 있는 횟수에 상한을 두는 것.
샌드 테이블 위에서는:
- 각 서비스 옆에 작은 “재시도 컵(retry cup)”을 둡니다.
- 요청이 실패할 때마다, 그 서비스의 재시도 컵에 토큰을 하나 떨어뜨립니다.
- 컵의 크기를 제한합니다. 컵이 가득 차면, 그 이후 실패는 더 이상 재시도하지 않습니다.
무엇을 보게 되는가:
막힌 영역으로 끝없이 모래가 쏟아져 들어가 장애를 증폭시키는 대신, 재시도 흐름이 어느 지점에서 멈춥니다. 쌓이는 모래의 양은 더 작고, 영향 범위도 더 국소적입니다.
2. Jitter (지터)
개념: 재시도 타이밍에 무작위성을 더해, 모든 요청이 한꺼번에 몰리는 스파이크를 피하는 것.
샌드 테이블 위에서는:
- 재시도 모래를 한 번에 쏟아붓는 대신, 여러 사람이 서서 모래를 조금씩, 서로 다른 타이밍에 떨어뜨립니다.
무엇을 보게 되는가:
시스템이 작은 물결을 계속 흡수하면서, 한 번에 몰리는 거대한 재시도 폭풍을 피할 수 있습니다. 깨지기 쉬운 컴포넌트가 한순간에 압사당하는 상황을 완화합니다.
3. Per-call deadlines (호출별 데드라인)
개념: 각 호출마다 최대 시간 예산을 두고, 이를 초과하면 해당 호출을 포기하는 것.
샌드 테이블 위에서는:
- 각 서비스 옆에 작은 타이머나, 모래가 이동해야 하는 **“데드라인 트랙(deadline track)”**을 만듭니다.
- 모래가 서비스 영역을 빠져나갈 때까지 타이머가 끝나거나, 모래가 트랙 끝에 도달하면, 그 모래를 흐름에서 제거합니다.
무엇을 보게 되는가:
모래가 막힌 영역에 무기한 갇혀 있지 않습니다. 이는 실제 시스템에서 스레드, 커넥션, 리소스가 무한정 붙들려 있다가 전체를 무너뜨리는 대신, 일정 시점 이후에는 해제되는 모습을 모델링합니다.
4. Per-service retry scopes (서비스 단위 재시도 범위)
개념: 요청 경로 상에서 어디서 재시도가 허용되는지 제한하고, 주로 시스템의 “엣지(외곽)” 쪽에 재시도를 몰아두는 것.
샌드 테이블 위에서는:
- 일부 영역에 “재시도 금지 구역(no-retry zone)” 표시를 합니다.
- 예를 들어, 퍼블릭 게이트웨이 같은 엣지 서비스만 재시도 컵을 사용하도록 허용합니다.
무엇을 보게 되는가:
시스템 깊은 곳에서 난 장애가, 경로의 모든 홉에서 재시도를 만들어내지 않습니다. 모래가 매 단계에서 곱절로 늘어나지 않고, 주로 경계(엣지)에서만 압력이 커집니다. 이 구간은 캐싱, 서킷 브레이커, 레이트 리밋 등으로 상대적으로 통제 수단이 더 풍부한 곳입니다.
메시징 인프라: 샌드 폭풍이 아닌 샌드 버퍼 만들기
대규모 마이크로서비스 환경에서는 RabbitMQ 같은 메시지 큐 기반의 견고한 메시징 인프라가 연쇄 장애를 완화하는 데 핵심적인 역할을 합니다.
샌드 테이블에서 큐는 자연스럽게 **버퍼 영역(buffer region)**으로 표현할 수 있습니다.
- 큐는 다음 서비스로 넘어가기 전 모래가 쌓여 있는 **저장 통(bin)**입니다.
- 컨슈머(소비자)가 일정 속도로 모래를 끌어가 처리합니다.
큐가 충격을 흡수하는 방식
다음과 같은 핵심 동작을 눈으로 보여줄 수 있습니다.
- 부하 평준화(load leveling): 입력으로 들어오는 모래가 서비스 처리 속도보다 빠를 때, 큐의 통이 먼저 차오릅니다. 서비스는 자신의 처리 가능 속도대로만 모래를 가져가므로, 즉시 압도당하지 않습니다.
- 역압(backpressure) 신호: 통이 거의 가득 차면, 위험이 눈에 훤히 보입니다. 이때 입력 유량을 줄이거나, 새 모래를 거부하거나, 다른 경로로 넘기는 등의 조치를 고민할 수 있습니다.
- 장애 격리(failure isolation): 다운스트림 컨슈머가 멈추면, 먼저 큐의 통이 가득 차게 됩니다. 업스트림 모래가 즉시 시스템 전체를 덮치는 대신, 장애가 일정 부분 격리되고 완충됩니다.
이 비유 속의 RabbitMQ와 친구들
RabbitMQ, Kafka, 클라우드 메시지 큐 같은 기술은 비유하자면 다음과 같습니다.
- 잘 설계된 통 – 내구성 있는 큐, 명확한 용량 제한
- 여러 차선 – 워크로드나 우선순위별로 분리된 큐
- 흐름 제어 메커니즘 – ack, 재전송 정책, DLQ(Dead-Letter Queue)
샌드 테이블에서 시도해 볼 수 있는 것들:
- 큐에 용량 제한이 전혀 없으면 어떤 일이 생기는지 (통이 넘치며 사방으로 모래가 흩어짐)
- **DLQ(Dead-Letter Queue)**는 어떻게 보이는지 (문제 있는 모래를 따로 모아 두는 작은 보조 통)
- 하나의 큰 통을 공유하는 구조 vs. 서비스별 개별 큐를 두었을 때의 차이
이런 아날로그 실험은 다시 실제 설계 논의—라우팅 키, 컨슈머 그룹, 동시성 설정, 역압 전략—로 자연스럽게 이어집니다.
인시던트 샌드 테이블을 실제로 활용하는 방법
완벽한 모델이 필요하지 않습니다. 유용한 모델이면 충분합니다. 실무에 적용하는 방법을 보겠습니다.
1. 기본 테이블 만들기
- 얕은 쟁반이나 화이트보드 같은 평평한 표면
- 곱고 잘 흐르는 모래나 작은 비드(한두 가지 색이면 충분)
- 서비스를 구분할 테이프나 마커
- 큐와 용량을 표현할 작은 용기나 종이벽
2. 실제 시나리오 선택하기
구체적인 상황을 하나 고릅니다.
- 이해하고 싶은 과거 장애 사건
- 불안한 마음이 드는 신규 아키텍처
- “만약 X가 죽는다면?” 같은 가상 시나리오
엔드 투 엔드 스토리를 설명하는 데 필요한 최소한의 서비스만 모델링합니다.
3. 장애를 따라가 보기
- 먼저 정상 상태 부하부터 시작합니다. 모래를 일정한 속도로 시스템 전체에 흘려보냅니다.
- 그런 다음, 중요한 채널 하나를 막거나 좁혀 장애를 주입합니다.
- 어디에 모래가 쌓이고, 어떻게 전파되는지 지켜봅니다.
이때 사람들이 실제 프로덕션 용어로 설명하게 해 보세요. “이 통이 가득 차는 게 우리 메시지 큐 백로그예요.” “여기 쌓인 더미가 DB 커넥션 풀 포화 상태입니다.” 같은 식으로요.
4. 완화책을 하나씩 얹어 보기
이제 하나씩 추가해 봅니다.
- Bounded retries (작은 재시도 컵)
- Jitter (시간을 흩뿌린 재시도 투입)
- Deadlines (타이머나 트랙)
- Retry scopes (재시도 금지 구역)
- 메시지 큐와 용량 제한
각 완화책이 흐름을 어떻게 바꾸는지 관찰하고, 거기서 나온 인사이트를 실제 엔지니어링 태스크로 옮겨 적습니다.
결론
복잡한 분산 시스템은 다이어그램과 대시보드만으로 이해하기 어렵습니다. 특히 연쇄 장애는 우리의 직관이 닿지 않는 틈을 파고듭니다.
아날로그 인시던트 샌드 테이블은 그리스의 아박스부터 군사용 샌드 테이블까지 이어지는 오래된 아이디어를 바탕으로, 팀이 자신의 시스템을 눈으로 보는 새로운 방식을 제공합니다. 모래가 흘러가고, 쌓이고, 넘치는 모습을 보는 순간, 다음과 같은 것들이 훨씬 쉬워집니다.
- 작은 문제가 어떻게 시스템 전체 장애로 커지는지 이해하기
- 새로운 팀원이나 비기술 이해관계자에게 장애 양상을 설명하기
- Bounded retries, jitter, deadlines, 견고한 메시징 같은 완화책을 설계·검증하기
완벽한 물리 모델도, 거창한 장비도 필요 없습니다. 쟁반 하나, 모래 한 줌, 그리고 호기심 많은 팀이면 충분합니다. 이렇게 하면 지금까지는 보이지 않던 장애의 역학을 손가락으로 가리키고, 함께 논의하고, 무엇보다 다음 새벽 2시 인시던트가 오기 전에 고칠 수 있는 것으로 바꿀 수 있습니다.