Skip to content

[infra/mongodb] 몽고디비 마이그레이션 로컬 환경 세팅 및 테스트 #87

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 25, 2023

Conversation

dldmsql
Copy link
Member

@dldmsql dldmsql commented Mar 24, 2023

주요 작업 내용

몽고디비로 로컬 환경 세팅을 하였습니다.



작업 내용 정리

  • docker-compose 파일 작성 ( 도커 컨테이너로 몽고디비 사용 )
  • application.yml 파일 수정 ( 몽고디비 사용을 위한 프로퍼티 적용 )
  • Document 생성 ( 식사, 좋아요, 싫어요, 식당 )
  • API 개발 ( Document 와 비즈니스 로직 동작 확인용 )



변경점

  • docker-compose.yml 파일 작성

이유 : 로컬 환경에서 운영체제와 버전 등의 제약으로부터 벗어나 동일하게 작업을 할 수 있도록 도커 컨테이너로 몽고디비를 사용하였습니다. 해당 파일에는 몽고디비 구동을 위한 이미지 파일 정보만을 작성하였습니다.

  • application.yml 파일 수정

이유 : 몽고디비 사용을 위한 프로퍼티를 추가하였습니다. 로컬 환경 테스트이기 때문에 암호화 처리는 하지 않았습니다.

  • Document 생성

이유 : RDB와 몽고디비의 혼합 사용이 가능한지를 테스트하기 위해 Document를 생성해서 마이그레이션 작업을 일부 진행했습니다. 운영 환경에 영향이 가지 않도록 운영 RDB에서 조회하는 쿼리 외에는 비즈니스 로직에서 사용하지 않습니다.
마이그레이션 테스트를 위해 식사 테이블, 식당 테이블만을 Document로 적용하였습니다. 기존에 좋아요와 싫어요에 대해서는 속성값으로 두어 계산하였으나, 별도의 Document로 분리하여 유저 본인이 눌렀는지 아닌지에 대한 정보까지 서버에서 관리하는 식으로 구성하였습니다.

  • API 개발

이유 : 실제로 비즈니스로직을 검증 및 네트워크 레이어에서 문제가 없음을 검증하기 위해 API를 개발하였으며, 이는 POSTMAN 도구를 이용해 검증하였습니다. 단순 테스트를 목적으로 진행한 작업이기 때문에 모든 API를 구현하지 않았습니다.



고민 Point

  1. 스키마 디자인

스키마 디자인을 어떤 식으로 가져갈 지에 대해서는 혼자만의 결정이 아닌 팀원과의 합의가 이루어져야 하는 부분이기 때문에, 기존 구조와 유사하게 가져갔습니다.

  1. MongoTemplate vs. MongoRepository

스프링에서 몽고디비를 사용하기 위한 ORM에는 두 가지 방식이 있습니다. 두 방식의 장단점에 대해서는 여기를 참고해주시기 바랍니다.

RDB와 연동하여 사용하면서 Repository 사용이 더 익숙하기 때문에 환경 세팅에서도 Repository를 이용하는 방식을 선택하였습니다. Template으로 세밀한 데이터 조작까지는 현재 기능에서 필요하지 않을 것이라고 판단한 것도 이유 중 하나입니다.

  1. MongoDB로의 마이그레이션이 옳은 선택일까?

로컬 환경 세팅을 진행하면서 마이그레이션이 필수적인지에 대한 생각이 들었습니다. ( 저는 필수적이지 않다고 생각합니다. )
-> NoSQL의 대표적인 특징 중 하나인 "컬럼의 수평적 확장" 때문에 몽고디비를 시도해보려고 했었는데, 기존 테이블에서도 충분히 개선할 수 있는 방법이 떠올랐습니다.

[기존 방식]
Meal ( MealId, MealType, StatusType, Menu1, Menu2, Menu3, Menu4, Menu5, Menu6, OfferedAt, Love, Hate, WeekId, AreaId )

