MongoDB는 겜린더에 적합한 DB일까?

강문혁·2023년 8월 26일
0

겜린더

목록 보기
7/9
post-thumbnail

이 글에는 코드가 없습니다.
현재 문제점과 어떻게 해결해야 할지 고민한 글입니다.

다음 글에 전체적인 백엔드 구조와 함께 정리해서 올릴 예정입니다.
아마 다음 글이 최종 백엔드 설계가 아닐까 싶네요 :)


문제인식

현재 겜린더의 DB는 Redis로 개발하고 있다.

Redis는 In-Memory 방식이기 때문에 I/O 성능이 정말 빠르지만 반면에 외부요인으로 인해 데이터 손실이 발생할 수 있는 리스크가 존재한다.

그리고 개발과 함께 Redis를 공부하면서 문득 들었던 생각은

"많은 게임 관련 정보를 담아야 하는데 Redis의 메모리 용량으로 감당이 가능할 수 있을까?"

"라즈베리파이의 RAM 용량은 8GB인데 이 8GB를 전부다 사용하면 Swap이 발생할 테고 이러면 어차피 느려지지 않을까?" 라는 의문이 생겼다.

물론 위의 문제를 해결할 수 있는데, 데이터 손실 문제는 RDB, AOF 방식의 백업을 이용해 추후 외부적인 요인으로 데이터 손실이 발생했을 때 복구할 수 있다.

아니면 Redis Cloud를 사용하면 위의 의문들과 데이터 손실 걱정이 모두 해결된다. 하지만 매달 낼 돈이 없기도 하고...🥲
데이터와 트래픽이 늘어날수록 비용이 엄청나다는 글을 읽어버렸다.

LINE 알림 센터의 메인 스토리지를 Redis에서 MongoDB로 전환하기

기존에 LIN은 Redis를 메인 스토리지로 사용하면서 알림 관련 주요 데이터를 Redis에 저장해 서빙하고 있었습니다. 하지만 늘어가는 알림 종류와 스펙, 새 계정 유입 등의 영향으로 Redis 사용률이 지속적으로 증가하면서 결국 가용량의 80% 이상을 사용하는 상황까지 도달했습니다. 이에 따라 스왑 인/아웃(swap in/out)이 발생하면서 Redis 페일오버(failover) 또한 발생하는 상황이었고요.

내가 우려했던 상황이 그대로 LINE에서도 겪었던 문제였다.

그래서 Redis는 캐시 서버, MySQL 같은 디스크에 저장하는 DB를 사용하는 것이 적절하다고 판단했다.

그럼 다시 만들어야겠네...? 거의 다 개발했는데... 😂


문제 해결을 위한 조사

SQL를 제대로 다루지 못하는 나..

사실 난 SQL을 제대로 다루지 못한다.
그래서 갑작스럽게 RDB를 만들면 너무 조잡하고 효율적이지 못한 DB를 구축할 것 같았다.

실제로 MariaDB를 설치해 보고 대충 테이블을 만들었으나… 내가 제대로 만들고 있는지도 감이 잡히지 않았다.

그래서 정석으로 배우자!라는 기분으로 책을 하나 구매해서 개념 정리를 하고 있었다.

RDB vs Document?

겜린더는 JSON 형태로 불러오는데 지인이 차라리 RDB 말고 Document 형식의 MongoDB를 사용하는 것이 어떻겠냐고 조언을 해주었다.

사실 아주 예전에 겜린더를 처음 개발할 때 MongoDB를 사용해보고 싶었지만, 그 당시의 나에겐 너무 복잡하고 당장 앱 만들기도 힘들어서 보류했었는데

MongoDB의 자세한 스펙과 겜린더에 적절한지 판단하기 위해 이 기회에 제대로 조사해 보았다.

겜린더의 데이터 저장 방식

겜린더는 기본적으로 JSON 형식으로 저장을 한다.

일단 JSON으로 저장하는 가장 큰 이유가
서비스 확장 혹은 원하는 기능을 넣을 때 데이터 구조를 자유롭게 변경했어야 했기 때문에 JSON으로 저장했었다.

MongoDB의 BSON (Binary JSON)

MongoDB의 장점 중 BSON(Binary JSON)이 있었는데 JSON Document를 Binary로 인코딩한 포맷이다.

왜 Binary로 인코딩을 했는지 알아보았는데 기존 JSON으로 저장하면 텍스트 기반이라 구문 분석이 느리고 공간 효율성이 떨어졌기 때문에 컴퓨터가 읽기 좋게 Binary 포맷으로 저장해 구문 분석과 공간 효율 단점을 해결하였다.

공식 스펙 사이트가 있다.
BSON Spec

이 3가지가 대표적인 특징이라는데

  1. 경량화

    • 경량화는 모든 데이터 표현 형식에서 매우 중요한 요소

    • 특히 네트워크를 통해 사용되는 경우는 더욱 중요하다.

    • 그만큼 트래픽을 줄이고 공간을 최대한 활용할 수 있다는 의미이기 때문이다.

  2. 횡단 가능

    • BSON은 쉽게 탐색할 수 있도록 설계되어 있다.

    • 기본 데이터 표현이 필요한 MongoDB에 있어서 필수적인 속성이다.

  3. 효율적

    • BSON으로 인코딩하고 BSON에서 디코딩 하는 것이 C 데이터 유형을 사용하기 때문에 대부분의 언어에서 매우 빠르게 수행된다.
  1. 이 밖에도

    • JSON 보다 더 많은 데이터 타입을 사용할 수 있다.

