NoSQL DB 도입기

승톨·2023년 12월 8일
1
post-thumbnail

인트로

  • NFT 거래소를 만들면서 외부 플랫폼 데이터 저장을 위해 어떤 DB를 사용할까?를 고민해보고 리서치 한 결과, NoSQL DB를 사용하기로 결정하고 도입을 했던 바 있습니다.
  • 이번 글에서 NoSQL이 무엇이고, 왜 NoSQL을 도입했고, 그 중에서도 어떤 NoSQL DB를 선택했는지 이야기해보려고 합니다.

NoSQL이란

  • NoSQL은 Not only SQL의 약자로 SQL만을 사용하지 않는 DBMS(DataBase Management System)을 의미합니다.
  • 따라서 Relational DataBase(RDB) 와는 다르게 관계형 모델을 사용하지 않습니다.
    • 참고로, RDB(Relational DataBase)는 데이터 간의 관계에 초점을 두고 있으며 키와 값들의 관계를 테이블화 시킨 데이터베이스를 의미합니다. ex: PostgreSQL, MySQL 등

      여러분이 지금껏 다루어온 데이터베이스들이 이러한 테이블 구조를 가지고 있다면 그것들은 모두 RDBMS라고 볼 수 있는 것이죠.

NoSQL의 특징

  1. 데이터 간의 관계를 정의하지 않는다.
    • RDBMS는 데이터 관계를 외래키 등으로 정의하고 JOIN 연산을 수행할 수 있지만, NoSQL은 기본적으로 JOIN 연산이 불가능합니다. (JOIN 연산 = 서로 다른 두 개의 테이블을 결합하는 연산)
  2. RDB에 비해 더 많은 용량의 데이터를 저장할 수 있다.
    • RDB는 주로 단일 시스템에서 작동하며, 이 시스템의 저장 용량은 해당 하드웨어의 한계에 의해 제한됩니다.
    • 반면에 NoSQL은 '스케일 아웃'이라는 기법을 사용하여 데이터를 여러 서버에 분산시켜 저장할 수 있습니다. 따라서 훨씬 더 큰 데이터 세트를 관리하는데 용이합니다.
  3. 유연한 스키마를 가지고 있다.
    - NoSQL 데이터베이스는 비정형 데이터를 저장하고 관리하는데 특화 되어있습니다. 비정형 데이터를 다루기 때문에 다양한 데이터 형태를 받아들일 수 있으며, 데이터 구조 변경 없이 새로운 데이터 타입을 도입할 수 있습니다.
    - 데이터를 저장하는 칼럼이 각기 다른 이름과 다른 데이터 타입을 갖는 것이 허용된다.
    - schemaless라고도 하며, 구조에 대한 정의를 변경할 필요 없이 데이터베이스 레코드에 자유롭게 필드를 추가할 수 있다.

    schema란 : 데이터베이스에서 자료의 구조, 자료의 표현 방법, 자료 간의 관계를 형식 언어로 정의한 구조

  1. 스케일 아웃이 가능하다.
    • NoSQL 데이터베이스는 수직 확장(새로운 하드웨어를 추가하여 성능을 향상시키는 방식)이 아닌 수평 확장(더 많은 서버를 추가하여 데이터와 트래픽을 분산시키는 방식)을 통해 데이터베이스를 확장할 수 있습니다. 이로 인해 대규모 데이터를 다루는데 매우 유용합니다.
  2. 다양한 데이터 모델을 지원한다.
    • NoSQL 데이터베이스는 여러 종류의 데이터 모델을 지원합니다. 예를 들어, Key-Value 타입, Document 타입, Graph 타입 등을 지원합니다.

