Skip to content

[DB] MongoDB 마이그레이션 로컬 환경 세팅 및 테스트

이은비 edited this page Mar 29, 2023 · 1 revision

배경

명식이에서 가장 불안정한 부분이 바로 "식당"입니다. 대학교 내에서 운영되는 식당 측에서 식당 운영 여부, 식당에서 제공하는 식단, 중/석식 등의 분류 데이터를 식당마다 다르게 사용자에게 제공하고 있습니다. 명식이에서는 이 데이터들을 사용자에게 동일한 양식으로 제공하고자 RDB를 이용한 ERD 설계에 많은 고민의 시간을 들였습니다.

운영 단계에 접어 들면서 식당 측에서 ERD 설계와 맞지 않는 형식의 데이터를 제공함에 따라 이를 어떻게 대응하면 좋을지 고민하던 중 "컬럼의 수평적 확장"이 가능한 MongoDB로 마이그레이션 이라는 아이디어가 떠올랐습니다.

MongoDB에 대한 경험이 거의 없는 상태였기 때문에 로컬 환경에서 RDB의 일부 테이블만을 마이그레이션하여 테스트를 진행해보기로 했습니다.

진행 과정

진행 과정에서 사용되는 코드 혹은 상세 정보가 궁금하다면, 여기를 참고해주세요.

  1. docker-compose.yml 파일 작성

로컬 환경에서 운영체제와 버전 등의 제약으로부터 벗어나 동일하게 작업할 수 있도록 도커 컨테이너로 MongoDB를 사용하였습니다.

  1. application.yml 파일 수정

MongoDB 사용을 위한 프로퍼티를 추가해야 합니다. 명식이 프로젝트에서는 프로퍼티 값들을 모두 암호화 처리하여 관리하고 있습니다. 하지만, 로컬 환경에서 테스트하는 용도이고 암호화하여 관리해야 하는 데이터는 아니라고 판단하여 암호화의 과정은 거치지 않았습니다. 만일, 운영 단계에 적용된다면 암호화 처리가 진행될 예정입니다.

  1. Document 작성

RDB에 있는 모든 테이블이 아닌, 일부 테이블에 대해서만 Document로 작성하여 MongoDB와 RDB의 혼합 사용이 가능한지, API가 정상적으로 동작하는 지를 테스트하였습니다. 단, 운영 환경에 영향이 가지 않도록 운영 RDB에서 조회하는 쿼리 외에는 비즈니스 로직에서 사용하지 않습니다.

마이그레이션 테스트를 위해 식사 테이블, 식당 테이블만을 Document로 작성하였습니다. 자바 코드 상에서 동일한 이름일 경우, import 문제가 발생할 수 있으므로 다르게 지정하였습니다. 기존에 좋아요와 싫어요에 대해서는 식사 테이블에서 속성값으로 두어 계산하였으나, 이번 작업에서는 별도의 Document로 분리하여 유저 본인이 눌렀는지 아닌지에 대한 정보까지 서버에서 관리하는 식으로 구성하였습니다.

[Dish.java]

image

위의 코드는 식사 테이블에 대한 Document 코드 일부입니다. RDB의 @Entity 어노테이션 대신 @Document 어노테이션으로 해당 클래스가 Document임을 표시합니다.

@Id 어노테이션으로 해당 데이터를 식별할 수 있는 PK 값을 지정합니다. 이때 데이터 타입은 String 혹은 Object 타입으로 두어야 오류가 발생하지 않고, auto_increment 옵션을 사용할 수 있습니다. @Id 어노테이션을 사용할 때 주의해야 하는 점으로 import 가 있습니다. JPA와 혼합해서 사용하다 보니, 자동 import로 import javax.persistence.Entity;가 설정되는데, MongoDB에서는 import org.springframework.data.annotation.Id;를 사용해야 합니다.

  1. MongoRepository 사용하기

[DishRepository.java]

image

이번 테스트에서는 MongoRepository를 사용하였습니다. 이것 외에도 MongoTemplate을 이용해 DB와 통신할 수 있습니다. MongoRepository를 선택한 이유는 이미 RDB와 JpaRepository의 조합으로 개발을 진행하면서 더 익숙하기 때문입니다. ( Template으로 세밀한 데이터 조작까지는 현재 기능에서 필요하지 않을 것이라고 판단한 것도 이유 중 하나입니다. )

진행 결과

MongoDB에서 스키마를 디자인하는데 여러가지 방식이 있습니다. 각 방식마다 장단점이 존재하고, 그 중 어떤 방식이 명식이에게 잘 맞는지에 대한 기준점이 존재하지 않기 때문에 현재의 테스트용 디자인이 정답이라고 생각하지 않습니다. 테스트를 진행한 필자가 한 스키마 디자인 방식은 key 참조 방식입니다. 참조가 필요한 Document에 id 값을 속성으로 두어 참조할 때 사용하도록 하고 있습니다. 이는 RDB의 방식과 유사합니다.

MongoDB의 장점과 성능을 최대한 끌어내는 디자인을 하기 위해서는 사용자에게 제공되는 데이터의 형식이 어느정도 확립이 되고 서비스가 안정화되어야 할 것 같다는 생각이 들었습니다. key 참조 방식 외에 Extended 참조 방식으로 구성할까에 대해서도 고민했습니다.

Extended Reference 패턴은 서로 관계가 있는 Document에서 자주 사용되는 데이터를 저장해두는 패턴입니다. MongoDB에서는 성능을 위해 Join 대신 쿼리를 두 번 날려 연관 데이터를 불러오는 방식을 많이 사용하는데, 데이터가 많아질수록 성능상 불리합니다. 따라서 명식이에서 연관 관계가 있는 Document의 데이터가 많아지고 참조가 자주 필요할수록 이 패턴을 사용하면 어떨까 합니다. ( 필자의 개인적 의견입니다. )

스키마 디자인 방식에서부터 경험의 부족으로 마이그레이션을 함으로써 데이터의 불일치나 성능 악화 등의 상황이 발생할 수 있다는 생각이 들었습니다. 따라서 운영 환경에서의 마이그레이션을 보류하기로 결정하였습니다. 각자 로컬환경에서 명식이에 맞는 스키마 디자인 방식을 찾고 잦은 요구사항의 변경에도 유연하게 대응이 됨이 보장이 되면 운영 환경에 적용할 계획입니다.