Articlestripe.com·2024년 6월 6일·0

How Stripe’s document databases supported 99.999% uptime with zero-downtime data migrations

Quick Summary

Stripe는 MongoDB Community 기반의 자체 DBaaS인 DocDB와 데이터 이동 플랫폼을 구축해 초당 500만 건 이상의 쿼리를 처리하면서도, 데이터 정합성과 원본 샤드 성능을 보존하는 클라이언트 투명형 무중단 마이그레이션을 구현했다.

How Stripe’s document databases supported 99.999% uptime with zero-downtime data migrations 관련 대표 이미지

🖼️ 인포그래픽

How Stripe’s document databases supported 99.999% uptime with zero-downtime data migrations 내용을 설명하는 본문 이미지

🖼️ 4컷 인포그래픽

How Stripe’s document databases supported 99.999% uptime with zero-downtime data migrations 내용을 설명하는 본문 이미지

💡 한 줄 요약

Stripe는 MongoDB Community 기반의 자체 DBaaS인 DocDB와 데이터 이동 플랫폼을 구축해 초당 500만 건 이상의 쿼리를 처리하면서도, 데이터 정합성과 원본 샤드 성능을 보존하는 클라이언트 투명형 무중단 마이그레이션을 구현했다.

📌 핵심 요약

  • Stripe의 DocDB는 MongoDB Community와 자체 개발 서비스로 구성되며, 2,000개가 넘는 샤드에 분산된 페타바이트 규모의 금융 데이터를 대상으로 초당 500만 건 이상의 쿼리를 처리한다.
  • DocDB는 프록시 서버, 청크 메타데이터 서비스, 논리·물리 데이터베이스, 복제 세트와 변경 데이터 캡처 파이프라인을 결합해 샤딩된 데이터를 일관되게 조회하고 관리한다.
  • 데이터 이동 플랫폼은 샤드 분할과 통합뿐 아니라 데이터베이스 엔진의 주요 버전 업그레이드, 대형 사용자의 단일 테넌시 전환 등 다양한 온라인 데이터 이동 작업을 수행한다.
  • 마이그레이션은 시점 T의 스냅샷을 대상 샤드에 적재한 뒤 이후 변경 사항을 비동기로 복제하며, 정렬된 삽입 순서를 활용해 벌크 적재 처리량을 10배 높였다.
  • 트래픽 전환에는 버전 토큰 기반 게이팅을 적용해 원본 샤드의 요청을 짧게 차단하고 미처리 변경 사항을 동기화한 다음, 청크 메타데이터의 경로를 대상 샤드로 변경한다.

🧩 주요 포인트

  1. 소수의 초대형 샤드를 수천 개의 작은 샤드로 전환함으로써, 트래픽 변화에 따라 샤드를 분할하거나 통합할 수 있는 탄력적 DBaaS 기반을 마련했다.
  2. 스냅샷 적재와 변경 데이터 캡처 기반 복제를 분리함으로써, 대용량 데이터를 옮기면서도 원본 샤드의 사용자 쿼리 처리량에 미치는 영향을 줄였다.
  3. 양방향 복제와 버전 토큰 기반 전환을 결합함으로써, 대상 샤드에서 문제가 발생할 경우 원본으로 트래픽을 되돌릴 수 있는 복구 가능성을 유지했다.

🧠 상세 정리

1. 대규모 결제 인프라가 요구한 신뢰성

Stripe는 2023년에 총 1조 달러의 결제 규모를 처리하면서 99.999%의 가동 시간을 유지했다. 이 결제 API의 기반 계층으로 사용되는 DocDB는 MongoDB Community를 확장하고 Stripe가 자체 개발한 여러 서비스를 결합한 DBaaS다. DocDB는 제품 애플리케이션에서 발생하는 초당 500만 건 이상의 쿼리와 1만 개가 넘는 서로 다른 쿼리 형태를 처리한다. 데이터 규모도 페타바이트 수준이며, 5,000개가 넘는 컬렉션이 2,000개 이상의 데이터베이스 샤드에 분산돼 있다. 이러한 운영 규모 때문에 데이터 이동 과정에서도 가용성, 정합성, 지연 시간과 사용자 쿼리 처리량을 동시에 보존하는 것이 핵심 요구사항이 됐다.

2. MongoDB 기반 자체 DBaaS를 구축한 이유

