Etsy의 데이터베이스 샤딩을 Vitess로 마이그레이션

발행: (2026년 3월 20일 AM 06:03 GMT+9)
20 분 소요

Source: Etsy Engineering

Etsy의 샤드된 MySQL 아키텍처

Etsy는 2010년경부터 샤드된 MySQL 아키텍처를 유지해 왔습니다. 이 데이터베이스 클러스터는 Etsy의 대부분 온라인 데이터를 포함하고 있으며 ~1,000개의 테이블이 ~1,000개의 샤드에 분산되어 있습니다. 지난 16년 동안 크게 성장했습니다:

  • 전체 크기: > 425 TB의 데이터
  • 처리량: ≈ 1.7 백만 요청/초

ORM 작동 방식

  • Etsy 엔지니어는 독점 객체‑관계 매핑(ORM) 을 통해 MySQL 데이터에 접근합니다.
  • ORM은 각 MySQL 테이블에 해당하는 모델을 가지고 있습니다.
  • 테이블이 샤드될 경우, 행은 서로 다른 데이터베이스(샤드)로 파티셔닝됩니다.
  • 각 샤드는 동일한 테이블 스키마를 가지며 전체 행 중 별도의 하위 집합을 포함합니다.

샤드파이어 ID

  • 샤드된 테이블은 모델에 고유한 ID 필드, 즉 “샤드파이어 ID” 가 필요하며, 이는 각 레코드가 속할 샤드를 결정합니다.
  • 샤드파이어 ID는 관련 데이터를 동일한 샤드에 배치하도록 설계되어, 쿼리 시 필요한 데이터베이스 수를 최소화합니다(예: 하나의 상점이나 사용자의 모든 레코드가 같은 샤드에 존재).
  • 대부분의 모델은 shop_id 또는 user_id 를 샤드파이어 ID로 사용하지만, > 30개의 다양한 옵션이 사용되고 있습니다.

레거시 인덱스 데이터베이스

  • Vitess 도입 이전에, ORM은 레코드 → 샤드 매핑을 단일, 샤드되지 않은 “인덱스” 데이터베이스에 저장했습니다.
  • 레코드가 생성될 때, ORM은 무작위로 샤드를 선택하고 매핑을 인덱스 DB에 저장한 뒤, 이후 라우팅을 위해 이를 조회했습니다.

쿼리 흐름:

  1. ORM이 인덱스 DB에 샤드 매핑을 요청합니다.
  2. ORM이 실제 쿼리를 해당 샤드에 전송합니다.

샤드 아키텍처의 장점

  • 확장성 – 다수의 샤드에 걸친 수평적 성장.
  • 복원력 – 단일 샤드 장애가 전체 트래픽의 ~1/1000에만 영향을 미침.

단점

  • 수동적이고 복잡한 확장 – 새로운 샤드 추가에 수개월이 소요됨.
  • 단일 장애 지점 – 인덱스 데이터베이스가 다운되면 전체 사이트가 중단될 수 있음.
  • 개발자 마찰 – 제품 개발자가 샤딩을 이해하고 관리해야 했으며, 이는 종종 혼란스럽고 번거로웠음.

Etsy와 인덱스 데이터베이스가 성장함에 따라 인덱스‑DB 가용성 문제와 관련된 사고가 증가했으며, 이러한 취약점을 해결하는 것이 높은 우선순위가 되었습니다.

Vitess 소개

2018년에 우리는 Vitess(대규모 MySQL 클러스터를 확장·배포·관리하기 위한 오픈소스 추상화 레이어)를 아키텍처에 추가했습니다.

마이그레이션 단계

  1. 초기 통합 – ORM이 여전히 Vitess에 어떤 샤드를 조회할지 알려주어, 샤드 로직을 Vitess로 옮기기 전에 새로운 구성 요소들을 검증할 수 있었습니다.
  2. vindex 탐색 – Vitess “vindex”는 Vitess 내부에서 샤딩 전략을 정의하며, 이전에 사용하던 shardifier‑id → 샤드 매핑과 유사합니다.

