본문 바로가기

IT/디자인 패턴(Design Pattern)

확장-축소 패턴

이번에 회사에서 기존 수작업으로 처리해야하는 작업들을 자동화하여 모든 회사에 새로운 데이터베이스 구조도로 동시에 변경될 수 있는 기능이 필요하다하여 분석 중 pgRoll(https://github.com/xataio/pgroll)이라는 비교적 최근에 나온 오픈소스를 분석하며 확장 축소 패턴에 대해서 분석해보았다. 아무래도 마이그레이션은 앞으로도 마주치기 싫으나 마주칠 수 밖에 없는 상황들이 계속 발생하기에 해당 패턴을 알면 도움이 될까 싶어 찾아보았고 공부해보았는데, 아무래도 한글로 되어있는 곳을 찾기가 쉽지않아 하기 링크를 참조하여 공부할 겸 번역하였다. (https://www.prisma.io/dataguide/types/relational/expand-and-contract-pattern)

 
 

확장 축소 패턴

소프트웨어 개발자와 데이터베이스 관리자가 기존 서버에 영향을 주지 않고 기존 데이터 구조도와 새로운 데이터 구조도를 변환할 수 있게 도와주는 패턴이다. 아래 앞으로 소개할 단계를 따라가면 기존 데이터 구조도에 새로운 데이터 구조도를 자연스럽게 적용시킬 수 있게 될 것이다.

확장 축소 패턴 사용하기

여기에서 확장 축소 패턴을 실질적으로 사용하는 방법과 무엇을 얻을 수 있는지 알아볼 것이다. 이 개별적인 스탭은 어플리케이션과 스키마의 조화롭게 해줄 것이고, 각 단계마다 그 단계가 존재하는 이유와 목적을 이해하는게 매우 중요하다.

2단계와 3단계는 요구사항에 순서가 바뀔 수 있다. 거의 대부분은 확장을 데이터 이전 전에 수행하나, 기획 / 디자인 / 참고사항 등에 의해 확장이 데이터 수행 이후에 하는 것이 도움되는 케이스도 종종 있다.

1단계 : 새로운 스키마에 대한 빌드와 배포

확장 / 축소 패턴의 첫 단계는 너의 요구사항이 처리된 새로운 스키마를 디자인하는 것이다. 이상적으로 기존 스키마(이후 구조도는 스키마로 명명하겠다.)에서 작은 변화가 발생하는 것이 좋다. 큰 변화는 작은 변화로 쪼개어 작은 변화들을 확인하며 진행하는 점진적으로 진행하는 것이 좋다고 생각한다.

왜냐하면 기존 스키마는 현재 클라이언트가 쓰고 있고, 순식간에 새로운 스키마로 변경이 불가능하여 새로운 스키마에서 변경사항을 적용해야하기에 되도록 점진적으로 수정하는 것이 리스크를 낮추는 방안이라고 생각한다. 예를 들어 name 컬럼을 first_namelast_name 으로 변경 시 name컬럼을 변경하지 않고 새로운 컬럼 2개를 추가하는 방향으로 가는 것이 좋다.

새로운 스키마를 배포하기에 앞서 새로운 컬럼들이 클라이언트에게 어떤 제약조건을 통해서도 그것에 의해 클라이언트가 실패값을 전달받으면 안 된다는 것을 명심해야한다. 예를 들어 nullable 를 추가할 경우 기본 값을 추가해줘야한다.

요약하면 새로운 스키마를 클라이언트는 바뀌었는지 알 수 없을 정도로 만들어야한다.

2단계 : 인터페이스 확장

새로운 스키마를 확장한 후, 다음 단계는 새로운 컬럼과 테이블을 클라이언트가 인식하는 것이다. 클라이언트는 계속해서 기존 스키마에서 데이터를 읽겠지만, 쓰기 작업 시에는 해당 데이터를 기존 스키마와 새로운 스키마에 모두 반영해주어야한다.

두 스키마에 모두 반영하며 신규 스키마의 유효성을 체크할 수 있다.

3단계 : 새로운 스키마로 기존 데이터 복사

새로운 스키마를 사용할 준비를 하기 위해 기존 스키마에 존재하던 데이터를 새로운 스키마로 복사해주자. 데이터를 복사하며 데이터 가공처리를 해줘야하는 케이스도 더러 있는데 이 경우는 매우 주의깊게 생각하여 두 데이터의 동일성을 보장할 수 있어야한다.

4단계 : 새로운 인터페이스 테스트

모든 데이터 복사가 끝나고 새로운 스키마에도 쓰기 작업이 정상적으로 되고 있다면, 이제 새로운 스키마가 의도한 대로 동작하는지 테스트해보자.

이 단계는 모든 요구사항이 충족되는지를 확인하기 위해 가끔씩 기능 테스트를 해줘야한다. 테스트를 하며 성능이 문제일 경우는 새로운 인덱스를 생성하거나 쿼리를 수정해주자.

이 단계가 새로운 스키마의 유효성을 검증할 수 있는 마지막 기회이므로 가능하다면 운영서버의 트래픽도 넣어서 테스트해보며 너의 모든 요구사항이 성공적인에 대해 다시 한 번 생각해보자.

5단계 : 새로운 스키마에서 데이터 조회

이제부터 새로운 스키마로 트랜잭션과 운영서버 트래픽을 주고받아보자.

이 단계가 마이그레이션의 마지막 단계라고 봐도 되며, 새로운 스키마에서 모든 트랜잭션이 일어나야한다. 하지만 혹시 모를 위험에 대비하여 데이터를 잃지 않고 롤백을 하기 위해 기존 스키마에도 똑같이 데이터 변경사항을 알려줘야하며, 새로운 스키마에 데이터들을 유니크하게 저장하지 말도록 하자. 이렇게 하면 별다른 롤백 작업이 없어도 기존 스키마로 롤백을 간단하게 할 수 있다.

6단계 : 기존 스키마와 연결 종료

모든 단계가 완료되고 새로운 스키마가 정상적으로 동작하고 있다고 확신할 시에는 기존 스키마와 연결을 종료하고 새로운 스키마로 이제 모든 트랜잭션 처리를 해주도록하자.

7단계 : 기존 스키마 삭제

더 이상 필요 없어진 스키마는 리소스 낭비가 되므로 삭제해주자.

 

요약

이 글에서 우리는 확장 축소 패턴을 통해 기존 스키마와 신규 스키마 간의 변환을 어떻게 해야하는 지 알아보았다. 이 패턴의 장점이 무엇인지 알아보았으며, 이 패턴을 사용하고 보완하며 마이그레이션을 진행하게 된다면 많은 공통적인 문제점과 서비스 중단을 막을 수 있을 것이라고 생각한다.