Backend/FastAPI

DockerCompose & MongoDB

지미닝 2024. 3. 18. 20:30

원래 글: https://velog.io/@stopmin/DockerCompose-MongoDB

🤔 Docker Compose

docker compose는 여러 개의 docker container를 모아서 관리하기 위한 툴이다.

웹 서비스는 일반적으로 프론트엔드 서버, 벡엔드 서버, 데이터베이스 서버로 구성되기 때문에 각 서버를 docker container로 연결하여 동작시키고 docker compose를 사용하여 해당 컨테이너들을 관리하는 것이다.

사용 방법

  1. 각각의 컨테이너의 Dockerfile를 작성한다(기존에 있는 이미지를 사용하는 경우는 불필요).
  1. docker-compose.yml를 작성하고, 각각 독립된 컨테이너의 실행 정의를 한다(경우에 따라는 구축 정의도 포함).

  2. "docker-compose up" 커맨드를 실행하여 docker-compose.yml으로 정의한 컨테이너를 개시한다.

✏️ Docker-compose.yml?

docker-compose.yml파일에 모든 서비스를 정의한다.
그 자체로는 일반 텍스트 파일 이지만 docker-compose의 빌드 프로세스를 통해 실행할 수 있다. 그리고 이 빌드 프로세스는 실제로 이미지를 생성할 수 있으며 이미지를 실행하면 컨테이너를 만들 수 있다.

docker-compose.yml 포함 항목들

  • version
    docker compose의 파일 포맷 버전을 지정한다.
    기본적으로 버전 3을 사용하는 것이 일반적이다.
  • services
    한개 또는 여러 개의 docker container를 설정한다.
  • image
    docker container의 이름을 정의한다.
    Docker Hub에 있는 이미지를 사용하여 docker container를 작성할 경우 image를 설정할 수 있다.
  • restart
    docker container가 다운되었을 경우, 항상 재시작하라는 설정이다.
  • volumes
    docker run 명령의 -v 옵션과 동일한 역할을 한다.
    여러 개의 volume을 지정할 수 있으며 리스트처럼 작성하면 된다.
  • environment
    dockerfileENV 옵션과 동일한 역할을 한다.

이하 나중에 실제로 사용해보면서 추가적으로 실습 내용을 정리해가며 자세한 사항 익히고 싶다.

🤔 PymongoDB란?