우리는 먼저 여러 비샤드 결제 테이블을 확장하여, 바로 사용할 수 있는 Vitess vindex를 활용할 수 있는 새로운 샤드 클러스터를 만들었습니다. 이 파일럿의 성공은 기존 사내 샤드 인프라를 Vitess vindex로 마이그레이션하는 길을 열어주었습니다.

Vindex 선택

Vitess는 다양한 vindex를 제공합니다. 우리는 샤드 알고리즘을 계산하는 vindex(예: hash vindex)에 집중하여 외부 조회 저장소에 대한 의존성을 없앴습니다.

  • ORM의 샤드 매핑은 무작위이며 알고리즘 기반이 아닙니다.
  • 내장된 알고리즘 vindex를 사용하려면 전체 데이터를 재샤딩해야 했으며, 이는 수년이 걸릴 수 있는 수동 작업이었습니다.

우리의 접근 방식

  1. 맞춤형 vindex 작성 – 기존 샤드 로직을 Vitess에 포팅하여 데이터를 이동하지 않고도 vindex를 테스트할 수 있게 했습니다.
  2. ORM의 샤드 할당 알고리즘을 Vitess hash vindex 알고리즘에 맞게 수정
    • 이 변경 후에는 새로운 샤드 매핑에 더 이상 인덱스‑DB 조회가 필요하지 않게 되었습니다.
  3. 기존 매핑을 읽기 전용 SQLite 데이터베이스에 저장
    • 낮은 지연 시간, 작은 용량, 각 Vitess 서버에 복사해 놓을 수 있어 외부 DB 지연을 피할 수 있습니다.
  4. SQLite 조회 vindex를 맞춤형으로 구축 – SQLite에서 샤드 정보를 읽어옵니다.
  5. 하이브리드 vindex 생성 – 임계값에 따라 두 vindex 중 하나를 선택합니다.
    • SQLite vindex: ID ≤ 임계값 (기존 레코드)
    • Hash vindex: ID > 임계값 (신규 레코드)

임계값은 샤드 할당 알고리즘을 변경한 직후에 생성된 첫 번째 ID로 설정했습니다.

우리 환경에 Vindexes 도입

맞춤형 vindexes를 적용함으로써 데이터를 이동하지 않고 Vitess vindexes를 추가할 수 있었습니다. 다음 단계는 레거시 ORM용으로 작성된 모든 기존 쿼리가 여전히 정상적으로 실행되고 Vitess‑관리 샤딩 하에서도 동일한 결과를 반환하는지 확인하는 것이었습니다.

호환성 문제

  • Vitess는 샤드 라우팅을 위해 SQL 쿼리의 WHERE 절에 샤드 식별자(ID)가 포함되어야 합니다.
  • 레거시 ORM은 이 요구사항이 없었으며, 개발자들은 종종 샤드 식별자를 SQL 문과 별도로 제공했습니다.
  • 따라서 많은 기존 쿼리에서 WHERE 절에 샤드 식별자(ID)가 누락되어 있어 라우팅 실패 가능성이 있었습니다.

우리는 다음과 같이 해결했습니다:

  1. 전체 프로덕션 쿼리를 감사하여 샤드 식별자가 누락된 경우를 식별했습니다.
  2. ORM 헬퍼를 업데이트하여 가능한 경우 자동으로 필요한 WHERE 절을 삽입하도록 했습니다.
  3. 개발자를 위한 마이그레이션 가이드를 제공하여 맞춤형 쿼리를 조정하도록 지원했습니다.

이러한 단계를 거친 후, 시스템은 레거시 아키텍처와 기능적 동등성을 유지하면서 안전하게 Vitess‑관리 샤딩으로 전환될 수 있었습니다.

Scaling Etsy Payments with Vitess – Part 3

Incremental Migration with Vindexes

