database-migration

3 개의 포스트

스마트스토어센터 Oracle에서 MySQL로의 무중단 전환기 (새 탭에서 열림)

네이버 스마트스토어센터는 비즈니스 성장에 따른 Oracle DBMS의 리소스 경합과 라이선스 비용 문제를 해결하기 위해 오픈소스인 MySQL로의 무중단 마이그레이션을 단행했습니다. 10년 이상의 레거시 시스템을 안정적으로 전환하기 위해 '이중 쓰기(Dual Write)' 전략을 채택했으며, 이를 통해 데이터 손실 없는 실시간 동기화와 즉각적인 롤백 가능성을 확보했습니다. 결과적으로 서비스 중단 없이 DB 환경을 성공적으로 전환하며 운영 효율성을 높였습니다. ### 이중 쓰기(Dual Write)를 통한 무중단 전환 전략 * **3단계 전환 프로세스**: 전환 전에는 Oracle을 메인으로 사용하며 MySQL에 백그라운드 쓰기를 수행하고, 데이터 마이그레이션 후에는 MySQL을 메인으로 전환하되 Oracle에 백그라운드 쓰기를 지속하여 정합성을 유지합니다. * **롤백 안정성 확보**: 신규 시스템 배포 후 치명적인 성능 저하나 장애가 발생하더라도, Oracle에 실시간으로 데이터가 쌓이고 있으므로 별도의 복구 작업 없이 즉시 이전 환경으로 복구가 가능합니다. ### JPA 환경에서의 기술적 대응 * **Proxy DataSource 활용**: `datasource-proxy` 라이브러리를 사용하여 Oracle에서 수행되는 쿼리를 가로챈 뒤 MySQL DataSource에서도 동일하게 실행하는 구조를 구축했습니다. * **트랜잭션 분리 및 동기화**: MySQL 쿼리 실패가 메인 트랜잭션(Oracle)에 영향을 주지 않도록 `TransactionSynchronizationManager`를 사용했습니다. Oracle 커밋이 성공한 시점(`afterCommit`)에 모아둔 MySQL 쿼리를 일괄 실행하여 정합성을 맞춥니다. * **엔티티 및 PK 전략 변경**: Oracle의 Sequence 전략을 MySQL의 Identity(Auto-increment)로 변경하고, `columnDefinition` 설정을 통해 Oracle의 VARCHAR2, CLOB 등을 MySQL의 TEXT, LONGTEXT 타입에 맞게 조정했습니다. ### MyBatis 기반의 중앙 집중형 이중 쓰기 구현 * **SqlSession Proxy 적용**: 수천 개의 비즈니스 로직을 수정하는 대신, MyBatis의 `SqlSession`을 프록시로 감싸 쓰기 작업(CUD)이 발생할 때 Oracle과 MySQL 쿼리를 동시에 호출하도록 구현했습니다. * **DBMS별 쿼리 매핑**: Oracle과 MySQL의 SQL 문법 차이를 해결하기 위해 별도의 MySQL용 쿼리 파일을 작성하고, 실행 시점에 Query ID에 접두사(예: `mysql.`)를 붙여 적절한 쿼리를 찾아 실행하는 방식을 사용했습니다. ### 데이터 정합성 검증 및 최종 전환 * **배치 기반 검증**: 두 DB 간의 레코드 카운트와 데이터 해시값을 주기적으로 비교하는 배치 프로그램을 운영하여 미세한 데이터 불일치를 식별하고 수정했습니다. * **기능 토글을 이용한 전환**: ZooKeeper 등을 활용한 설정 변경만으로 메인 DB(Read/Write 주체)를 즉시 교체할 수 있는 환경을 구성하여 배포 없이 안정적으로 전환을 완료했습니다. 이와 같은 전략은 대규모 레거시 시스템에서 DB를 교체해야 할 때, 코드 수정을 최소화하면서도 서비스 안정성을 최우선으로 고려하는 개발자들에게 실무적인 가이드라인을 제공합니다. 특히 트랜잭션 동기화와 프록시 패턴을 활용한 중앙 집중식 제어는 복잡한 시스템 마이그레이션의 위험 부담을 낮추는 핵심 기술 요소입니다.

