[기술리포트] 클라우드 네이티브 4편 : 상태 관리와 데이터 일관성 - 안정성·신뢰성 확보 전략

Tech Story/Cloud Architecture

[기술리포트] 클라우드 네이티브 4편 : 상태 관리와 데이터 일관성 - 안정성·신뢰성 확보 전략

 

 
[ kt cloud Cloud컨설팅팀 심대섭 님 ]

📋 요약

이 글에서는 클라우드 네이티브 환경에서 상태를 분리하고 데이터 일관성을 유지하여
시스템의 가용성을 확보하는 설계 전략을 다룹니다.
분산 시스템에서 발생할 수 있는 장애와 데이터 불일치 위험을 최소화하고,
비즈니스 연속성을 지키기 위한 실무적인 운영 방향을 정리합니다.

 

#클라우드네이티브 #상태관리 #데이터일관성 #분산트랜잭션 #고가용성


cloud native 가용성은 ‘상태 설계’가 좌우한다.

 

[기술리포트] 클라우드 네이티브 4편 : 상태 관리와 데이터 일관성 - 안정성·신뢰성 확보 전략

인터넷에서 쇼핑을 하다 보면, 분명히 담아둔 상품이 어느 순간 장바구니에서 사라져 보이는 경험이 있습니다. 사용자는 “버그인가?”라고 느끼지만, 시스템 관점에서는 상태(state)가 끊기거나 지연된 값을 읽는 전형적인 신호인 경우가 많습니다.

 

이유는 대개 세 가지 중 하나입니다. 첫째, 장바구니를 앱 서버 메모리에 두는 바람에 로드밸런서가 다른 인스턴스로 요청을 보내면 상태가 이어지지 않습니다. 둘째, 스티키 세션에 기대고 있다가 오토스케일이나 재시작으로 라우팅이 바뀌면 ‘초기화된 것처럼’ 보일 수 있습니다. 셋째, 멀티 존·리전 구성에서 쓰기와 읽기 경로가 갈리면 복제 지연 시점의 데이터를 읽어 장바구니가 비어 보이기도 합니다.

 

cloud native가 말하는 stateless는 ‘상태를 없애라’가 아니라 ‘상태를 앱 서버에서 분리하라’에 가깝습니다. 로그인 세션, 장바구니, 결제 같은 핵심 데이터는 어딘가에 반드시 남아야 합니다. 그래서 4편은 “데이터(상태) 관점에서의 가용성”을 여섯 가지 키워드로 나눠 정리합니다.


1. Stateless 설계와 세션 관리

핵심은 간단합니다. 앱 서버가 상태를 들고 있지 않아야 인스턴스를 마음껏 갈아끼울 수 있습니다. 서버 메모리(또는 로컬 디스크)에 세션·장바구니를 두면, 오토스케일·재배치·장애 복구가 곧바로 사용자 경험 붕괴로 연결됩니다.

 

실무에서는 서버는 연산만 하고, 상태는 외부 저장소로 분리합니다. 세션/장바구니는 Redis 같은 공용 저장소에, 핵심 트랜잭션은 DB에 두는 식으로 “상태의 거처”를 명확히 나누는 순간부터 가용성 설계가 쉬워집니다.

세션·장바구니처럼 “사용자 경험을 즉시 흔드는 상태”는 서버 밖(공용 저장소)으로 분리한다.

2. 분산 데이터 정합성 전략: strong vs eventual

분산 시스템에서 네트워크 단절(파티션)은 현실입니다. 특히 파티션이 발생한 순간, 시스템은 동시에 두 가지를 다 만족시키기 어렵습니다.

  • 모든 요청에 오류 없이 응답(가용성)
  • 언제나 동일한 정답을 보장(강한 정합성)

그래서 정합성은 “기술 선택” 이전에 “데이터별 정책”입니다. 결제 승인·재고 차감·권한 변경처럼 틀리면 사고가 되는 데이터는 강한 정합성을 택해야 합니다. 반대로 피드·통계·검색 인덱스·알림처럼 잠깐 늦거나 어긋나도 되는 데이터는 최종 일관성을 전제로 설계하는 편이 가용성과 비용 측면에서 현실적입니다.

틀리면 사고인 데이터만 강하게, 나머지는 최종 일관성+UX/운영정책으로 감당한다.

3. 데이터 복제와 장애 도메인: multi-AZ/multi-region, RPO/RTO