ORM에는 MySQL에 접근하는 다양한 방법을 포함한 10년 이상의 쿼리가 있었으며, 모든 쿼리를 감사하는 데 많은 시간이 소요되었습니다. 각 테이블이 설계와 목적이 크게 달라 모델 변경을 테스트할 컨텍스트를 구축하는 것도 어려웠습니다.

이러한 상황에서 우리는 점진적인 접근 방식을 선택하고 vindexes를 한 번에 하나의 테이블씩 코드베이스에 도입하기로 했습니다. 이를 통해 다음을 할 수 있었습니다:

  • 작은 규모에서 테스트하여 각 데이터 접근 패턴이 Vitess와 함께 정상적으로 동작하는지 확인
  • 특정 쿼리 집합에 대해 vindexes가 어떻게 동작하는지 모니터링
  • 호환성 문제를 점진적으로 드러내어 대규모 장애 위험을 감소

수백 개의 테이블에 대해 마이그레이션을 반복해야 했기 때문에 명확하고 반복 가능한 프로세스를 만드는 것을 우선시했습니다. Etsy의 실험 프레임워크를 활용해 각 테이블마다 Vitess vindexes를 사용하는 트래픽 비율을 점진적으로 늘려가며 변경을 서서히 적용했습니다. 이를 통해 다음을 할 수 있었습니다:

  • vindexes 사용 시와 ORM 샤드 라우팅 시의 쿼리 성능을 비교
  • 문제가 발생하면 즉시 0 %로 롤백 가능

작게 시작하고 빠른 롤백 경로를 마련함으로써 모든 쿼리를 사전에 테스트하지 못하는 위험을 완화할 수 있었습니다.

Working Through Challenges: Database Transactions

초기 단계에서 데이터베이스 트랜잭션과 관련된 문제에 직면했습니다.

  • 인‑하우스 샤드 라우팅: ORM은 각 샤드를 별개의 데이터베이스로 취급하고 특정 샤드에 직접 쿼리했습니다.
  • Vitess‑관리 샤딩: ORM은 샤드들을 단일 데이터베이스처럼 쿼리했으며, Vitess는 내부에서만 이를 별개의 데이터베이스로 보여주었습니다.

이 차이로 인해 두 접근 방식은 서로 다른 연결을 사용하게 되었고, 이는 원자성 보장(원자성은 연결당 적용)을 깨뜨렸습니다. 데이터 무결성 문제를 방지하기 위해 단일 트랜잭션 내에서 쓰여지는 테이블들은 동시에 vindexes에 올려 동일한 연결을 사용하도록 해야 했습니다.

이론적으로는 간단했지만 실제로는 큰 영향을 미쳤습니다. 가장 복잡하고 핵심적인 데이터 모델인 receipts, listings, transactions와 같은 소수의 테이블이 전체 트래픽의 큰 비중을 차지하고 있었습니다. 이들 중 하나를 vindexes에 맞추는 과정에서 27개의 모델(전체 테이블의 3 %)이 데이터베이스 트래픽의 3분의 1을 발생시키며 모두 트랜잭션으로 연결되어 있음을 발견했습니다.

테이블별 전략에도 불구하고 이러한 고위험 변경은 긴밀히 결합되어 있었기에, 우리는 전사적으로 협업하여 27개 모델을 동시에 올리는 작업을 진행했습니다.

Reaping the Benefits: Cross‑Shard Queries

Vitess vindexes의 주요 장점 중 하나는 샤드 간 쿼리가 가능하다는 점입니다. 기본적으로 샤드 식별자(ID)를 포함하지 않은 모든 쿼리는 “scatter”됩니다: Vitess는 해당 쿼리를 모든 샤드에 병렬로 전송하고 결과를 정렬한 뒤 단일 결과 집합으로 반환합니다.

  • 예시: 한 모델의 쿼리 시간이 ~2 초에서 ~20 ms로 감소했습니다(크로스‑샤드 쿼리 사용 시).