NoSQL의 장점

  1. 분산처리와 병렬 처리 가능(수평확장 가능)

    • 대부분의 관계형 데이터베이스는 데이터의 정합성 및 일관성 문제로 인해 인스턴스를 여러 대로 늘려 성능을 수평적으로 확장하는 Scale-Out 대신, 인스턴스 자체의 성능을 수직적으로 확장하는 Scale-Up 방식을 이용해야 합니다.
    • 이는 성능 향상에 한계가 있을 뿐만 아니라, 인스턴스 하나가 온전히 부하를 감당해야 하므로 가용성에 문제가 생길 가능성이 높습니다.
    • 하지만 NoSQL 데이터베이스는 연관되어 있는 데이터들을 중복으로 저장하여 데이터 분산이 용이한데요. 따라서 Scale-Up 뿐만 아니라 Scale-Out으로 성능 확장이 쉽습니다. (Scalability가 높다)
    • 따라서 대용량 데이터 처리에도 효과적이라고 할 수 있습니다.
  2. 가변적인 구조로 데이터 저장이 가능 / 데이터 모델의 유연한 변화가 가능

    • 관계형 데이터베이스는 미리 정의된 스키마를 통해 데이터를 다루기 때문에 데이터 또는 스키마를 변경할 때 유연하지 못하고 비용이 많이 듭니다.
    • 하지만 NoSQL은 스키마가 없으므로, 유연하고 자유로운 데이터 구조를 가질 수 있습니다. 따라서 변화하는 어플리케이션 요구사항에 맞춰 쉽게 데이터를 추가하거나 변경할 수 있는 장점이 있습니다.

NoSQL의 단점

  • 데이터가 여러 컬렉션에 중복으로 저장되어 있기 때문에, 데이터를 수정 또는 삭제해야 한다면, 데이터가 저장된 모든 컬렉션에 대해 이를 수행해야 합니다. 데이터 동기화에 신경을 써야 합니다.
  • 스키마가 존재하지 않다는 것은 단점이 될 수 있는데요. 데이터 구조가 명확하지 않기 때문에 데이터 구조 정의가 어려울 수 있습니다.
  • 확장성이 높아지는 대신, 일관성이 떨어질 수 있습니다.

NoSQL 종류

NoSQL 데이터베이스는 크게 3가지 종류로 나뉩니다.

  1. Key-Value DB
  2. Document DB
  3. Column Family DB

(이외에도 Graph DB라는 타입도 있습니다.)

Key-Value DB

  • 키와 값으로 이루어진, 저장과 조회라는 가장 간단한 원칙에 충실한 데이터베이스입니다.
  • Key-Value DB의 Key 값은 unique한 고유값으로 유지되어야 합니다.
  • JOIN 연산을 고려하지 않으므로 RDB에서 관리하는 외부키나, 컬럼별 constraints 등이 필요 없습니다.
  • 간단한 데이터 모델을 대상으로 데이터를 자주 읽고 쓰는 애플리케이션에 적합합니다. boolean이나 integer타입처럼 원시 타입뿐만 아니라, 리스트나 JSON같은 구조화된 타입도 지원합니다.
  • 종류:
    • Redis
    • Oracle Berkely
    • AWS DynamoDB
  • 이런 케이스에 사용하면 좋습니다 :
    • 성능 향상을 위해 데이터 캐싱
    • 장바구니 같은 웹 애플리케이션에서 일시적인 속성 추적
    • 이미지나 오디오 파일 같은 대용량 객체 저장
    • 대용량 로그 저장

Document DB

  • Document DB는 데이터 저장에 Key-Value Type을 사용합니다만, Key-Value DB와의 중요한 차이는 Document DB는 값을 문서로 저장한다는 점입니다.
  • Document란 데이터 단위이며, ****JSON, BSON, XML과 같은 형태로 저장됩니다.
  • 값을 저장하기 전에 schema를 별도로 정의하지 않으며, Document 타입을 지정하면 그게 바로 schema가 된다고 볼 수 있습니다.
  • Document별로 다른 필드를 가질 수 있으며, 따라서 개발자가 애플리케이션에서 데이터를 입력하는 단계에서 컬럼과 필드의 관리가 제대로 이루어지도록 보장하는 것이 매우 중요합니다.
  • 예를 들어 필수 속성(Null을 허용하지 않는 속성)에 대한 관리도 애플리케이션 레벨에서 관리가 이루어져야 합니다.
  • 종류 :
    • MongoDB
    • CouchDB
    • AWS Document DB
  • 이런 케이스에 사용하면 좋습니다 :
    • 대용량 데이터를 읽고 쓰는 서비스 백엔드 지원
    • 다양한 속성이 있는 데이터 관리
    • 유형이 다양해질 수 있는 메타데이터 저장
    • 비정규화된 중첩 구조의 데이터를 사용하는 앱 백엔드