상태를 외부 저장소로 분리했다면 다음 질문은 “그 저장소가 죽을 때 어떻게 되나”입니다. 멀티 AZ·리전 구조에서 복제 방식은 곧 가용성의 성격을 결정합니다. 여기서 복제는 “정합성 자체를 자동 보장한다”기보다, 장애 시 데이터 유실 허용 범위(RPO)와 복구 시간(RTO)을 어떤 수준으로 가져갈지에 직접 연결됩니다.

  • 동기 복제는 RPO를 줄이는 데 유리하지만, 네트워크 지연이 곧 쓰기 지연으로 이어질 수 있습니다
  • 비동기 복제는 응답과 확장성에 유리하지만, 짧은 구간의 데이터 유실 가능성(RPO)이 남을 수 있습니다

중요한 건 ‘무조건 동기’나 ‘무조건 비동기’가 아니라, 데이터 등급에 따라 RPO/RTO 목표를 먼저 두고 복제 전략을 맞추는 접근입니다. 핵심 트랜잭션과 비핵심 데이터가 동일한 복제 정책을 쓰면 비용이 폭증하거나, 반대로 사고 확률이 올라갑니다.

RPO/RTO 목표를 데이터 등급으로 나누고, 복제 방식은 그 목표를 충족하는 최소 비용으로 설계한다.

4. 분산 트랜잭션 패턴: saga와 outbox

마이크로서비스로 갈수록 “한 번에 전부 성공/전부 실패”라는 단일 트랜잭션 감각은 무너집니다. 주문 생성, 결제 승인, 재고 차감이 서로 다른 서비스/DB에 있으면, 전통적인 분산 트랜잭션(예: 2PC)로 억지로 묶는 순간 지연과 운영 리스크가 급격히 커집니다.

그래서 실무에서 많이 쓰는 해법이 saga와 outbox입니다.

  • saga는 로컬 트랜잭션을 단계적으로 진행하고, 실패 시 보상(취소/환불/복구)으로 결과를 맞춥니다
  • outbox는 “DB 저장은 됐는데 이벤트 발행이 실패” 같은 불일치를 줄이기 위해, 이벤트를 같은 커밋으로 기록하고 별도 릴레이로 발행합니다. 다만 대부분의 메시징 환경에서는 이벤트가 중복 전달될 수 있으므로, 소비자(consumer) 측에서 중복 처리(멱등성)나 중복 제거를 전제로 설계하는 편이 안전합니다

둘을 결합하면 “즉시 완벽”은 아니어도 운영 가능한 정합성을 만들 수 있고, 그게 곧 서비스 가용성의 바닥을 올립니다.

서비스/DB가 둘 이상이면 ‘단일 트랜잭션’ 환상을 버리고 saga·outbox로 운영 가능한 정합성을 설계한다.

5. 충돌 처리와 데이터 모델링: CQRS, 샤딩, LWW

파티션/복제 지연이 있는 환경에서 특히 다중 쓰기(멀티 라이터)를 허용하거나 비동기 복제·최종 일관성을 선택한 경우, 충돌 처리는 설계의 일부가 됩니다. 중요한 건 “충돌을 없애겠다”가 아니라 “충돌이 생겨도 비즈니스가 망가지지 않게 하겠다”입니다.

대표적인 방향은 세 가지로 정리됩니다.

  • CQRS: 쓰기(정답 생성)와 읽기(조회)를 분리해, 조회는 빠르게, 정답은 단계적으로 맞춘다
  • 샤딩/파티셔닝: 같은 데이터에 동시 쓰기가 몰리지 않게 구조적으로 회피한다
  • LWW: 마지막 값 우선 같은 단순 규칙은 편하지만 조용한 데이터 손실 위험이 있으니 “안전한 범위”에만 제한적으로 쓴다
충돌이 허용되는 데이터만 ‘충돌 전략’을 쓰고, 허용되지 않는 데이터는 쓰기 경로를 단일화한다.

6. 캐시/회복력 패턴: fallback, circuit breaker

캐시는 성능을 올리지만, 캐시가 장애의 기점이 되는 순간이 있습니다. 캐시 미스가 한꺼번에 발생하면 DB로 트래픽이 쏟아지는 현상(캐시 관통/폭주)으로 전체 장애가 확대될 수 있습니다. 그래서 캐시는 “빠르게 만드는 도구”가 아니라 “가용성을 지키는 장치”로 다뤄야 합니다.

 

실무 포인트는 단순합니다.

  • 캐시가 비어도 시스템이 버티도록 기본값·대체 경로(fallback)를 준비한다
  • 외부 저장소가 느려지면 요청을 계속 누적시키지 말고 차단/완화(circuit breaker)한다
  • 폭주를 막는 백오프/지터 같은 완화 기법을 적용해 확산을 줄인다
캐시는 “없어도 버티는 구조” 위에 얹고, 느려지면 빨리 끊고(fail fast) 확산을 막는다.