하지만 Etsy 규모에서는 의도치 않게 비용이 큰 쿼리를 1,000개의 모든 샤드에 scatter하면 문제가 될 수 있습니다. 이를 방지하기 위해 우리는 다음과 같은 조치를 취했습니다:

  1. 환경에서 scatter 쿼리를 기본적으로 비활성화했습니다.
  2. 필요 시 개발자가 ORM을 통해 명시적으로 scatter를 허용할 수 있는 방법을 제공했습니다.

Bulk Primary‑Key Lookups

위에서 언급한 27개 테이블을 올리는 과정에서 scatter 쿼리를 활용하면 대량 기본키 조회에 큰 개선이 있었습니다.

  • 이전 방식: ORM은 기본키 배열을 받아 샤드별로 배치하고 각 샤드에 쿼리를 실행한 뒤 결과를 병합했습니다.
  • 새 방식: Vitess는 하나의 문장으로 여러 샤드를 동시에 조회할 수 있으므로 모든 기본키를 하나의 쿼리에 포함시켜 샤드별 배치를 없앨 수 있었습니다.

이로 인해 여러 모델에 대한 대량 조회 시 발행되는 쿼리 수가 크게 감소했습니다.

Figure: Bulk lookup queries for one model during its ramp onto vindexes.
Purple lines de

참고: vindexes를 사용하여 모델에 대한 트래픽을 1 %, 10 %, 50 %, 및 100 %로 지정합니다.

결론

5년, 약 2,500개의 풀 리퀘스트, 그리고 약 6,000개의 쿼리를 거쳐, 우리는 Etsy의 샤드 관리를 Vitess vindexes로 성공적으로 마이그레이션했습니다!

간소화된 마이그레이션 프로세스에도 불구하고, Etsy와 같은 규모와 역사를 가진 코드베이스의 데이터베이스 인프라를 교체하는 것은 여전히 도전이었습니다. 인프라 엔지니어로서 우리는 변경하는 코드와 발생할 수 있는 문제에 대한 맥락이 거의 없었습니다. 그럼에도 불구하고, Etsy 엔지니어링 전반에 걸친 협업과 신중한 테스트를 통해 우리는 목표를 달성했습니다:

  • 스케일링 작업이 더 이상 수동이 아니며, 몇 달이 아니라 며칠 안에 수행될 수 있습니다.
  • 인덱스 데이터베이스가 이제 우리 샤드 클러스터의 단일 장애 지점이 아닙니다.
  • 샤드 인프라가 개발자에게 숨겨져 데이터 모델링과 쿼리 작성을 단순화합니다.
  • 데이터베이스 성능은 크게 변하지 않아, 변경 사항이 최종 사용자에게 보이지 않습니다.
  • 우리는 점진적으로 진행했으며, 필요할 때 빠르게 롤백하고, 대규모 데이터 마이그레이션 없이 Vitess를 통합했습니다.

이제 우리는 vindexes로 마이그레이션함으로써 잠금 해제된 새로운 Vitess 기능들을 활용하게 되어 기대됩니다, 예를 들어:

  • 데이터 재샤딩.
  • 샤드 간 데이터 재균형.
  • Vitess의 MoveTable 작업을 사용하여 이전에 샤드되지 않은 테이블을 샤드하는 것.

이처럼 중요한 복잡한 인프라를 거의 다운타임 없이, 사용자에게 영향을 주지 않으면서 교체하는 것은 매우 도전적인 작업이었지만, 동시에 엄청나게 보람 있는 일이었습니다.

매우 보람찼습니다.

감사의 글

이 프로젝트는 Data Access Platform 팀의 공동 성과였습니다: Jessica Chen, Samantha Drago‑Kramer, Hermes Garcia, Sam Kenny, David Leibovic, Kyle Leiby, Benjamin Mariscal, Juan Ortega, Adam Saponara, Wendy Sung, 그리고 Stephanie Wu. 엔지니어링 전반에 걸쳐 vindex 프로젝트에 기여해 주신 모든 분들께 감사드립니다.

0 조회
Back to Blog

관련 글

더 보기 »