Stripe는 2011년 서비스를 시작할 때 문서 모델의 유연성과 대규모 실시간 데이터 처리 능력, 개발 생산성을 이유로 MongoDB를 온라인 데이터베이스로 선택했다. 당시에는 Stripe의 요구조건을 충족하는 관리형 서비스가 존재하지 않았기 때문에 클라우드에서 MongoDB 인스턴스를 직접 운영하는 방식을 택했다. 필요한 시스템은 높은 가용성·내구성·성능뿐 아니라, 부적절한 쿼리로 발생할 수 있는 장애를 막기 위한 제한된 데이터베이스 기능도 제공해야 했다. 여기에 강제 할당량을 포함한 멀티테넌시와 권한 정책에 기반한 접근 통제까지 필요했다. Stripe는 이 요구를 충족하기 위해 MongoDB를 저장 엔진으로 사용하되, 온라인 데이터 마이그레이션을 핵심 기능으로 삼는 DocDB를 자체 구축했다.

3. 프록시와 메타데이터 중심의 샤딩 구조

Stripe의 제품 애플리케이션은 Go로 자체 개발된 데이터베이스 프록시 서버를 통해 DocDB에 접근한다. 프록시는 쿼리를 분석해 관련 샤드 하나 또는 여러 개로 전달하고, 각 샤드의 결과를 결합한 뒤 애플리케이션에 반환하면서 안정성, 확장성, 승인 제어와 접근 제어를 집행한다. 프록시가 수천 개의 샤드 가운데 목적지를 찾을 수 있도록 청크 메타데이터 서비스가 데이터 청크와 샤드 사이의 대응 관계를 관리한다. 애플리케이션 팀은 하나 이상의 컬렉션을 담는 논리 데이터베이스를 사용하지만, 실제 데이터는 컬렉션의 작은 부분을 보관하는 여러 물리 데이터베이스에 분산된다. 각 물리 데이터베이스는 기본 노드와 여러 보조 노드로 구성된 복제 세트에서 실행되며, 복제와 자동 장애 전환을 지원한다.

4. 탄력적 운영을 위한 데이터 이동 플랫폼

데이터 이동 플랫폼은 처음에는 MongoDB의 컴퓨팅 및 저장 공간에 대한 수직 확장 한계를 극복하기 위한 수평 확장 수단으로 개발됐다. 이후 활용 범위가 넓어져 사용률이 낮은 샤드의 통합, 데이터베이스 엔진의 주요 버전 업그레이드, 대형 사용자의 멀티테넌트 환경을 단일 테넌트 환경으로 전환하는 작업에도 사용됐다. 이를 통해 Stripe는 각각 수십 테라바이트를 보유한 소수의 샤드 구조에서, 원래보다 훨씬 작은 데이터 조각을 담는 수천 개의 샤드 구조로 이동했다. 플랫폼은 트래픽 급증 시 샤드를 분할하고 트래픽이 낮을 때 여러 데이터베이스를 빈 패킹 방식으로 통합할 수 있게 한다. 핵심은 이러한 데이터 이동을 애플리케이션 클라이언트가 인식하지 않아도 되는 방식으로 수행해 탄력적인 DBaaS 운영을 가능하게 하는 것이다.

5. 온라인 마이그레이션의 네 가지 핵심 조건

Stripe는 마이그레이션 도중 원본과 대상 샤드의 데이터가 일관되고 완전하게 유지돼야 한다는 조건을 가장 먼저 제시했다. 결제를 사용하는 수백만 기업 때문에 장시간 중단은 허용되지 않으며, 핵심 전환 단계는 일반적으로 수초가 걸리는 계획된 기본 노드 장애 전환보다 짧고 애플리케이션의 재시도 허용 범위 안에 있어야 했다. 또한 임의 개수의 원본과 대상 사이에서 크기가 서로 다른 데이터 청크를 고처리량으로 옮기고, 전체 시스템이나 개별 샤드가 동시에 참여할 수 있는 마이그레이션 수를 인위적으로 제한하지 않아야 했다. 일부 샤드가 테라바이트 규모이기 때문에 작은 단위의 이동만 지원하는 방식으로는 충분하지 않았다. 무엇보다 마이그레이션 작업이 원본 샤드의 읽기 처리량을 소모해 사용자 쿼리의 성능과 가용 처리량을 떨어뜨리지 않아야 했다.

6. 스냅샷 적재와 삽입 순서 최적화

