DB migration(DynamoDB to MongoDB)

Beomhyunkim
aaant
Published in
5 min readApr 27, 2022

DynamoDB를 사용하던 중 MongoDB로 전환을 하게 되었고 이유와 과정을 공유하고자 합니다.

DynamoDB 를 포기하게된 이유
1. 항목 당 용량 제한
- DynamoDB는 한 항목의 데이터 크기 제한이 400KB 입니다. 정규화를 통해 한 항목에 저장된는 데이터를 줄이는 방법도 있겠지만 저희 서비스의 특성상 특정 데이터들은 무제한으로 커질수도 있기 때문에 DynamoDB를 포기하게 되었습니다.
2. 데이터 조회의 불편함
- DynamoDB는 다른 DB들의 데이터 조회와 방식이 다릅니다.
query가 있지만 테이블 생성시 지정한 partition key 와 sort key로만 조회가 가능합니다. index 설정을 통해 partition key, sort key를 추가 할 수 있지만 key가 다른 테이블을 하나 더 만드는것과 동일한 리소스를 차지하는것으로 보입니다.
- 데이터 조회의 결과가 1MB로 제한됩니다. 결과에 LastEvaluatedKey 가 포함되어있는지를 확인하고 추가로 조회하는 로직을 직접 만들어야 합니다. pagination 구현이 쉽다고 생각할수 있지만 선택할수 없이 1MB 제한이라 불편할수 있습니다.
- 테이블 Join 개념이 없어서 애플리케이션 레벨에서 직접 처리해야한다.

MongoDB를 선택한 이유
1. DynamoDB 와 동일한 NoSQL
기존에 사용하던 DynamoDB의 데이터를 유지하기 위해서는 NoSQL을 사용할수 밖에 없었습니다.
2. mongoose
- schema, populate 등의 기능을 통해 RDBMS와 유사하게 사용 가능

Migraion 과정

  1. ObjectId
    ObjectId란 document 내에서 유일함이 보장되는 12 byte binary data 입니다. 쉽게 생각하면 RDBMS에서 Primary key에 해당되지만 형식이 고정되어있다고 생각할수 있을것같습니다.
    기존의 DynamoDB에서 사용하던 데이터를 그대로 migraion 하기 위해서는 각 테이블 마다 사용되고 있던 partition key 를 12 byte binary data 즉 objectId의 형태로 만들어줄 필요가 있었습니다. 이때 주의할 점은 모든 참조되어있는 곳의 데이터도 변경해주어야 합니다. 저희의 경우 S3 버킷에 저장하는 경로에도 partition key 가 사용되고 있었고 S3의 copyObject를 사용하여 해결했습니다.
  2. Schema 정의
    DynamoDB에서는 partition key와 sort key만 지정해 줄뿐 나머지 데이터는 어떠한 형태로 들어오던 심지어 기존에 있던 데이터와 구조가 다르더라도 아무런 영향이 없습니다.
    이는 대부분의 noSQL에서 동일하게 동작하고 있습니다. mongoDB 또한 마찬가지입니다. 이는 편리하다고 생각할수도 있지만 오타등의 실수가 발생했을 때 디버깅 하기가 힘들게 됩니다.
    mongoose에서는 Schema를 정의해두고 사용함으로써 이를 해결합니다. 하지만 document의 field중 object타입의 key가 동적으로 생성되는 경우에는 사전에 정의해두는게 불가능합니다.
    이를 위해서 Schema.Types.Mixed를 사용하게 되었는데 사실상 정의를 안하고 무엇이든 들어올수 있는것이기 때문에 어떻게 개선할수있을지 고민중 입니다.(좋은 방법이 있으면 알려주세요!)
  3. DAO(Data Access Object)
    (node.js + express , MongoDB 환경으로 DAO 라는 개념이 맞는지는 모르겠지만…)
    mongoose를 사용 할때 service에서 model을 통해 직접 db에 접근하는 형태로도 많이 사용하는것 같은데 좋은 패턴인지 잘 모르겠습니다.
    저는 Controller -> Service -> DAO 구조가 익숙하고 자연스럽게 느껴집니다. DynamoDB를 사용할때에도 이와 동일한 형태에 DAO에서 처리하고 있었고 DAO에서 DynamoDB에 접근하는 코드를 mongoose의 model을 이용하는 것으로 변경하는것으로 처리하였습니다.
    이때 실수를 방지하고자 한다면 DB unit test 를 꼼꼼하게 작성해두면 좋습니다.(저희는 테스트가 부족 했어서 이번 기회에 모두 추가 하는 중 입니다)
  4. Data migraion
    이제 모든 준비가 끝났기 때문에 기존 데이터를 옮겨주고 배포하면 끝!
    DynamoDB에서 데이터를 csv로 export하고 mongoDB에 import 하는 방식도 가능할것으로 보입니다.
    하지만 저는 script code를 짜서 진행하였습니다. 이유는 DynamoDB에 오염된 데이터가 너무 많아서 mongoose의 Schema로 정의해둔 데이터 외에는 들어가지 않도록 하기 위해서 입니다.

--

--