앞서 이런 글을 올린 적이 있습니다. 근데 생각해보니 저것 말고도 꺼려지는 일이 한두 가지가 아니더군요. 오늘은 다른 사례를 소개해볼까 합니다.
저희 회사엔 서로 비슷한 두 서비스가 돌아가고 있습니다. 한쪽은 그나마 최근에 개발되어 유지 보수가 그나마 용이하지만, 다른 한쪽은 매우 오래전에 개발된 데다가 사용되는 기술도 최근에 잘 안 쓰는 것 들이라 유지 보수에 애로사항이 있습니다. 그래서 개발 리더분들의 장고 끝에 이 두 프로젝트를 통합하기로 결정했습니다. 프로젝트를 통합하고 데이터를 마이그레이션 해야 합니다.
정말 불행한 점은 이 업무를 제가 담당하게 되었다는 것입니다. 물론 저 혼자 하는 것은 아닙니다만 여간 부담스럽고 까다로운 작업이 아닐 수 없습니다.
통합 마이그레이션이 왜 어렵죠?
그냥 저쪽 DB에 있던 거 이쪽 DB에 인서트만 잘하면 끝 아닌가요?
개발에 대해 잘 모르는 분이라면 이렇게 생각할 수도 있습니다. 심지어 조직 리더들도 개발과 관련이 없는 분이라면 이렇게 말할 수도 있습니다. (그 조직 개발자들은 퇴사를 추천드립니다.)
아래 예시를 보면 어떤 생각이 드시나요?
남북통일 그거 왜 어렵죠? 그냥 철책만 걷어내고 대통령만 1명 만들면 되는 거 아니에요?
굉장히 터무니없는 이야기입니다. 지금 그 허무함이 바로 앞서 들었던 얘기를 개발자가 들었을 때의 기분이라고 보시면 되겠습니다.
왜 어려운지 알아보기 전에 마이그레이션의 경우를 생각해봅시다.
한 시스템을 종료하고 서비스 중인 다른 시스템으로 완전히 마이그레이션.
두 시스템을 서로 아우르는 새로운 개선된 시스템으로 마이그레이션.
첫 번째의 경우 외환은행 → 하나은행 전산 통합 등과 같은 일을 생각해 볼 수 있겠습니다.
두 번째의 경우 새롭게 개선된 시스템은 아직 서비스 중이 아닌 상태이고, 전부 개발이 끝나면 오픈하는 구조가 되겠습니다.
일단 첫 번째의 경우가 훨씬 더 어렵습니다. 좀 그렇긴 하지만 의학으로 빗대 보자면, 둘 다 산 사람일 때 간의 일부를 이식하는 경우를 생각해봅시다. 잘못하면 한 명이 죽을 수도 있습니다. 물론 둘 다 죽을 수도 있죠. 모든 게 완벽히 맞아야 합니다. 그때 의사를 비롯한 수술 관계자들의 스트레스는 어마어마할 것입니다. 첫 번째 경우가 바로 그런 케이스라고 보시면 되겠습니다.
두 번째의 경우는 그나마 낫습니다. 새로 만들면서 기존에 안 좋았던 점들을 개선할 여지도 있고, 무엇보다도 아직 서비스 중이 아니기 때문에 하다가 망하면 만들던걸 싹 다 버려도 됩니다. 단, 위보다 낫다는 것뿐 굉장히 어려운 과제입니다.
전 그나마 다행스럽게도 두 번째의 경우입니다.
아래의 경우를 생각해봅시다.
어느 날 두 거대 쇼핑몰이 합병을 했습니다. obay와 z마켓입니다.
합병 후 쇼핑몰 MD를 비롯한 운영자들의 불만이 쏟아지기 시작합니다.
왜 합병을 했음에도 불구하고,
같은 상품을 두 서비스에 따로 등록하며 관리해야 하죠?
CS 관리를 두 벌로 해야 하죠?
왜 판매자 관리를 두 벌로 해야 하죠?
물론 개발자들의 불만도 생기기 시작합니다.
왜 합병을 했음에도 불구하고,
왜 같은 기능을 두 벌로 만들어야 하죠?
왜 같은 상품 내용을 두 벌의 DB에 넣어야 하죠?
고심 끝에 개발 리더는 통합을 결정합니다. database, web app 등을 통합하고 obay, z마켓 서비스 고유 기능에는 지장이 없도록 상품 데이터만 마이그레이션 하는 방안입니다. 이렇게 상품 관리 영역의 백엔드만 통합하게 된다면 위에서 나왔던 불만들을 해결할 수 있습니다.
(obay, z마켓 서비스를 리브랜딩 하여 하나의 서비스로 출범시키자는 게 아닙니다. 상품 데이터 관리의 백엔드만 합치자는 겁니다.)
가장 큰 어려운 점은 마이그레이션으로 인해 데이터베이스 상의 PK가 필연적으로 바뀌게 되는 문제입니다. 기존 obay와 z마켓의 상품 상세화면 웹페이지 URL이 아래와 같다고 가정해봅시다.
http://www.obay.com/product/1
http://www.zmarket.com/product/1
두 서비스의 도메인은 당연히 따로 유지가 됩니다만, 데이터를 통합했을 때 저 URL 맨 뒤의 1은 바뀌게 될 수밖에 없습니다. DB가 하나로 통합되기 때문에 PK가 변경되기 때문이죠.
해결 방법은 두 가지가 있습니다.
obay 상품은 그대로 두고 z마켓 상품만 obay db로 인서트 한다. 단, z마켓 상품을 마이그레이션 할 때 이전의 PK를 전부 저장하도록 한다.
obay 상품은 1번부터, z마켓 상품은 2억 번부터 시작한다고 정책을 수정하고 PK를 그렇게 맞춰 마이그레이션을 진행한다.
물론 두 방법 다 허점은 있습니다. 하지만 어쩔 수 없습니다. 이 정도는 감수해야 합니다.
테이블 한 개의 PK 바뀌는 거 매핑만 잘해주면 되지 뭐가 문제겠느냐고 생각하실 수도 있습니다만 상품 데이터는 최소 수십 개의 테이블이 PK를 통해 서로 연관되어 있습니다. 마이그레이션 중 조금이라도 잘못 건드리면 상품 정보가 어긋날 수도 있으며 최악의 경우에는 판매 대금이 해당 판매자한테 지급이 안될 가능성도 배제할 수 없게 됩니다.
물론 테스트를 잘 짜고 QA에서 검증을 철저히 하면 되겠습니다만 개발자로서 여간 부담되는 작업이 아닐 수 없습니다.
쇼핑몰처럼 오랫동안 운영되어 온 서비스는 프로젝트의 규모가 어마어마하게 큽니다. 그래서 개발자들도 잘 모르는 영역이 있을 수밖에 없습니다. 전혀 모르는 캐시가 잘 돌고 있어서 트래픽을 받쳐주고 있다거나, 1년에 1번 호출되는 API가 굉장히 중요한 역할을 하고 있다거나 등등 눈에 안 띄는 곳에서 열일 하고 있는 것들이 있죠.
만약에 이것을 파악하지 못하고 배포를 하게 된다면? 개발자들은 하루 종일 알 수 없는 에러 메시지를 수신하게 될 것이며 유저들의 온갖 CS를 받게 될 것입니다.
obay, z마켓의 프로젝트에서 상품 데이터 관리 로직만 깔끔하게 떼내는 것 자체가 일단 큰 문제입니다. 그 로직이 구매자, 판매자 등의 데이터와 강하게 결합이 되어있다면 일단 그 강 결합을 떼내는 작업이 선행되어야 합니다. (DB를 같이 보던 것을 REST API로 연동하는 방법으로 변경한다던지 등)
이렇게 파고파고 들어가다 보면 결국 연관된 로직들이 마치 고구마 줄기처럼 계속 딸려 나오게 되고, 최악의 경우 결국 쇼핑몰 모든 로직을 전부 건드리고 개선해야 할 수도 있습니다. 위에 나열한 1, 2번 문제점들은 확인할 기회조차 없을 수도 있습니다. 일정은 걷잡을 수 없이 밀리게 됩니다. 지친 개발자들은 회사를 한 두 명씩 나가게 되고..
사실 저의 경우 온몸으로 막막함을 느끼고 있습니다만 이걸 도저히 말로 설명을 못하겠습니다. 어려운 점이 수천 개는 더 있을 거라 확신합니다.
개발자라고 하면 어떤 이미지가 떠오르실지 모르겠습니다. 굉장히 새로운 기술로 연구하며 멋지게 일을 해결하는 영화 같은 모습보다는 위처럼 운영 공수 대응하는 게 훨씬 더 많습니다.
아무튼 통합 마이그레이션은 어렵습니다. 남북통일이 어렵듯이.