커머스 솔루션에서 자사 커머스 플랫폼으로 이전
얼마전 핏펫은 커머스 솔루션에서 자사 커머스 플랫폼으로 이전을 하였습니다. 이때 DB 마이그레이션을 하면서 겪은 일들에 대하여 기술하려고 합니다.
커머스 솔루션이란
비개발자가 자신의 커머스 사이트를 쉽게 만들 수 있는 솔루션이며, 대표적으로 까페24 쇼핑몰, NHN 커머스의 고도몰, Shopify 등이 있습니다.
커머스 솔루션을 사용하면, 쉽게 커머스를 런칭할 수 있고 많은 사람들이 사용했기 때문에 안정적입니다. 일부 커머스 솔루션은 커스터 마이징을 지원하지만, 비개발자가 하기 어렵거나 제한적인 경우가 많습니다.
자사 커머스 플랫폼으로 서비스를 시작하려면, 많은 기능을 개발해야 하기 때문에 시간이 많이 필요합니다. 또한 안정적으로 서비스를 제공하기 시간도 필요합니다. 대신 신규 기능을 추가하거나 기존 기능을 수정하기에 용이합니다.
자사 커머스 플랫폼으로 이전하기 전의 핏펫 현황
핏펫은 2021년도에도 자사 커머스 플랫폼으로 이전을 시도했습니다. 자사 플랫폼의 프론트엔드가 기존의 프론트엔드를 완벽하게 대체하였지만, 커머스 솔루션의 백엔드와 DB를 여전히 사용(?!)하고 있었습니다. 저희는 이 형상을 V2라고 부릅니다.
완벽하게 다른 2개의 DB
완벽하게 다른 2개의 백엔드
다행히(?) 1개의 프론트엔드
V2는 여전히 커머스 솔루션의 백엔드와 DB를 사용하고 있기 때문에 자사 커머스 플랫폼으로 이전 했다고 할 수 없습니다. 덤으로 커머스 솔루션 비용 + AWS 서버 비용이 발생하기 때문에 이전보다 더 많은 비용을 지불하고 있었습니다!
V3 런칭 준비
커머스 솔루션과의 완벽한 안녕을 위해 저희는 다시 한번 자사 커머스 플랫폼 런칭을 위한 준비를 하게 되었습니다.
백엔드: Django + GraphQL
프론트엔드: React
인프라: AWS Fargate
DB 마이그레이션
DB 마이그레이션 스케쥴
저희는 2개의 DB(커머스 솔루션의 DB와 V2의 DB)에서 데이터를 합쳐서 하나의 DB를 만들어야 했습니다. 물론 DB schema는 전혀 달랐기 때문에 각 table에서 데이터를 조회 후 가공한 데이터를 신규 DB에 저장하는 작업을 진행하였습니다.
이전 회사에서도 커머스 솔루션을 자사 커머스 플랫폼으로 이전한 경험이 있었으며, 다음과 같이 진행하였습니다.
1. 점검 페이지 노출
2. 커머스 솔루션의 DB에서 데이터를 조회 후 가공하여 자사 커머스 플랫폼의 DB에 저장
3. 커머스 플랫폼 오픈!
이때 커머스 솔루션의 DB 크기는 약 2GB고, DB마이그레이션(2번 작업)에 약 2시간 정도가 걸렸습니다. 이번에도 동일한 방식으로 진행하고 싶었지만, 불가능하다고 판단하였습니다. 이유는 Legacy DB의 크기가 매우 컸기 때문에 DB이전 작업에만 하루가 넘는 시간이 필요했기 때문입니다.
커머스 솔루션의 DB:약 70GB
V2의 DB: 약 7GB
합이 약 77GB
그리고 서비스 중이기 때문에 실시간으로 데이터는 증가하고 있었습니다.
서비스 중단 시간을 최소화 하기 위해 DB마이그레이션 계획을 수정하였습니다.
운영 중인 Legacy DB들에서 많은 데이터를 조회하면, 운영에 영향을 줄 수 있기 때문에 DB dump 후 개발용 맥북에서 V3 schema에 맞춰서 데이터 마이그레이션을 진행합니다.
이후 Celery를 이용하여 주기적으로 운영 중인 Legacy DB들에서 데이터 조회 후 런칭 이후에 사용할 V3 DB에 데이터를 생성/갱신합니다.
WorkerLostError를 만나다
개발용 맥북에서 생성한 V3 DB를 런칭 후 사용할 AWS AuoraDB에 import하고 Celery 실행 후 만난 것은 WorkerLostError였습니다.
검색해보니, Celery로 오래 걸리는 작업을 실행하면 발생할 수 있다는 글을 찾을 수 있었습니다. 각 도메인 별로 스크립트를 작성하였기 때문에 작업을 나눠서 실행하는 것은 어렵지 않았습니다.
변경 완료하고 Celery 실행 후 WorkerLostError를 다시 만나게 되었습니다. 저희 생각과는 다르게 오래 걸리는 작업으로 인해 발생하는 문제는 아니었습니다. 그래서 Celery 서버 상태를 확인해보았습니다. 해당 오류가 발생했던 시점의 메모리 사용율이 100%가 되는 것을 확인했습니다!
서버 메모리를 추가한 후에는 오류 없이 동작하는 것을 확인할 수 있었습니다. 메모리가 부족한 경우에도 WorkerLostError가 발생한다는 점을 알 수 있었습니다.
2개의 DB
작업은 쉽지 않았습니다. 2개의 DB에는 같은 도메인의 table이 존재하였습니다. 과연 어느 DB의 데이터가 맞는 데이터 일까요?
멈추지 않는 눈물을 닦으며 한땀한땀 데이터를 맞춰보는 수 밖에 없었습니다. 로그인 ID와 비밀번호는 커머스 솔루션에서 가져오고, SNS 로그인 정보는 V2에서 가져오고, 겹치는 전화번호는 변경 시각을 기준으로 최신의 데이터를 가져오는 등으로 말이죠.
정확하지 않은 데이터로 인해 발생하는 문제들을 피하기 위해, 정확한 데이터만을 마이그레이션 하기로 했습니다. 그리고 일부 비어 있는 데이터로 인해 발생하는 문제는 CS를 통하여 대응하기로 했습니다.
FSM(finite-state machine)
주문 관련 마이그레이션이 가장 복잡했습니다. 주문은 여러 개의 상태를 갖고 있었고, 상태에 맞춰서 데이터를 가공해야 했습니다.(정산 데이터 생성은 덤이었습니다.) 그래서 복잡한 상태를 한눈에 볼 수 있도록 주문 상태의 FSM을 작성하였고, 매우 큰 도움이 되었습니다.
Legacy DB의 데이터, 어디까지 믿을 수 있는가
당연히 Legacy DB에 쌓여있는 데이터의 정합성 문제는 없을 것이라고 생각했습니다. 상품의 구매 금액이 음수가 나올 줄은 꿈에도 몰랐습니다.
상품 결제 금액 계산식
상품 판매가 — 쿠폰 할인금액 — 적립금 사용액 = 상품 결제 금액
총 주문 금액의 합계는 문제가 없었지만, 각 주문 상품의 금액에 문제가 있었습니다. 환불을 하는 경우에 금액이 잘못되는 문제가 발생할 수 있는 상황이었습니다. 그래서 데이터의 정합성을 맞추기 위해 원인 분석 및 수정 작업을 추가로 진행하게 되었습니다.
주문 데이터가 컸기 때문에 테스트 케이스 실행에 약 12시간이 필요했고, 테스트를 실행퇴근 하는 경우가 많았습니다.
자사 커머스 플랫폼 런칭
드디어 런칭일이 되었습니다. 저희는 점검중 페이지를 노출시키고, 이전 작업을 시작했습니다. DB 마이그레이션 작업을 시작하였는데, 이전에 만나지 못했던 오류를 만나게 되었습니다.
Error: Lost Connection
순간 머리속에 별의 별 생각들이 스쳐 지나갔습니다.
‘커머스 솔루션 서버에서 우리 연결을 일부러 끊었나!?!?’
설마하는 마음으로 DB 마이그레이션 작업을 다시 실행하였습니다.
==== START migrate database ====
start_at: 2022–01–25 00:10:27
…
==== START migrate user ====
…
==== END migrate user ====
…
==== START migrate order ====
…
Done
다행히 네트워크 등의 일시적인 문제였고, 작업을 무사히 완료 할 수 있었습니다.
같이 마이그레이션 작업을 진행했던 동료에게 ‘DB 마이그레이션 작업을 한번 더 하면, 이전 보다 잘하겠죠?’ 라고 웃으며 농담으로 얘기 하곤 합니다.
이 글을 작성하며, DB 마이그레이션에 사용했던 코드들을 살펴보았습니다. ‘우와, 이걸 어떻게 했지’ 라는 생각이 들었습니다. 작은 실수로 인해 큰 문제가 발생하고, 마이그레이션 작업 이전으로 되돌리기 어려운 작업이었기 때문입니다. 믿을 수 있는 동료들과 함께 작업을 했기 때문에 가능하지 않았나 싶습니다.
written by Link(SungSoo Park)
email: ss.park@fitpet.co.kr