API V2 전환과 DB 무중단 마이그레이션 후기

rogiry
29CM TEAM
Published in
7 min readOct 11, 2021

29CM에서는 비즈니스 확장에 대응하기 위해 Monolithic Architecture 으로 구성 되어있던 시스템을 Microservice Architecture(이하 MSA)로 전환중입니다.

이 과정에서 Monolithic에서 사용하던 좋아요 API 의 V2 전환과 PostgreSQL 데이터를 Microservice가 사용하는 MySQL 로 무중단 마이그레이션을 진행했던 경험을 공유해보려 합니다.

배경

29CM 에서는 좋아요 기능을 제공하고 있습니다. 유저의 취향에 맞는 상품을 좋아요 하고, 좋아요 한 상품의 목록을 확인할 수 있습니다. 어찌보면 단순했던 이 기능의 고도화를 위한 사전 작업으로 테이블의 변경이 필요한 상황이었는데요. 이때 Microservice로 이관하는 시점이라 기존의 Monolithic 서비스와 별개로 하여 V2 API를 제공하는 Microservice를 만들기로 결정했습니다.

대부분의 마이그레이션은 동일 기종의 데이터베이스를 사용하여 타겟 시스템으로 옮기는 경우가 많지만, 이번 경우는 PostreSQL 을 MySQL 로 전환하면서 추후 좋아요 기능의 요구사항 확장을 대비한 스키마 변경이 추가로 포함되어 있었습니다. 그래서 기존 데이터베이스를 조회하고, 몇가지 전처리 로직을 거친 뒤 데이터베이스에 적재 되어야 했습니다.

마이그레이션 과정에서는 다음과 같은 제약 조건이 있었습니다

  • 신규 구현은 모바일용 API 에만 적용 (MVP)
  • 웹과 모바일의 호환성을 지키기 위해 V1, V2 버전을 동시에 사용 가능해야 함
  • 해당 제약 조건은 상당히 긴 시간 동안 적용될 수 있음

위와 같은 사항을 대응하기 위해 백엔드 서버에서는 기존 시스템의 V1 버전을 담당하는 데이터베이스 (PostgreSQL) 와 신규 시스템의 V2 버전을 담당하는 데이터베이스 (MySQL) 가 정확히 동기화가 되어야 한다는 요구사항이 발생했습니다.

마이그레이션 전략

마이그레이션 전략은 다양한 방법으로 진행될 수 있습니다. 가장 직관적인 방법은 서비스 점검 공지 후 가용 시간을 확보하여 서비스를 중단한 뒤에, 기존 데이터를 Dump 하고 신규 시스템에 Load 시킨 후 서비스를 재개하면 됩니다.

좋아요 데이터의 경우 데이터 행이 꽤 많은 빅테이블 중 하나였고, 마이그레이션이 필요한 경우 분 단위가 아닌 시간 단위가 필요했습니다. 해당 기능의 마이그레이션을 위한 시간 단위의 서비스 중단은 유저 경험 측면에서 어렵다는 판단을 하였고, 서비스 중단이 아닌 다른 전략을 구상해보기 시작했습니다. 처음 막연히 구상한 전략은 기존 시스템에 적재되는 데이터를 신규 시스템에 스트리밍하여 동기화 하는 방식이었습니다.

API 요구사항 대응

V1 인터페이스를 그대로 Microservice에 포팅하는 일은 불필요한 일이라 판단했고, 대신 V1 API 에서 좋아요 설정이나 해제 시 V2 API 에 동기화가 가능하도록 이벤트를 발송하는 구조로 전략을 정했습니다.

동기화 방법으로 생각한 것 중의 하나는 CDC 였습니다. 하지만 당시 기반 플랫폼에서는 CDC 사용을 위한 준비가 전혀 되어있지 않았기 때문에 Kafka 를 활용한 CDC 도입은 부담스러웠던 선택지였습니다.

현재는 비즈니스 로직에 적극적으로 Kafka 적용을 준비 하고 있습니다.

추후 Kafka 로 메시지 브로커 변경을 고려하되, 당장의 요구사항에 대응하기 위해 이미 우리 플랫폼에서 준비가 되어있고 간단하게 사용이 가능한 SQS를 활용하기로 결정 했습니다.

좋아요 설정/해제 플로우