이런 특징을 보고 RDB보단 Document 방식에 자유롭게 데이터 구조를 변경할 수 있는 MongoDB를 사용하는 것이 더 좋다고 판단하였다.


데이터 모델링

Ref.
(NHN Cloud) mongoDB Story 3: mongoDB 데이터 모델링

LINE+가 사내에 MongoDB를 도입한 이유

일단 데이터 모델링의 정확한 정의를 짚고 넘어가자

데이터 모델링이란 데이터를 정확하고 효율적으로 데이터베이스에 저장하기 위해 데이터 구조를 설계하는 과정을 의미한다.

RDB의 데이터 모델링은 Table 설계 후 Column을 설계하는 순서이지만, MongoDB는 Document를 설계 후 Collection을 설계하는 순서로 진행된다.

물론 그 이전에 요구사항과 필요한 데이터가 무엇인지 분석해야 하지만 이미 Redis로 설계하면서 필요한 데이터와 요구사항을 정립해뒀기 때문에 넘어간다.

Document 구조

MongoDB에는 Document 구조가 2가지 존재한다.

1. Embedding

관계를 갖는 데이터 집합을 단일 Document에 포함하여 저장하는 방식

장점

  • 데이터 관리가 직관적이고 쿼리가 단순
  • 조회 성능이 좋고 도큐먼트에 포함된 관련 데이터를 모두 업데이트할 수 있다.
  • 구조가 단순해 반정규화 모델이다.

단점

  • 구조가 단순하고 조회 성능이 좋아지지만 데이터 불일치가 발생할 수 있다.

  • Document에 포함하는 데이터가 증가할수록 크기도 증가하여 디스크 I/O 시 성능 저하 및 최대 크기를 초과하면 저장이 불가능하다.

2. Referencing

Document에 관계를 갖는 다른 Document의 식별자를 참조키로 저장하여 필요시 애플리케이션에서 조인하는 방식

장점

  • 데이터가 중복되지 않도록 업무 성격별로 컬렉션을 분리 후 참조하므로 데이터 불일치가 발생하지 않는 정규화 모델
  • 적절한 업무 단위의 Collection으로 데이터가 분리되어 Embedded 방식 대비 Document의 크기 증가가 작다.
  • 업무 요건 추가 및 변경으로 인한 도큐먼트 구조에 미치는 영향이 적다.

단점

  • 참조가 많거나 대규모 Document를 조회하는 경우 애플리케이션에서 2차 쿼리로 인한 처리량 증가로 조회 성능이 저하될 수 있다.
  • 데이터 중복으로 인한 일관성 문제는 해소되나 참조 정보를 정확하게 관리하지 않는 경우 참조 정보 소실에 의한 데이터 정합성 문제가 발생할 수 있다.

Collection

관계형 데이터베이스의 Table과 같은 개념으로 용도가 같거나 유사한 도큐먼트들의 그룹을 묶는 단위를 의미한다. 간단하게 특징만 정리해 보자

1. Normal Collection

  • 가장 일반적으로 사용되는 컬렉션이다.

2. Capped Collection

  • 고정된 크기를 갖는 Collection으로 높은 성능의 Logging 기능을 위해 설계되었다.

3. TTL Collection

  • TTL Collection은 특정 시간이 경과한 도큐먼트를 자동으로 삭제하는 컬렉션으로 TTL 인덱스에 의해 지원되는 기능이다.

4. System Collection

  • mongoDB 내부에서 사용되는 컬렉션으로 사용자가 지정하여 사용할 수 없다.

겜린더에는 어떤 Document 방식이 적합할까?

겜린더는 DB에 있는 게임 정보를 간단하고 빠르게 조회할 수 있는 기능이 핵심이다.

그렇다는 의미는 조회 성능이 중요하고 업데이트가 자주 발생하지 않는다.
어차피 데이터는 크롤러가 수집 후 DB에 계속 집어넣기 때문이다.

그래서 도달한 결론은 겜린더에는 사실 Embedded 방식이 매우 적합하다고 생각한다.


조사하면서 느낀 점

최근 Redis, SQL을 공부한 덕분에 MongoDB의 용어가 이해하기 쉽고 빠르게 넘어갈 수 있었다고 생각한다.

사실 MongoDB를 사용해야 할지 1달 가까이 Docs를 읽어가면서 고민을 했는데, 이유는 간단했다.
기존 개발한 것들을 싹 다 갈아엎어야 하기 때문이었다.

하지만 장기적으로 봤을 땐 무조건 적용해야 한다는 생각과 함께 MongoDB와 RDB을 같이 공부할 수 있었다.

조사와 설계는 다했으니 이제 직접 만들어보면서 겪은 문제점과 어떻게 해결했는지 메모하면서 개발을 이어가야겠다.

프론트도 UI를 엄청 고민하면서 제작 중이다.
변천사들이 좀 많아서 개발하는 과정에서 UI&UX가 어떻게 변화했는지 적어볼 예정이다.

profile
흔들리지 말고 나만의 공부를 하자

0개의 댓글