데이터 이동 플랫폼의 Coordinator는 먼저 이동할 청크와 원본·대상 샤드를 청크 메타데이터 서비스에 등록하고, 대상 샤드에 필요한 인덱스를 생성하도록 관련 서비스를 호출한다. 이어서 특정 시점 T의 원본 청크 스냅샷을 만들고, 필터 조건에 맞는 데이터만 하나 이상의 대상 샤드로 대량 적재한다. 초기에는 쓰기 배치와 DocDB 엔진 설정 조정만으로 벌크 적재 병목을 해결하려 했지만 효과가 제한적이었다. Stripe는 DocDB가 B-트리로 데이터를 배치한다는 점에 착안해 컬렉션에서 가장 일반적인 인덱스 속성을 기준으로 데이터를 정렬한 뒤 그 순서대로 삽입했다. 그 결과 인접한 위치에 쓰기가 집중되면서 벌크 쓰기 처리량이 기존보다 10배 향상됐다.

7. 변경 데이터 복제와 정합성 검증

스냅샷 적재가 끝나면 시스템은 시점 T 이후 원본 청크에서 발생한 쓰기 변경 사항을 대상 샤드로 비동기 복제한다. 각 DocDB 샤드의 연산 로그에는 데이터를 변경한 작업이 기록되며, 이 이벤트는 Kafka로 전달된 뒤 클라우드 객체 저장소에 보관되는 변경 데이터 캡처 파이프라인을 거친다. 복제 서비스는 이 이벤트를 사용하므로 원본 샤드에서 데이터를 다시 읽어 사용자 쿼리에 필요한 처리량을 소비하지 않고, 원본 샤드의 연산 로그 보존 크기에도 제약받지 않는다. 서비스는 대상 샤드의 일시적 가용성 문제를 견디고 체크포인트에서 동기화를 시작·일시정지·재개할 수 있으며 복제 지연도 제공한다. 원본과 대상 사이의 변경 사항은 순환 복제를 막는 태그와 함께 양방향으로 복제되고, 동기화 후에는 처리량 영향을 피하기 위해 동일 시점의 스냅샷을 비교해 완전성과 정확성을 검증한다.

8. 버전 토큰을 이용한 짧고 안전한 트래픽 전환

데이터 적재와 변경 복제가 진행 중인 상태에서 Coordinator는 읽기와 쓰기를 대상 샤드로 넘기는 트래픽 전환을 수행한다. 평상시 각 프록시 서버는 DocDB 샤드로 보내는 요청에 버전 토큰을 붙이며, Stripe는 샤드가 자신이 알고 있는 값보다 새로운 토큰이 포함된 요청만 처리하도록 MongoDB를 수정했다. 경로를 변경할 때는 먼저 원본 샤드의 특수 컬렉션에 저장된 버전 토큰 값을 높여 해당 청크에 대한 기존 읽기와 쓰기를 잠시 거부한다. 그다음 복제 서비스가 원본에 남아 있는 모든 쓰기를 대상에 반영할 때까지 기다린다. 마지막으로 청크 메타데이터 서비스에서 청크의 목적지와 버전 정보를 대상 샤드 기준으로 갱신해 프록시가 읽기와 쓰기를 새 위치로 전달하도록 한다.

🧾 핵심 주장 / 시사점

  • DocDB의 탄력성은 단순히 샤드 수를 늘리는 데서 나오지 않고, 데이터 위치를 나타내는 메타데이터와 실제 데이터 이동 절차를 함께 제어하는 구조에서 나온다.
  • B-트리의 배치 특성을 고려한 정렬 삽입이 처리량을 10배 높인 사례는, 대규모 적재 성능이 배치 크기나 엔진 설정뿐 아니라 쓰기 순서에도 크게 좌우될 수 있음을 보여준다.
  • 변경 데이터 캡처 파이프라인을 복제 입력으로 재사용함으로써, 마이그레이션이 원본 샤드의 사용자 쿼리용 읽기 처리량과 직접 경쟁하는 문제를 피했다.

✅ 액션 아이템

  • DocDB식 무중단 이전을 위해 스냅샷 적재와 변경 데이터 캡처 복제를 분리하는 기준을 정의한다.
  • 샤드 분할·통합과 엔진 메이저 업그레이드 등 온라인 이동 대상 범위를 우선순위로 정리한다.
  • 버전 토큰 게이팅과 양방향 복제로 짧은 차단 후 메타데이터 경로 전환·원본 복귀 조건을 점검한다.

❓ 열린 질문

  • 초당 500만 쿼리·2,000개 이상 샤드 환경에서 원본 쿼리 처리량 영향의 허용 한도는 어디까지인가?
  • 정렬 삽입으로 벌크 적재 처리량을 10배 올린 방식이 모든 데이터 패턴에 같은 효과를 내는가?
  • 대상 샤드 장애 시 원본으로 되돌리는 판단은 어떤 정합성·지연 기준으로 내릴 것인가?

관련 문서

공통 태그와 주제 흐름을 기준으로 같이 보면 좋은 문서를 이어서 제안합니다.