좋아요 설정/해제 API는 V1만 호출하도록 하여, V1 서비스가 일종의 원장 데이터라는 컨셉을 가져갑니다. 모든 데이터의 정합성 주체는 V1 PostgreSQL을 기준으로 동기화 하도록 구성했고 4, 5번의 스프링 서비스의 경우에는 SQS 큐를 FIFO로 구성 후 API를 멱등하게 구현하여 마지막 이벤트를 최종 상태로 구성하도록 합니다.

조회의 경우는 V1, V2를 각각 호출이 가능합니다.

조회 API

스트랭글러 패턴에 영감을 많이 받았고, 실제로 진행한 방법도 이와 유사합니다. 웹에서는 V1 API 를 통해 데이터를 조회하고, V2 의 경우는 우선 안드로이드 플랫폼에서만 배포를 진행했습니다. V1 API 호출 시 Django 에서 PostgreSQL 을 조회하고, V2 API 호출시에는 MySQL을 조회합니다.

추후에 모든 조회 로직이 V2 로 전환되는 시점부터는 MySQL 이 원장 데이터가 되도록 합니다. 그 후에는 PostgreSQL의 데이터는 제거 가능한 데이터라고 볼 수 있으며 Django 의 V1 좋아요 설정/해제 API 는 구버전의 호환을 위한 Proxy Adapter 역할만 하면 됩니다.
(해당 API 는 Deprecated 처리하고, 모니터링으로 트래픽이 더이상 들어오지 않는다는 판단이 드는 시점에 제거하면 됩니다)

데이터베이스 마이그레이션

포스팅 제목엔 거창하게 적었지만 데이터 이관은 간단했습니다. 무중단 마이그레이션에서 필수적으로 도출되는 요구사항 중 가장 중요한 핵심은 마이그레이션 도중 업데이트 되는 데이터의 동기화를 어떻게 진행하는가 입니다.

마이그레이션 플로우

이번 마이그레이션 작업에서는 API 전환 과정에 SQS로 데이터를 동기화하는 구간이 있었기 때문에 SQS 에 이벤트를 발행하는 로직을 추가하고, 배포 후에는 PostgreSQL Database 을 Dump 하여 해당 데이터를 그대로 MySQL 에 Load 합니다. 마이그레이션 도중 유저의 설정/해제로 인한 데이터 변경사항은 SQS 큐에 쌓이게 되고 마이그레이션이 끝난 이후 V2 API 를 구현한 Spring 서비스를 배포하면서 SQS 를 구독하면 데이터의 최신화가 진행됩니다.

마이그레이션에는 스키마의 변경이 포함되어 있어 별도의 마이그레이션 로직이 필요했고, 간단히 사용하기 편한 파이썬으로 작성하여 이용했습니다.

29 개발팀에서 흔히 볼 수 있는 뭔가 멋있는 현장

MSA 전환에 맞춰 데이터를 마이그레이션 하는 경우가 앞으로 많아질거란 생각에 해당 마이그레이션 작업 중에 사용된 단순 반복 스크립트를 간단히 수정하여 프레임 워크 형태로 구성했습니다. 이 후 사내 유틸로 활용 가능하도록 해당 스크립트를 공유했고, 이후 사용자도 나왔습니다.

코드의 첫번째 유저님

피드백을 받았지만, 수정은 하지 못했습니다.. PR을 기대합니다 😇

아래 이미지는 V2 API 가 적용된 앱의 모습입니다.

V2 API 가 적용된 앱의 모습

마치며

좋아요 기능과 같은 심플한 기능이 아니더라도 비슷하게 무중단 마이그레이션을 진행할 수 있는 케이스가 많을듯 합니다. 무중단 마이그레이션에서 가장 중요한 부분이라 생각한 것은 마이그레이션 진행 중 업데이트 되는 데이터의 동기화일듯 싶습니다. 조금 더 복잡한 API 나 데이터들의 경우도 비슷한 방법으로 실시간 동기화를 시킨 뒤 DB 를 바꿔 보도록 구성할수도 있을듯 합니다.

함께 성장할 동료를 찾습니다

29CM ((주)무신사)는 3년 연속 거래액 2배의 성장을 이루었습니다.
이제 더 큰 성장을 위해 기존 모놀리틱 서비스 구조를 마이크로서비스 구조로 전환하고, 앵귤러 기반 프론트엔드 코드를 리액트로 전환하는 등의 기술적인 시도를 진행하고 있습니다. 모바일 앱 내부 구조도 모듈러 아키텍처로 개선하는 과정에 있습니다. 함께 성장하고 유저 가치를 만들어낼 동료 개발자분들을 찾습니다.

🚀 29CM 채용 페이지 : https://www.29cmcareers.co.kr/

--

--