Column Family Database

  • Column Family DB는 대용량 데이터, 읽기와 쓰기 성능, 고가용성을 위해 설계된 DB입니다.
  • Column과 Row를 지정할 수 있습니다.
  • Column 수가 많다면 관련된 컬럼들을 컬렉션으로 묶을 수 있습니다.
    • 예를 들어 성과 이름을 “이름”으로 묶고, 사무실 전화번호, 핸드폰 전화번호를 “전화번호”로 묶을 수 있습니다. 이렇게 묶인 컬럼들을 Column Family라고 합니다.
  • 미리 정의된 스키마를 사용하지 않으므로 개발자가 데이터를 입력하는 시점에 원하는대로 컬럼을 추가할 수 있습니다.
  • 데이터는 보통 비정규화 되어 저장되며 한 객체에 관련된 모든 정보를 단일 Row에 넣어서 보관합니다. 따라서 한 Row에 수백만개의 컬럼을 보관하는 경우도 있습니다.
  • 보통 Column Family DB는 여러대로 구성된 클러스터에서 운영됩니다.

columnfamily

  • 종류 :
    • Hbase
    • Cassandra
    • GCP BigTable
  • 이런 케이스에 사용하면 좋습니다 :
    • 데이터베이스에 쓰기 작업이 많은 애플리케이션
    • 지리적으로 여러 데이터 센터에 분산되어 있는 애플리케이션
    • 복제본 데이터가 단기적으로 불일치하더라도 큰 문제가 없는 애플리케이션
    • 수백만 테라바이트 정도의 대용량 데이터를 처리해야 하는 애플리케이션

왜 NoSQL을 도입했는가?

  • 인트로에서 말씀드린대로 제가 개발했던 프로젝트는 NFT 거래소였는데, 블록체인 관련 서비스이지만 백엔드에 거래(오더) 데이터를 저장해야했기 때문에, Database가 필요했습니다.
  • v1 버전에서는 자체 거래 데이터만 취급했기 때문에 데이터를 정규화 했었고, AWS RDS(PostgreSQL)를 사용했었습니다.
  • 그러다가, 써드파티 플랫폼의 데이터도 수집해서 보여주면 좋겠다는 요구사항이 추가 되었는데요.
  • 해당 플랫폼의 데이터는 이미 정해진 규격(JSON)이 있긴했지만, 데이터 케이스마다 사용하는 필드 값들이 다른 경우가 있었습니다.
  • 그리고 정책이 변경되면, 특정 필드들이 삭제되거나 추가되는 일들이 존재했는데요.
  • 그러다보니 RDB보다는 스키마를 유연하게 구성 할 수 있는 NoSQL 데이터베이스를 사용해야겠다 라는 결론을 내렸습니다.
  • 처음에는 Redis같은 Key-Value DB를 생각했으나, 수집해야 하는 오더 데이터의 양이 기존에 취급하던 데이터의 양보다 많았고(일 평균 약 150,000건), 인메모리에 의존하기에는 리스크가 있다고 생각해, AWS DynamoDB / AWS Document DB / Mongodb로 선택지를 좁혀서 고민했습니다.

왜 AWS Document DB를 선택했는가?

DB를 선택할 때 4가지 기준을 가지고 있었는데요.

  1. 안정성, 유지보수
  2. ODM 지원
  3. 학습 비용
  4. Throughput

1. 안정성, 유지보수

처음에는 자체 MongoDB 서버를 구축하는 방법도 생각해봤으나, Failover, Scaling을 생각했을 때는 AWS 인프라를 사용하는게 좋다고 판단했습니다. 그래서 우선 AWS의 대표적인 NoSQL DB인 AWS Document DB vs AWS DynamoDB로 범위를 더 좁혔습니다.