일 평균 30억 건을 처리하는 결제 시스템의 DB를 Vitess로 교체하기 - 2. 개발 및 운영기 (새 탭에서 열림)

LINE Billing Platform 팀은 일 평균 30억 건의 요청을 처리하는 대규모 결제 시스템을 운영하기 위해 기존 Nbase-T에서 Vitess로 성공적인 데이터베이스 마이그레이션을 수행했습니다. 이 글에서는 성능 문제와 개발 편의성을 고려해 gRPC 대신 MySQL 프로토콜을 선택한 과정과 효율적인 데이터 처리를 위한 샤딩 전략을 상세히 다룹니다. 또한 VTOrc와 Prometheus를 활용한 자동 복구 및 모니터링 체계를 구축하여 분산 데이터베이스 환경에서도 높은 안정성을 확보한 실무 노하우를 공유합니다. ### 프로토콜 선정 및 개발 환경 구축 * VTGate는 gRPC와 MySQL 프로토콜을 모두 지원하지만, gRPC 사용 시 `http2: frame too large` 에러와 CPU 오버헤드가 발생하여 최종적으로 MySQL 프로토콜을 채택했습니다. * Java 클라이언트 사용 시 gRPC 프로토콜은 쿼리 결과를 객체로 변환하는 과정이 번거롭고 Vitess 측에서도 현재 MySQL 프로토콜 사용을 권장하고 있습니다. * 익숙한 MySQL 프로토콜을 사용함으로써 기존 개발 경험을 유지하면서도 Vitess의 샤딩 기능을 안정적으로 활용할 수 있게 되었습니다. ### 키스페이스 설계 및 데이터 처리 방식 * 시스템은 크게 두 개의 키스페이스로 분리되어 있습니다. '글로벌 키스페이스'는 단일 샤드로 구성되어 자동 증가(Auto-increment)하는 샤딩 키를 관리합니다. * 실제 데이터가 저장되는 '서비스 키스페이스'는 N개의 샤드로 분산되어 있으며, 코인 잔액 및 충전/사용 내역 등의 데이터를 저장합니다. * 서비스 키스페이스는 'Hash Vindex'를 사용하여 데이터를 균등하게 분산하며, 애플리케이션이 쿼리에 샤딩 키를 포함하면 VTGate가 해당 샤드를 자동으로 특정해 효율적인 요청 처리가 가능합니다. ### MySQL 호환성 및 주요 기능 활용 * 트랜잭션 격리 수준은 단일 샤드일 경우 `REPEATABLE READ`, 다중 샤드일 경우 `READ COMMITTED`가 적용됩니다. * Vitess는 MySQL 프로토콜을 지원하지만 일부 쿼리 제약 사항이 존재하므로, `unsupported_cases.json`을 통해 사전에 호환성을 확인해야 합니다. * 분산 샤드 간 트랜잭션을 지원하는 'Two-Phase Commit(2PC)' 기능과 쿼리 실행 계획을 분석하는 'VEXPLAIN/VTEXPLAIN' 등을 통해 분산 환경의 제약을 보완하고 있습니다. ### 안정적인 운영을 위한 모니터링 및 장애 복구 * 자동 복구 도구인 'VTOrc'를 도입하여 토폴로지 서버와 VTTablet의 데이터를 기반으로 문제를 자동 감지하고 복구합니다. * Prometheus를 통해 VTOrc의 지표(Metrics)를 수집하며, 장애 발생 시 이메일과 Slack으로 알람이 전달되도록 구성했습니다. * VTAdmin 웹 UI를 활용해 복구 내역을 시각적으로 확인하고, `tablet_alias`를 통해 문제가 발생한 MySQL 노드를 즉각적으로 식별하여 운영 효율성을 높였습니다. 대규모 분산 환경에서 Vitess를 도입할 때는 성능과 유지보수를 위해 gRPC보다는 MySQL 프로토콜 사용을 우선적으로 고려하는 것이 좋습니다. 또한 단일 샤드와 다중 샤드 간의 트랜잭션 격리 수준 차이 및 쿼리 제약 사항을 면밀히 검토하여 애플리케이션 로직을 설계해야 하며, VTOrc와 같은 도구를 적극 활용하여 고가용성 운영 체계를 구축하는 것이 중요합니다.