[기술리포트] 클라우드 네이티브 4편 : 상태 관리와 데이터 일관성 - 안정성·신뢰성 확보 전략
Image: AI-Generated Content

데이터 관점의 가용성은 ‘정책+패턴’으로 완성된다

 

4편의 결론은 단순합니다. cloud native에서 서버는 언제든 죽고 바뀌는 전제를 받아들이는 대신, 상태가 흔들릴 때도 서비스가 깨지지 않게 만드는 전략이 필요합니다. 그 전략은 정합성 선택(데이터별 정책)과 분산 트랜잭션 패턴(saga·outbox), 그리고 복제·캐시·충돌 처리 같은 운영 설계로 구성됩니다.

 

정리하면 다음 세 가지입니다.

  1. 앱 서버는 stateless를 지향하고, 상태는 성격에 따라 외부 저장소로 분리한다
  2. 정합성은 데이터별로 강약을 나누고, 파티션 상황의 우선순위를 합의한다
  3. 분산 환경의 정합성은 saga·outbox 같은 패턴으로 “운영 가능한 수준”을 만든다

이어지는 5편에서는 이런 설계가 실제 극한 상황에서도 유지되는지 검증하는 카오스 엔지니어링을 다룹니다.

 

 

kt cloud 플랫폼 바로가기

❓ 자주 묻는 질문 (FAQ)

Q1. Stateless(무상태) 설계가 가용성에 왜 중요한가요?
A1. 애플리케이션이 특정 서버에 상태를 들고 있지 않아야 인스턴스를 언제든 교체·증설할 수 있기 때문입니다.
로그인 세션이나 장바구니를 서버 메모리에 두면, 로드밸런서가 다른 인스턴스로 보냈을 때 상태가 사라져 보이거나 서버 장애 시 사용자 경험이 즉시 깨집니다. 따라서 서버는 stateless로 두고, 세션·장바구니 같은 상태는 Redis 등 외부 저장소로 분리해야 장애 복구와 확장이 자연스럽게 됩니다.
Q2. 모든 데이터를 실시간으로 완벽하게 일치시켜야 하나요?
A2. 아닙니다. 네트워크 단절(파티션)이 생기면 “항상 같은 정답”과 “항상 응답”을 동시에 만족시키기 어렵습니다.
결제 승인·재고 차감·권한 변경처럼 틀리면 사고가 되는 데이터는 강한 정합성을 선택해야 하고, 피드·알림·검색 인덱스·통계처럼 잠깐 늦어도 되는 데이터는 최종 일관성을 전제로 설계하는 편이 현실적입니다. 중요한 건 데이터별로 ‘정확성이 먼저인지, 응답이 먼저인지’를 합의하는 것입니다.
Q3. 네트워크 오류로 같은 요청이 여러 번 들어오면 어떻게 하나요?
A3. 재시도 환경에서는 “중복 요청을 한 번만 처리”하는 서버 측 장치가 필요합니다. 결제·주문 생성처럼 중복 처리 자체가 사고인 작업은 요청 식별자를 기준으로 처리 이력을 확인하고, 이미 처리된 요청이면 같은 결과를 반환해야 합니다. 이렇게 해야 재시도를 가용성 전략으로 활용하면서도 중복 결제·중복 주문을 예방할 수 있습니다.

📚 관련/출처

  1. Amazon Web Services, 「AWS Well-Architected Framework – Reliability Pillar」 백서 (2023)
  2. Microsoft Azure, 「Cloud Design Patterns – Data Management and Caching」 아키텍처 가이드 (2023)
  3. Google Cloud, 「Building Resilient, Low-Latency Services on GKE」 기술 문서 (2024)
  4. Google SRE 팀, 「Site Reliability Engineering – Distributed State and Consensus」 도서 및 온라인 문서 (2016, 2023 개정판 기준)
  5. Martin Kleppmann, 「Designing Data-Intensive Applications」 O’Reilly Media (2017)
  6. Eric Brewer, 「CAP Twelve Years Later: How the ‘Rules’ Have Changed」 IEEE Computer (2012)
  7. Pat Helland, 「Data on the Outside vs. Data on the Inside」 CIDR Conference 논문 (2005)
  8. CNCF, 「Cloud Native Definition and Cloud Native Landscape」 프로젝트 문서 (2023)
  9. Redis, PostgreSQL, Kafka 등 주요 데이터 시스템 벤더의 고가용성·복제·일관성 관련 공식 기술 문서 (2022~2024)
  10. 국내외 주요 인터넷 서비스 기업의 장애 공개 보고서(Postmortem) 및 기술 블로그 (2019~2024)