식단 테이블에서 식단을 구성하는 메뉴를 별도의 속성으로 두어 관리하였습니다. 이때의 문제점은 null-safe 하지 못하다는 것입니다.
사전에 식단 정보가 입력되지 않은 채 조회하려고 하면, null 에 대한 처리가 menu1 ~ menu6 까지 6번 이루어져야 합니다.

[개선 방안]
Converter를 이용해 ,로 menu를 구분지어 리스트 형태로 하나의 컬럼에 메뉴를 저장합니다. ( 이 방식은 이미지 주소 값을 배열 형태로 저장하는 구성에서 착안하였습니다. )
클라이언트에게 반환하는 응답 데이터 형식 역시 List 타입이라면, DB 에서도 List 타입으로 저장하고 있어도 문제가 없을 것이라 생각합니다.

  1. 개발 중 마주한 이슈

고민 Point는 아니지만, RDB와 MongoDB를 혼합해서 사용하다보니, Document를 정의할 때 사소한 이슈가 있었습니다.
@Id 어노테이션의 import 오류로 인한 save 함수에서의 duplicate-key exception 발생입니다.
JPA를 사용하면서 @Entity 어노테이션을 이용하여 테이블을 정의할 때, @Id 어노테이션을 통해 PK임을 표시합니다. 이때의 import와 Document에서 사용하는 @Id의 import가 다릅니다. 이 점을 놓쳐서 _id 가 중복된다는 오류를 마주했습니다. 😅

작업 순서

  1. 해당 브랜치 pull 받기
  2. [Terminal] 열기 -> docker-compose up -d 명령어 입력하기
  3. 도커 컨테이너 구동 확인 후, 스프링 어플리케이션 실행하기
  4. 아래 API로 요청 보내기
    [식당 추가하기] POST
  • URL

localhost:8080/api/v3/dish/restaurant

  • DATA
{
    "name" : "MCC식당",
    "campusType" : "SEOUL"
}

[식단 추가하기] POST

  • URL

localhost:8080/api/v3/dish

  • DATA
{
    "offeredAt": "2023-03-24",
    "mealType": "LUNCH_A",
    "statusType": "OPEN",
    "restaurantId" : "641d4125f1a1563e43ad3737", // 위에서 반환받은 식당ID 넣어주세요.
    "menu" : ["백미", "미역국", "제육볶음"]
}

[식단 조회하기] GET

  • URL

localhost:8080/api/v3/dish

[좋아요] PUT

  • URL

localhost:8080/api/v3/dish/love

  • DATA
{
    "userId" : "string", // 이건 그대로 사용하시면 됩니다. 테스트 계정이라서.
    "dishId" : "641d4132f1a1563e43ad3738" // 여기에 위에서 반환 받은 식단 ID 넣어주세요.
}

@dldmsql dldmsql added the implement 구현 label Mar 24, 2023
@dldmsql dldmsql requested a review from Qbeom0925 March 24, 2023 07:01
@dldmsql dldmsql self-assigned this Mar 24, 2023
@github-actions
Copy link

Unit Test Results

3 tests   3 ✔️  0s ⏱️
2 suites  0 💤
2 files    0

Results for commit db3ea92.

Copy link
Member

@Qbeom0925 Qbeom0925 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고민 Point에 대한 생각

  1. 스키마 디자인
    저는 ID 기반 조회에 익숙하기에 References 방법이 적합하지 않을까 싶어요.

  2. MongoTemplate vs. MongoRepository
    저 또한 같은 Template의 세밀한 조작이 필요하지 않을 것 같아 Repository가 적합한 것 같습니다. 실제로 명식이 개발하면서 Repository를 벗어나는 개발은 한 적은 없습니다.

3. MongoDB로의 마이그레이션이 옳은 선택일까?

제가 가장 고민한 부분인 것 같습니다.
a. 왜 몽고디비로 바꾸려하나?
식당의 운영 다양성이 RDB와 맞지않다고 생각했기에 적용하려 했습니다.

b. 현재는 어떠한가?
현재 식당은 새로운 식당이 출시하면서 기존의 중식, 석식을 벗어나는 메뉴가 등장하며 기존의 설계로는 표현이 힘든 부분이 있습니다.