2. ODM 지원

  • 직접 DB의 DDL, DML을 사용해서 접근할 수도 있지만, ODM(Object Document Mapping) 라이브러리가 있으면 비즈니스 로직 작성에 더 집중할 수 있을 것이라 판단해 지원 라이브러리를 조사해보았습니다. DynamoDB의 경우 Dynamoose라는 라이브러리가 있었고, DocumentDB의 경우 Mongoose라는 라이브러리가 있었습니다.
  • 둘다 유지보수도 잘 되는 편이고, 사용층은 두터운 편이었지만 레퍼런스,자료는 Mongoose가 훨씬 많은 편이었습니다.

3. 학습 비용

기존에 제가 주로 사용했던 데이터베이스는 AWS DynamoDB였고, MongoDB(Document DB)는 사용 경험이 많지 않았으나, 학습 비용이 높진 않다고 판단했습니다. 따라서 이 부분은 높은 중요도를 매기진 않았습니다.

4. Throughput

사실상 결정에 가장 큰 요소였는데요.

요구사항을 구현하기 위해 NFT 콜렉션마다 존재하는 모든 거래를 실시간으로 다 가지고 와야했으므로, batchWrite가 필요한 상황이었습니다.

AWS Document DB, DynamoDB 모두 batchWrite를 지원했지만,

DynamoDB는 batchWriteItem을 사용할 때 한 번에 최대 25개의 아이템을 넣을 수 있었는데, 이 제한을 초과하는 아이템을 처리하려면 여러 번의 요청으로 나누어야 합니다. 즉, 한번에 최대 25개의 거래 데이터를 넣을 수 있는 것이죠. 아이템에 들어갈 수 있는 데이터 사이즈는 최대 400KB 였습니다.

반면, DocumentDB의 경우 단일 Bulk Write 작업에 최대 100,000개의 아이템을 포함시킬 수 있었습니다. 또한 단일 Bulk Write 작업의 최대 크기는 16MB입니다. (BSON 형식으로 인코딩된 문서의 크기 포함)

쿼리의 경우,

DynamoDB는 key-value 기반 쿼리를 지원합니다. primary key 기반으로 최대 2개 attribute 지정해서 쿼리 가 가능한데요.

추가적인 쿼리가 index(Global Secondary Index, Local secondary Index)로 가능하지만, 지정한 인덱스로만 쿼리 수행이 가능하며, index 지정 개수에 제한이 있습니다.

DocumentDB는 single key, ranges, JOINs, geospatial queries 등 다양한 조건으로 쿼리가 가능 & object array도 쿼리가 가능합니다.

추후에 여러가지 필터 기능이나 복잡한 쿼리를 해야하는 경우가 생길 수 있었기 때문에, 다양한 쿼리 조건을 지원하는 것도 중요 했습니다.


4가지 기준을 모두 놓고 봤을 때 DocumentDB를 쓰는게 낫다고 판단하여 DocumentDB로 결정하게 되었습니다.

마치며

NoSQL DB 구축을 하면서 NoSQL에 대해 좀 더 잘 알 수 있게 되었고 DB 사용에 더 익숙해지는 기회가 되었습니다.

또한 DB 도입 리서치를 하면서 AWS DocumentDB 뿐만 아니라 MongoDB Atlas라는 옵션도 알게 되었는데요.

atlas

  • MongoDB Atlas는 MongoDB 팀에서 제공하는 클라우드 기반의 Managed MongoDB 서비스입니다.
  • 인프라 프로비저닝, Failover 수행, 최신 패치 적용 등의 Managed 서비스의 장점을 모두 가지고 있습니다.
  • 사실 DocumentDB는 MongoDB를 한번 더 추상화해서 만든 DB이므로, 최신 MongoDB에서 지원하는 기능(특정 aggregate, expr 기능 등)을 100% 제공하진 않습니다.
  • Atlas 또한 AWS 위에서 구축이 가능하므로, 순수 MongoDB의 기능이 더 필요해지면 Atlas로 전환 하는 것도 고려해 볼 수 있을 것 같습니다.
profile
소프트웨어 엔지니어링을 연마하고자 합니다.

0개의 댓글