ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • MongoDB의 기본 개념에 대해 알아보자.
    개발/MongoDB 2020. 6. 21. 14:28
    728x90

    이번에는 MongoDB에 대한 기본 개념에 대해서 알아보겠습니다. 이번 시간에는 각 주제별 자세한 내용을 다루기보다는 mongoDB에 대한 전체적인 개념을 파악하는데 초점을 두었습니다. 😊

     

    1. mongoDB 소개

    • mongoDB는 도큐먼트(document) 지향적인 데이터베이스입니다.

      도큐먼트(document)는 아래와 그림과 같이 field:value 형식으로 구성된 데이터 구조입니다. vaule에는 문자열, 숫자, 날짜, 배열, 다른 도큐먼트를 저장하는 것도 가능합니다.

    https://docs.mongodb.com/manual/introduction/#document-database 그림 참조

    • mongoDB는 스키마를 고정하지 않은 형태(Schema-less 구조)입니다.

      이러한 특징으로 필드 추가 및 제거가 간편합니다.
    • 분산 확장이 간단합니다.

      아래의 그림과 같이 샤딩 시스템(샤딩 : 샤드(분산하는 각각의 장비)에 걸쳐 있는 데이터를 분할하는 처리)을 이용하면 분산 확장이 간단합니다.

    Mongo DB sharding

     


    2. mongoDB 개념

     mongoDB에서는 JSON, BSON 타입 모두 사용합니다. BSON 타입이 무엇인지 어디서 사용되는 건지 알아봅시다. 더 자세한 내용을 확인하고 싶으면 mongoDB 사이트에서 확인해 주세요.

    2-1. JSON 타입과 BSON 타입

    JSON 타입

     mongoDB는 Document 형태로 데이터를 저장합니다. 이러한 표현 방법을 java script 형식의 오브젝트 표기법 즉, JSON 타입이라고 말합니다. 이 데이터 타입은 사람이 읽고 쓰기 쉽고, 기계가 파싱하고 생성하기 쉽다는 장점이 있습니다.

     

    BSON 타입

     mongoDB에서는 모든 데이터는 반드시 JSON 타입으로 표현됩니다. 하지만, 데이터베이스 내에서 저장될 때는 BSON 타입의 바이너리 형태의 데이터로 반환되어 저장합니다.

     BSON 타입은 Binary JSON의 약어로, JSON 문서를 바이너리로 인코딩한 포맷이다. JSON과 비교하여 BSON은 스토리지 공간과 스캔 속도 모두에서 효율적으로 설계되어 있다는 장점이 있습니다.

    2-2. mongoDB 용어 설명

     mongoDB에서 사용하는 용어에 대해 알아봅시다. 이를 쉽게 이해하기 위해 RDBMS 용어와 비교해 봅시다. 아래 표와 같이 mongoDB에서는 table를 collection(컬렉션)이라 하고, row(행)을 Document(도큐먼트), db server를 mongod, db client를 mongo라고 부릅니다.

    RDBMS Mongo DB
    Database Database
    Table Collection
    Row Document
    Index Index
    DB server Mongod
    DB client mongo

     


    3. 기본 쿼리

    이제 mongoDB 기본적으로 사용되는 CRUD 쿼리에 대해 살펴보도록 하겠습니다. 아래 자료는 mongoDB documentation를 참고하였습니다.

    3-1. C(Create) - insert

    insert 명령어를 이용하여 json 형식 데이터를 삽입합니다. 아래 그림과 같이 field:value 형식으로 되어있는 것을 확인할 수 있습니다.

     >  db.users.insertOne({"name":"sue", "age":26, "status":"pending"})

     

    3-2. R(Read) - find

    find 명령어 데이터를 검색하려고 합니다. query criteria에는 조건문을 입력하는 것이고, 그 뒤 projection에는 출력하고자 하는 필드에 1을 넣어 줍니다.

     > db.users.find({age:{$gt:18}},{name:1, address:1}).limit(5) 

     

    3-3. U(update) - update

    특정 조건을 update 할 때 사용됩니다. update filter에 업데이트하고자 하는 도큐먼트 조건을 넣어줍니다. update action에는 업데이트할 것을 넣어줍니다.

     

     > db.users.updateMany( {age:{$gt:18}}, {$set: {status:"reject"}} )

     

    3-4. D(Delete) - delete

    특정 도큐먼트를 삭제할 때 사용됩니다. delete filter에 삭제할 조건을 넣어줍니다.

     

     > db.users.deleteMany( {status: "reject"} )

    4. index

     index에 대해 간단하게 알아보고 넘어가겠습니다. 자세한 내용은 MongoDB index 개념과 indexing 전략 내용을 확인해 주세요.  

    4-1. Index 란?

     Query를 더욱 효율적으로 할 수 있도록 documents에 기준(key)을 정해 정렬된 목록을 생성하는 것입니다. 인덱스가 없다면, Mongo DB는 full collection scan(collection의 데이터를 처음부터 끝까지 하나하나 조회) 방식으로 스캔하게 됩니다. Hash index를 제외하고 Mongo DB는 B-Tree 구조로 Indexing으로 되어 있습니다.

     

    4-2. 기본 Index

    • 모든 Mongo DB의 컬렉션은 기본적으로 _id 필드에 인덱스가 존재합니다.
    • 컬렉션 생성 시 _id 필드를 따로 지정하지 않으면 mongod 드라이버가 자동으로 _id 필드 값을 ObjectId로 설정됩니다.
    • _id 인덱스는 unique 하고 이는 MongoDB client가 같은 _id를 가진 문서를 중복적으로 추가하는 것을 방지합니다.

     

    4-3. Index 생성, 조회, 제거하기

    생성하기

    createIndex() 메소드 사용하여 생성합니다. 값을 1로 하면 오름차순, -1로 하면 내림차순 정렬됩니다.

    > db.collection.createIndex( { key: 1 } ) 

    조회하기

    > db.COLLECTION.getIndexes()  

    제거하기

    > db.COLLECTION.dropIndex( { KEY: 1 } )  

     


    5. data type

    mongodb data type은 아래 사진과 같이 여러 타입이 존재합니다. 많이 사용되는 데이터 타입만 확인하고 넘어가겠습니다.

     

     

    • ObjectId: 12 bytes로 구성된 하나의 document에 유일한 ObjectId가 자동으로 부여됩니다.
    • String: 문자열로 어떠한 UTF-8 문자열도 표현 가능합니다.
    • Date: UNIX 시간 형식으로 저장됩니다. 새로운 Date 객체를 생성할 때는 항상 Date가 아닌 new Date 호출, Date 호출 시 날짜 객체가 아닌 날짜의 문자열 표현 반환합니다.
      • 예) {“x” : new Date()}
      • 기본값) ISODate("1970-01-011T09:00:00.000**+09:00**") : 9시간을 더하면 한국/서울 시간으로 변경.
    • Array: 배열을 표현합니다.
    • Boolen: true, flase 값에 사용합니다.
    • integer: 정수를 저장할 때 사용합니다.
    • double: 부동 소수점을 저장할 때 사용합니다.

    6. 샤딩(Sharding)

    6-1. 샤딩이란

     빅데이터를 저장하기 위해서는 한 대의 서버에 저장하는 것은 불가능합니다. 초당 엄청난 양의 데이터를 insert 하면 Write scaling 문제가 발생하여 서비스 성능 저하를 유발합니다. 따라서 이를 해결하기 위해 여러 대의 서버에 분산 처리하는 것이 이상적입니다.

     샤딩을 하게 되면 여러 대의 독립된 프로세스가 병렬로 작업을 동시에 수행하여 이상적으로 빠른 처리 성능을 보장받습니다. 또 하나의 서버에서 관리를 하면 유실 시 큰 손실이 따르게 됩니다. 분산 처리를 하면 이러한 위험 요소로부터 안전하게 데이터를 저장, 관리할 수 있습니다.

     

    6-2. 샤딩 시스템 구조

    샤딩 시스템 구조 

    mongos 라우터

     mongos 프로세스는 중계자 계층으로 응용 계층(client)에서 전달된 질의를 분석하여 적절한 샤드에 보내는 라우터 역할을 합니다. 또한 mongos는 각 서버에서 어떤 일을 하는지 client가 모르게 해주는 역할을 합니다.

     

    shard

     Shard는 데이터를 하나 혹은 그 이상의 샤드에 걸쳐 분산 저장한다. 각 샤드는 전체 데이터의 일부를 저장한다. 그리고 각 샤드는 그림과 같이 리플리카 셋으로 구성되어 있습니다.

     

    config servers

     config servers는 샤드 시스템에 대한 설정 세팅과 메타 데이터를 저장/관리합니다. 다시 말하면 config servs는 각 샤드 서버에 어떤 데이터가 어떤 식으로 분산 저장되어 있는지에 대한 meta 데이터가 저장되어 있습니다. mongoDB 3.4에서는 config servers도 리플리카셋으로 구성되어야 한다고 합니다.

     

    6-3. shard key 구성

     shard key 구성 방법은 mongoDB 샤딩 시스템 구축할 때 가장 중요합니다. 이는 여러 개의 샤드 서버로 분할될 기준 필드를 가리키며, partition과 load balancing에 기준이 됩니다. 따라서 적절한 카디널리티를 가진 필드가 shard key로 선택되어야 합니다.

     카디널리티는 조건을 만족하는 데이터의 분산 정도를 나타내는 값으로 전체 데이터 중에서 조건을 만족하는 데이터의 분포가 넓으면 낮은 카디널리티라고 하며 분포가 좁으면 높은 카디널리티라고 표현합니다. 예를 들어 사원번호는 고유한 값이니 높은 카디널리티입니다. 남/여 라는 필드로 샤드키를 구성하면 낮은 카디널리티입니다.

     결과적으로 카디널리티가 너무 높거나 낮은 필드는 shard key로는 적절하지 않습니다. 왜냐면 데이터를 적절하게 분산 저장하기에는 데이터 값의 유형이 적절하게 잘 분포되어야 할 필요가 있습니다.

     


    7. replication

     복제는 여러 서버에서 데이터베이스 서버를 분산하고 관리하는 것입니다. "장애는 항상 발생한다"라고 하는 피할 수 없는 사실 때문에 대부분의 데이터베이스 관리 시스템에서 복제는 핵심적 요소입니다. mongoDB에서 복제는 아래와 같은 특징을 가집니다.

    • Master/slave 관계를 갖는 원본과 복사본 사이입니다. 
    • Master에서 쓰기 operation을 수행하고 이러한 operation을 Master의 oplog(명령어 기록)에 기록합니다. slave는 Master의 oplog를 복제하고 각자의 데이터 세트에 오퍼레이션을 비동기 방식으로 동일하게 적용됩니다. 
    • Master는 (read/write)용이고, slave는 master의 데이터를 미러링하고 있는 read 전용입니다. Slave에 write가 가능하도록 설정해 줄 수 있지만 속도면에서 권장하지 않습니다. 

     

    7-1. 복제 동작 원리

    mongoDB에서 복제가 되는 순서는 아래와 같습니다.

    1. 몽고디비 슬레이브는 주기적으로 마스터에게 자신의 optime보다 큰 oplog 요청합니다.
      • oplog에는 primary가 데이터가 아닌 명령어를 기록합니다. 
    2. 5초 안에 마스터에서 쓰기 연산이 발생하면 데이터를 응답합니다. 만약 발생하지 않았다면 데이터가 존재하지 않다는 응답을 보내줍니다.
    3. 슬레이브는 요구한 oplog 데이터가 존재하면 자신의 oplog에 데이터를 저장하고 바로 마스터에게 다시 oplog를 요청합니다.

     

    7-2. 리플리카셋(replicatset)

     마스터 서버와 슬레이브 서버의 관계는 원본 데이터베이스에 대한 복제한 데이터를 하나 더 저장하는 관계를 의미합니다. 장애가 발생하면 복구 작업으로 작업을 수행할 수 있습니다. 그러나 실시간으로 마스터 서버에 복구는 어려우며 슬레이브 서버를 바로 사용하기에도 어렵습니다. 따라서 이런 문제점을 개선한 것이 리플리카셋 입니다.

     

    리플리카셋 특징

    리플라카셋 특징은 아래와 같습니다.

    • primary 서버는 2초 단위로 secondary 서버 상태를 체크하며 동기화를 위한 heartbeat 작업을 수행합니다.
    • 만약 secondary 서버가 중지되더라도 복제 작업만 중지될 뿐 primary 서버에 대한 읽기 작업은 정상적으로 수행합니다.
    • secondary 서버가 복구되면 그동안 밀린 데이터를 복구하기 위해 primary 서버는 계속 oplog를 저장하며, 복구되면 자동으로 동기화해줍니다.
    • 만약 primary 서버가 장애가 생긴다면 secondary 서버를 primary 서버로 만들게 됩니다.

     

    리플리카셋 동작 원리

     client의 요청을 처리하는 하나의 primary server와 primary server의 복제 데이터를 가진 여러 secondary server로 구성됩니다. 이 서버들은 서로 heartbeat로 서로 죽었는지 주기적으로 확인합니다. primary 서버는 heartbeat가 과반수를 가져야 하며, 그렇지 않은 경우 seconday 서버로 전환되고 primary 서버를 뽑기 위해 투표를 시행합니다. primary가 되기 위한 조건은 priority(master가 되는 우선순위)와 votes 등이 있습니다.

    리프리카셋 

     


    8. 마무리

     이번 시간에는 mongoDB에 대한 전체적 내용을 알아보았습니다. 각 주제별 자세한 내용을 다루지는 않았지만 mongoDB에 대한 전체적인 개념을 파악하는데 초점을 두었습니다. 각 주제에 자세한 내용은 다음에 블로그에 포스트하도록 하겠습니다! 😃

    '개발 > MongoDB' 카테고리의 다른 글

    MongoDB index 개념과 indexing 전략  (2) 2020.06.07

    댓글

Designed by Tistory.