c. 그 부분은 RDB로는 표현이 불가능한가?
저 또한 ,로 표현하는 것에 큰 동의를 하며 List로 표현해도 좋다고 생각을 합니다. -> 해당 방법으로 Meal에 대한 요구사항 변경은 대응할 수 있습니다.

  • Meal을 제외한 Status에 대한 요구사항 변경에 대한 대책을 강구해야할 것 같습니다.

d. NoSQL에 익숙하지 않은 현재 마이그레이션은 적합한가?
기존의 기능이 많지 않기에 기능을 옮기는 것에 대해서는 무리가 없을 것 같습니다. 단, NoSQL에 대해 익숙하지 않은 상태에서 마이그레이션 진행은 오히려 성능저하를 초래할 수 있을 것 같습니다.

최종

MongoDB vs 기존 RDB Meal ,로 표현하는 방식 + Status 대책 강구
저는 후자가 더 옳다고 생각합니다. 그 이유는 c와 d를 기반으로 설명할 수 있습니다.

의견

NoSQL 데이터베이스는 SQL 데이터베이스와 다른 데이터 모델과 쿼리 언어를 사용하기 때문에, SQL 데이터베이스에서 NoSQL 데이터베이스로의 마이그레이션은 익숙하지 않은 사용자에게는 적절하지 않을 수 있습니다.

또한, NoSQL 데이터베이스는 스키마가 유연하고 동적으로 변경할 수 있기 때문에, 기존의 SQL 데이터베이스에서 사용하던 스키마를 NoSQL 데이터베이스에 그대로 가져오는 것이 쉽지 않을 수 있습니다. 따라서 데이터 모델링이 필요하며, 이를 위해서는 NoSQL 데이터베이스에 대한 이해와 경험이 필요합니다.

마이그레이션 과정에서 이러한 문제들을 해결하기 위해서는, NoSQL 데이터베이스에 대한 충분한 이해와 경험이 필요하며, 데이터 모델링에 대한 경험과 노하우가 필요합니다. 따라서, NoSQL에 익숙하지 않은 상태에서 마이그레이션을 진행하는 것은 성능 저하나 데이터 불일치 등의 문제를 초래할 수 있으므로 기존의 RDB의 방식을 유지하는 것이 옳다고 판단됩니다.

Copy link
Member

@Qbeom0925 Qbeom0925 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

기능 확인 완료하였습니다.

@dldmsql
Copy link
Member Author

dldmsql commented Mar 25, 2023

저 역시 @Qbeom0925 님과 마찬가지로 운영 디비의 마이그레이션은 위험성 있는 시도라고 생각됩니다. 하지만 로컬 환경에서 마이그레이션을 연습하고 명식이에 맞는 스키마 디자인을 찾는 과정은 필요하다고 느껴집니다.

따라서! 해당 브랜치를 기준으로 로컬 환경에서만 마이그레이션을 해보면 어떨까합니다.
현재 작업된 내용에서까지는 운영디비에 read 작업하는 쿼리만 발생시키고 있습니다. 운영환경에 영향이 가지는 않을 것이라 생각됩니다.

더이상 몽고디비를 적용하지 않을 것이라면, 해당 브랜치는 closed하는 게 맞다고 생각되어서 의견 여쭤봅니다!

Copy link
Member

@Qbeom0925 Qbeom0925 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

스키마 디자인을 찾는 과정은 필요한 것에 크게 공감합니다!
즉, 로컬 환경에서 각자 마이그레이션을 진행해보도록 하죠!!

@dldmsql
Copy link
Member Author

dldmsql commented Mar 25, 2023

그럼 지금 이 pr 브랜치는 머지할까요..? (머지하고 각자 로컬에서 url을 v3로 해서 작업하나요..?)

@SsongSik
Copy link
Member

만일 작업을 하게 되고, 반영이 잘 돼서 구조를 바꾸게 된다면 v3로 작업을 하셔야 될 것 같습니다!

@Qbeom0925 Qbeom0925 merged commit 7fee65d into develop Mar 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants