Figma 데이터베이스 팀이 대 (새 탭에서 열림)
제시해주신 Figma의 기술 블로그 글 **"The growing pains of database architecture"**는 급격한 성장 과정에서 단일 Postgres 데이터베이스의 한계를 극복하기 위해 Figma 엔지니어링 팀이 수행한 아키텍처 혁신 과정을 다루고 있습니다. 이 글은 수직적 확장이 불가능한 시점에서 어떻게 가동 중단 없이 수평적 확장(Sharding) 체제로 전환했는지에 대한 기술적 여정을 상세히 설명합니다. --- Figma는 사용자 트래픽의 폭발적인 증가로 인해 AWS RDS의 가장 큰 인스턴스조차 감당할 수 없는 병목 현상에 직면했습니다. 이를 해결하기 위해 단순한 읽기 복제본 추가를 넘어, 데이터를 기능별로 나누는 '수직적 분할'과 동일 테이블을 여러 장비에 분산하는 '수평적 샤딩'을 단계적으로 도입했습니다. 결과적으로 Figma는 데이터베이스를 유연하게 확장할 수 있는 구조를 갖추게 되었으며, 이는 서비스 안정성과 성능을 획기적으로 향상시켰습니다. ### 수직적 확장의 한계와 초기 대응 * **단일 DB의 임계치 도달:** 초기에는 단일 AWS RDS 인스턴스에 모든 데이터를 저장했으나, 쓰기 작업량이 r5.24xlarge 등 최고 사양 인스턴스의 처리 용량을 넘어섰습니다. * **읽기 복제본(Read Replicas)의 활용:** 읽기 트래픽은 복제본을 통해 분산했으나, 데이터 수정이 빈번한 작업 특성상 복제 지연(Replication Lag)이 발생하여 사용자 경험에 악영향을 주었습니다. * **수직적 테이블 분할 (Vertical Partitioning):** 첫 번째 해결책으로 관련 있는 테이블들을 묶어 별도의 데이터베이스 인스턴스로 분리했습니다. 이는 단기적으로 부하를 분산했지만, 테이블 간 Join 쿼리가 불가능해지고 트랜잭션 관리가 복잡해지는 비용이 발생했습니다. ### 수평적 샤딩(Horizontal Sharding) 도입 과정 * **샤드 키(Shard Key) 선정:** 특정 테이블(예: 파일, 레이어)이 너무 커져서 단일 인스턴스에 담을 수 없게 되자, 데이터를 행(Row) 단위로 분산하는 샤딩을 결정했습니다. '조직 ID(Org ID)'를 주요 샤드 키로 설정하여 관련 데이터를 동일한 물리적 위치에 배치했습니다. * **쿼리 라우팅 계층 구축:** 애플리케이션과 DB 사이에 쿼리를 적절한 샤드로 전달하는 중간 계층(Query Router)을 직접 구현했습니다. 이를 통해 애플리케이션 코드는 데이터가 어느 물리적 서버에 있는지 몰라도 쿼리를 수행할 수 있게 되었습니다. * **Vitess의 검토와 채택:** 처음에는 자체 솔루션을 사용했으나, 관리의 복잡성을 줄이기 위해 오픈소스 데이터베이스 클러스터링 시스템인 Vitess 도입을 결정하고 이를 Postgres 환경에 맞게 최적화했습니다. ### 무중단 데이터 마이그레이션 전략 * **섀도우 쓰기(Shadow Writes):** 새로운 샤딩 환경을 구축한 후, 실시간 데이터를 기존 DB와 신규 DB에 동시에 기록하며 시스템의 안정성을 검증했습니다. * **데이터 검증(Data Validation):** 스냅샷 비교와 실시간 체크섬 확인을 통해 기존 데이터와 샤딩된 데이터 간의 일관성을 100% 보장했습니다. * **점진적 전환(Canary Rollout):** 전체 트래픽을 한 번에 옮기지 않고, 일부 사용자나 조직부터 단계적으로 신규 아키텍처로 전환하여 리스크를 최소화했습니다. ### 운영 효율화를 위한 도구 및 인프라 * **DBProxy 개발:** 수만 개의 애플리케이션 연결을 효율적으로 관리하기 위해 고성능 커넥션 풀링(Connection Pooling)과 쿼리 분석 기능을 갖춘 DBProxy를 구축했습니다. * **가시성(Observability) 확보:** 샤드별 부하 상태, 쿼리 성능, 복제 지연 등을 실시간으로 모니터링할 수 있는 대시보드를 구축하여 병목 지점을 즉각 파악하도록 했습니다. --- **결론 및 추천** Figma의 사례는 서비스 초기부터 복잡한 샤딩을 도입하기보다는, **수직적 분할 → 논리적 샤딩 → 물리적 샤딩**으로 이어지는 단계적 접근이 실무적으로 유효함을 보여줍니다. 데이터베이스 확장을 고민하는 팀이라면 처음부터 완벽한 분산 시스템을 구축하기보다, 데이터 간의 관계를 분석하여 적절한 샤드 키를 선정하고 쿼리 라우팅 계층을 추상화하는 작업부터 시작할 것을 권장합니다.