일 평균 30억 건을 처리하는 결제 시스템의 DB를 Vitess로 교체하기 - 1. 솔루션 선정기 (새 탭에서 열림)

LINE 결제 플랫폼 팀은 라이선스 비용 절감과 시스템 확장성 확보를 위해 기존 Nbase-T 시스템을 오픈소스 데이터베이스 클러스터링 솔루션인 Vitess로 마이그레이션하기로 결정했습니다. Apache ShardingSphere, TiDB 등 다양한 분산 DB 솔루션을 대상으로 성능과 운영 편의성을 비교 분석한 결과, 대규모 트래픽 환경에서 검증된 안정성과 고가용성을 제공하는 Vitess가 최종 후보로 선정되었습니다. 이번 과정은 결제 시스템이라는 특수성에 맞춰 서비스 중단 없는 전환과 물리 서버 환경에서의 최적화 가능성을 검증하는 데 주력했습니다. ### 후보 솔루션별 특징 및 제외 사유 * **Apache ShardingSphere**: 프락시(Proxy)와 JDBC 레이어 방식을 모두 지원하여 유연한 아키텍처 구성이 가능하지만, 데이터가 각 샤드에 고르게 분배되지 않을 경우 리샤딩(리밸런싱) 기능을 직접 구현해야 한다는 치명적인 단점이 있어 후보에서 제외되었습니다. * **TiDB**: MySQL 호환 분산 SQL DB로, SQL 계층(TiDB), 메타데이터 관리(PD), 행/열 기반 저장소(TiKV/TiFlash)로 분리된 구조를 가집니다. 샤딩키 설정 없이도 데이터를 자동 리밸런싱하여 운영 비용을 낮출 수 있다는 장점이 있어 유력한 후보로 PoC를 진행했습니다. * **Vitess**: YouTube에서 개발된 CNCF 프로젝트로, 샤딩 기술을 통해 수평 확장을 지원하며 베어 메탈 환경 설치가 가능해 결제 시스템에 필요한 높은 수준의 안정성을 확보할 수 있습니다. ### Vitess의 구조적 장점과 컴포넌트 역할 * **VTGate**: 클라이언트의 쿼리를 적절한 샤드로 라우팅하고 분산 트랜잭션을 처리하며, 애플리케이션에는 단일 DB처럼 보이도록 추상화 레이어를 제공합니다. * **VTTablet 및 VTorc**: 각 MySQL 인스턴스 앞에 위치하여 쿼리 실행과 복제를 관리하며, VTorc를 통해 장애 발생 시 자동으로 장애 조치(Failover)를 수행하여 고가용성을 유지합니다. * **토폴로지 서버**: ZooKeeper나 etcd를 활용해 클러스터의 구성 정보와 노드 상태를 중앙에서 관리함으로써 분산 환경의 일관성을 보장합니다. ### PoC를 통한 성능 및 운영 환경 검증 * **환경 일치화**: 실제 결제 시스템과 동일한 사양의 장비와 테이블 구조를 설정하여 Nbase-T, Vitess, TiDB 간의 성능 비교를 수행했습니다. * **성능 테스트 결과**: 순수 성능(TPS 및 CPU 효율) 관점에서는 기존 Nbase-T가 가장 우수했으나, Vitess 역시 대규모 요청 상황에서 안정적인 리소스 처리 능력을 보여주었습니다. * **유연한 설정**: Vitess는 필요에 따라 조회와 입력을 프라이머리와 레플리카로 분리하는 기능을 지원하며, 모든 DB 노드에 일괄적인 DDL 수행이 가능하여 관리 효율성이 높음을 확인했습니다. 결제와 같이 높은 신뢰성이 요구되는 시스템을 마이그레이션할 때는 단순한 쿼리 처리 성능뿐만 아니라 자동 장애 복구(Failover) 능력과 데이터 리샤딩의 용이성을 우선적으로 고려해야 합니다. Vitess는 글로벌 대형 서비스들에서 이미 안정성이 검증되었고, 베어 메탈 환경에서도 유연한 최적화가 가능하므로 대규모 MySQL 클러스터 운영이 필요한 조직에 강력히 추천되는 솔루션입니다.