MongoDBPython 으로 사용하기 위해 널리 사용되는 라이브러리 중 하나이다.`

☁️ MongoDB는 뭐지?

NoSQL DBMS의 한 종류이다.

MongoDBNoSQL로 분류되는 크로스 플랫폼 도큐먼트 지향 데이터베이스 시스템이다. MySQL 처럼 전통적인 테이블-관계 기반의 RDBMS가 아니며 SQL을 사용하지 않는다.

이름의 mongohumongous를 줄인 표현이다. 즉 '겁나 큰 DB' 라는 뜻이다.

SQL vs NOSQL

단어 뜻 그 자체를 따지자면 "Not only SQL"로, SQL만을 사용하지 않는 데이터베이스 관리 시스템(DBMS)을 지칭하는 단어이다. 관계형 데이터베이스를 사용하지 않는다는 의미가 아닌, 여러 유형의 데이터베이스를 사용하는 것이다.
데이터를 조직하는 방법에는 리스트, 해시 테이블, 트리, 그래프 등의 다양한 방법이 있고 각각은 장점과 단점이 명확하기 때문에 단순히 NoSQL이라고만 해서는 너무 뜬구름 잡는 얘기가 된다.

등장 배경

지난 20년간, 데이터를 저장하는 데에는 관계형 데이터베이스가 사용되었다. 트랜잭션을 통한 안정적인 데이터 관리가 가장 중요한 이슈였기 때문이다. 하지만 웹 2.0 환경과 빅데이터가 등장하면서 RDBMS는 난관에 부딪히게 되었는데, 바로 ‘데이터를 처리하는 데 필요한 비용의 증가’때문이다. 데이터와 트래픽의 양이 기하급수적으로 증가함에 따라 한 대에서 실행되도록 설계된 관계형 데이터베이스를 사용하는 것은 하드웨어적으로 큰 비용이 들게 되었다. 장비의 성능이 좋을수록, 성능을 향상시키는 데(Scale-up : 수직적 확장) 비용이 기하급수적으로 증가하기 때문이다.
NoSQL은 데이터의 일관성을 약간 포기한 대신 여러 대의 컴퓨터에 데이터를 분산하여 저장하는 것(Scale-out : 수평적 확장)을 목표로 등장하였다. NoSQL의 등장으로 작고 값싼 장비 여러 대로 대량의 데이터와 컴퓨팅 부하를 처리하는 것이 가능하게 되었다.

특징

  1. 일관성확장성 사이의 trade-off
    일관성(Consistency)이 데이터베이스의 절대적인 요소가 아님을 주장하는 움직임이 생기기 시작했다.
    비일관성이 다음과 같은 두 가지 이유로 감수할 만한 것이라고 주장했다.
    • 다수가 동시에 읽고 쓰는(Read and write) 상황에서의 성능 향상을 위해서.
    • 분산 환경에서 노드들이 잘 작동하고 있음에도, 시스템의 일부가 고장나면 데이터베이스를 사용할 수 없게 되는 문제를 해결하기 위해서.
  2. 분산 저장
    데이터와 트래픽이 증가함에 따라 기존의 장비로는 원활한 데이터의 처리가 어려워졌다. 이를 해결하기 위한 방법으로는 처리하는 장비의 성능을 키우는 수직적 확장(Scale-up)과 처리하는 장비의 수를 늘리는 수평적 확장(Scale-out)이 있다. 위에서 서술했듯이 수직적 확장은 비용적인 문제가 발생하므로 수평적 확장을 통해 성능을 올려야 한다. 하지만 문제는 관계형 데이터베이스가 클러스터 상에서 효율적으로 동작하도록 설계되지 않았다는 점이다.
    샤딩(Sharding)샤드 키(Shard key)를 기준으로 하나의 테이블을 수평 분할하여 서로 다른 클러스터에 분산 저장하고 질의할 수 있는 기법이다. 이를 통해 관계형 데이터베이스에서도 부하를 분산할 수 있지만 어플리케이션 레벨에서 모든 샤딩을 제어해야 한다. (어떤 데이터를 어느 클러스터에서 처리해야 하는지 등) 또한 여러 샤드에 걸치는 쿼리나 참조 정합성, 트랜잭션, 일관성의 제어에 문제가 발생한다.
    분산 저장을 지원하는 NoSQL 데이터베이스의 경우, 집합-지향(Aggregate-oriented) 모델을 사용하여 이러한 문제를 해결한다. 연관된 데이터들이 함께 분산되므로, 관계형 모델에서처럼 복잡한 제어가 필요하지 않게 된다.
  3. 데이터 일치
    RDBMS에서 관계형 튜플 안의 값은 단순해야 하며 중첩된 레코드나 리스트 등 다른 구조를 포함할 수 없는 반면, 메모리 내 데이터 구조에서는 이런 제약이 없어 훨씬 복잡한 구조를 사용한다. (ex : 리스트, 딕셔너리, 중첩된 객체 구조) 그 결과 복잡한 메모리 내 데이터 구조를 데이터베이스에 저장하려면 먼저 관계형 표현으로 변환해야 한다. 물론 이는 ORM(Objective-Relational Mapping : 객체-관계 매핑) 프레임워크를 통해 해결할 수 있지만, 여전히 관계형 모델과 메모리 내 데이터 구조 간에는 데이터 불일치는 존재한다. 이를 Impedance mismatch라 한다.

하지만 NoSQL은 그런 게 없다. 메모리 내의 데이터가 어떤 구조이든지 상관하지 않고 하나의 Aggregation으로 취급하여 저장해버리기 때문이다. 따라서 NoSQL에서는 ORM 프레임워크가 필요하지 않다.
4. Schema-less
NoSQL 데이터베이스의 공통적인 특징은 사용 전에 정의된 명시적인 스키마 없이 동작한다는 점이다. 따라서 데이터 구조를 미리 정의할 필요가 없으며, 시간이 지나더라도 언제든지 바꿀 수 있기 때문에 비형식적인 데이터를 저장하는 데 용이하다. 하지만 이는 데이터베이스가 스키마를 직접 관리하지 않는 것을 의미할 뿐, 데이터 타입에 따른 암묵적인 스키마는 여전히 존재한다. 이 때문에 단일 값에 대한 데이터 타입에서 불일치가 발생할 수 있다.

NoSQL 데이터베이스

그래프 모델을 제외한 나머지 세 모델은 집합-지향(Aggregate-oriented) 모델

  • Key-value
  • Document
  • Column-family
  • Graph

NoSQL vs RDBMS

대부분의 사람들은 NoSQLRDBMS를 대체할 수 있을 것이라고는 생각하지 않는다. 그러기에는 RDBMS가 가진 장점이 너무나 명확하고, 또한 많은 사람들이 RDBMS을 사용하는 데 익숙해져 있기 때문이다. 그럼에도 불구하고 NoSQL이 각광받고 있는 까닭은 NoSQL만의 장점이 뚜렷하기 때문이다.

  • 예를 들어 구매 내역이나 게임의 로그 같은 데이터들은 매 초마다 엄청난 양이 생성되지만 한번 저장되고 난 뒤에는 수정될 일이 거의 없다. 이런 데이터들을 저장하는 데 데이터의 일관성을 보장하기 위해 ACID 트랜잭션을 지원할 필요는 없을 것이다. 거기다 생성되는 데이터의 양도 많기 때문에 장비의 성능에도 상당한 영향을 미칠 것이다. NoSQL은 이러한 데이터들을 효율적으로 저장할 수 있다. 여러 대의 장비에 빠른 속도로 저장이 가능하며, 데이터의 양이 누적되더라도 얼마든지 수평적 확장이 가능하기 때문이다.
    • 실제로 페이스북이나 트위터 같은 소셜 네트워크 서비스에서는 게시글들을 저장하는 데 NoSQL 데이터베이스를 사용하고 있다. 매 초에 수백 기가~수 테라 바이트씩 생성되는 데이터들을 RDBMS를 사용해 저장한다면, 글 작성 버튼을 누른 후 글이 중앙 데이터베이스에 저장되기까지 한참을 기다려야 글을 성공적으로 게시할 수 있을 것이다. 하지만 NoSQL의 분산 데이터베이스를 사용한다면 부하가 분산되기 때문에 우리가 글쓰기 버튼을 누르고 한참을 기다릴 필요가 없게 된다.
    • 각종 검색 엔진에도 사용되는 것이 NoSQL인데, 웹 페이지 내의 텍스트들을 형태소 단위의 토큰으로 분리하여 토큰과 해당 토큰이 포함된 페이지들의 URL을 맵핑하는 Inverted Index(역 인덱스) 구조NoSQL을 통해 구현한다. 이런 기능을 일반적인 RDMBS로 구현했을 경우 검색 창에 단어를 입력했을 때마다 상당한 시간이 소요될 것이다.
    • 하지만 데이터의 일관성이 보장되어야 하거나 여러번의 조인 연산이 필요한 데이터라면 NoSQL을 사용하는 것 보다 RDBMS를 사용하는 것이 좋을 것이다. NoSQLRDBMS를 대체하기 위한 데이터베이스가 아니라 상호 보완할 수 있는 데이터베이스이며, 따라서 목적에 맞게 사용하는 것이 중요하다.

MongoDBMySQL의 테이블과 같은 스키마가 고정된 구조 대신 JSON 형태동적 스키마형 문서를 사용하는데, 이를 MongoDB 에서는 BSON이라고 부른다.

MongoDB는 가장 기본적인 데이터를 Document 라고 부른다. 이는 MySQL같은 RDBMS에서는 row에 해당된다. 이 Document의 집합을 Collection이라고 하는데, RDBMS에서는 테이블(Table)에 해당된다. Collection의 집합은 DB이고, 이는 RDBMS에서도 동일하다.

is MongoDB faster than MySQL?

똑같은 조건으로 설계되었을 시 기존 RDBMS 속도보다 굉장히 빠르다는 장점이 있다. 이런 속도는 ACID를 포기한 댓가로 얻은 것이다. 따라서 데이터 일관성(Consistency)이 거의 필요 없고 조인 연산을 Embed로 대체할 수 있는 경우에는 MongoDB가 확실한 대안이 될 수 있다. 반대로 저장하는 데이터가 은행 데이터 같이 일관성(Consistency)이 매우 중요한 작업에는 MongoDB를 쓰기 매우 힘들다.
➡️ 이건 위에 정리한 내용을 참고하면 더 확실히 알 수 있다!

그리고 추가적으로 MySQLmongoDB의 차이점을 알고 싶다면 mongoDB에서 이 두 가지를 비교한 공식문서를 참고하면 좋을 듯 하다.

참고 페이지

https://engineer-mole.tistory.com/221
https://fronquarry.tistory.com/41
https://unpasoadelante.tistory.com/197
https://namu.wiki/w/NoSQL

'Backend > FastAPI' 카테고리의 다른 글

Precommit Test  (0) 2024.03.18
AID backend project 추가 정리  (1) 2024.03.18
SQLAlchemy  (0) 2024.03.18
[FastAPI] CloneCoding (CRUD, ToDO-list)  (2) 2024.03.18
Pytest & Github action & Docker  (0) 2024.03.18