MongoDB 샤딩: 단계별 실용 가이드

샤딩은 대규모 데이터 세트를 분산 환경의 여러 MongoDB 인스턴스에서 더 작은 데이터 세트 청크로 분할하는 프로세스입니다.

샤딩이란?

MongoDB 샤딩은 단일 서버에 저장하는 것이 아니라 여러 서버에 많은 양의 데이터를 저장할 수 있는 확장 가능한 솔루션을 제공합니다.

실제적으로 기하급수적으로 증가하는 데이터를 단일 시스템에 저장하는 것은 실현 가능하지 않습니다. 단일 서버에 저장된 엄청난 양의 데이터를 쿼리하면 리소스 사용률이 높아지고 만족스러운 읽기 및 쓰기 처리량을 제공하지 못할 수 있습니다.

기본적으로 시스템과 함께 증가하는 데이터를 수행하기 위해 존재하는 두 가지 유형의 확장 방법이 있습니다.

수직 확장은 더 강력한 프로세서를 추가하거나 RAM을 업그레이드하거나 시스템에 더 많은 디스크 공간을 추가하여 단일 서버 성능을 향상시킵니다. 그러나 기존 기술 및 하드웨어 구성을 사용하는 실제 사용 사례에서 수직 확장을 적용할 경우 영향이 있을 수 있습니다.

수평적 확장은 더 많은 서버를 추가하고 여러 서버에 부하를 분산하는 것과 함께 작동합니다. 각 시스템은 전체 데이터 세트의 하위 집합을 처리하므로 고급 하드웨어를 배포하는 것보다 더 나은 효율성과 비용 효율적인 솔루션을 제공합니다. 그러나 많은 수의 서버가 있는 복잡한 인프라에 대한 추가 유지 관리가 필요합니다.

Mongo DB sharding은 수평적 확장 기법으로 작동합니다.

샤딩 구성 요소

MongoDB에서 샤딩을 달성하려면 다음 구성 요소가 필요합니다.

Shard는 원본 데이터의 하위 집합을 처리하는 Mongo 인스턴스입니다. 샤드는 복제본 세트에 배포해야 합니다.

Mongos는 Mongo 인스턴스이며 클라이언트 애플리케이션과 샤딩된 클러스터 간의 인터페이스 역할을 합니다. 샤드에 대한 쿼리 라우터로 작동합니다.

Config Server는 클러스터의 메타데이터 정보 및 구성 세부 정보를 저장하는 Mongo 인스턴스입니다. MongoDB를 사용하려면 구성 서버를 복제본 세트로 배포해야 합니다.

샤딩 아키텍처

MongoDB 클러스터는 여러 복제본 세트로 구성됩니다.

각 복제본 세트는 최소 3개 이상의 mongo 인스턴스로 구성됩니다. 샤드 클러스터는 여러 mongo 샤드 인스턴스로 구성될 수 있으며 각 샤드 인스턴스는 샤드 복제본 세트 내에서 작동합니다. 응용 프로그램은 Mongos와 상호 작용하여 샤드와 통신합니다. 따라서 샤딩에서 애플리케이션은 샤드 노드와 직접 상호 작용하지 않습니다. 쿼리 라우터는 샤드 키를 기반으로 샤드 노드 간에 데이터 하위 집합을 배포합니다.

샤딩 구현

샤딩을 위해 아래 단계를 따르십시오

1 단계

  • 복제 세트에서 구성 서버를 시작하고 이들 간의 복제를 활성화합니다.

mongod –configsvr –포트 27019 –replSet rs0 –dbpath C:datadata1 –bind_ip 로컬 호스트

mongod –configsvr –포트 27018 –replSet rs0 –dbpath C:datadata2 –bind_ip 로컬 호스트

mongod –configsvr –포트 27017 –replSet rs0 –dbpath C:datadata3 –bind_ip 로컬 호스트

2 단계

  • 구성 서버 중 하나에서 복제본 세트를 초기화합니다.

rs.initiate( { _id : “rs0”, configsvr: true, 구성원: [   { _id: 0, host: “IP:27017” },   { _id: 1, host: “IP:27018” },   { _id: 2, host: “IP:27019” }    ] })

rs.initiate( { _id : "rs0",  configsvr: true,  members: [   { _id: 0, host: "IP:27017" },   { _id: 1, host: "IP:27018" },   { _id: 2, host: "IP:27019" }    ] })
{
        "ok" : 1,
        "$gleStats" : {
                "lastOpTime" : Timestamp(1593569257, 1),
                "electionId" : ObjectId("000000000000000000000000")
        },
        "lastCommittedOpTime" : Timestamp(0, 0),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1593569257, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        },
        "operationTime" : Timestamp(1593569257, 1)
}

3단계

  • 레플리카 세트에서 샤딩 서버를 시작하고 서버 간 복제를 활성화합니다.
  MS Office에서 차트 범례를 사용자 지정하는 방법

mongod –shardsvr –포트 27020 –replSet rs1 –dbpath C:datadata4 –bind_ip 로컬 호스트

mongod –shardsvr –포트 27021 –replSet rs1 –dbpath C:datadata5 –bind_ip 로컬 호스트

mongod –shardsvr –포트 27022 –replSet rs1 –dbpath C:datadata6 –bind_ip 로컬 호스트

MongoDB는 첫 번째 sharding 서버를 Primary로 초기화하여 기본 sharding 서버 사용을 이동합니다. movePrimary 방법.

4단계

  • 샤딩된 서버 중 하나에서 복제본 세트를 초기화합니다.

rs.initiate( { _id : “rs0”, 구성원: [   { _id: 0, host: “IP:27020” },   { _id: 1, host: “IP:27021” },   { _id: 2, host: “IP:27022” }    ] })

rs.initiate( { _id : "rs0",  members: [   { _id: 0, host: "IP:27020" },   { _id: 1, host: "IP:27021" },   { _id: 2, host: "IP:27022" }    ] })
{
        "ok" : 1,
        "$clusterTime" : {
                "clusterTime" : Timestamp(1593569748, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        },
        "operationTime" : Timestamp(1593569748, 1)
}

5단계

  • 샤딩된 클러스터에 대한 망고 시작

mongos – 포트 40000 –configdb rs0/localhost:27019, 로컬 호스트:27018, 로컬 호스트:27017

6단계

  • 몽고 라우트 서버 연결

몽고 포트 40000

  • 이제 샤딩 서버를 추가합니다.

sh.addShard( “rs1/localhost:27020,localhost:27021,localhost:27022”)

sh.addShard( "rs1/localhost:27020,localhost:27021,localhost:27022")
{
        "shardAdded" : "rs1",
        "ok" : 1,
        "operationTime" : Timestamp(1593570212, 2),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1593570212, 2),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}

7단계

  • mongo 셸에서 DB 및 컬렉션에서 샤딩을 활성화합니다.
  • DB에서 샤딩 활성화

sh.enableSharding(“geekFlareDB”)

sh.enableSharding("geekFlareDB")
{
        "ok" : 1,
        "operationTime" : Timestamp(1591630612, 1),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1591630612, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}

8단계

  • 컬렉션 샤드 키(이 문서 뒷부분에서 설명)를 샤딩하려면 필요합니다.

구문: sh.shardCollection(“dbName.collectionName”, { “키” : 1 } )

sh.shardCollection("geekFlareDB.geekFlareCollection", { "key" : 1 } )
{
        "collectionsharded" : "geekFlareDB.geekFlareCollection",
        "collectionUUID" : UUID("0d024925-e46c-472a-bf1a-13a8967e97c1"),
        "ok" : 1,
        "operationTime" : Timestamp(1593570389, 3),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1593570389, 3),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}

컬렉션이 존재하지 않는 경우 다음과 같이 생성합니다.

db.createCollection("geekFlareCollection")
{
        "ok" : 1,
        "operationTime" : Timestamp(1593570344, 4),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1593570344, 5),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}

9단계

컬렉션에 데이터를 삽입합니다. Mongo 로그가 증가하기 시작하고 밸런서가 작동 중이고 샤드 간에 데이터 균형을 맞추려고 함을 나타냅니다.

10단계

마지막 단계는 샤딩 상태를 확인하는 것입니다. 상태는 Mongos 경로 노드에서 아래 명령을 실행하여 확인할 수 있습니다.

샤딩 상태

mongo 경로 노드에서 아래 명령을 실행하여 샤딩 상태를 확인합니다.

sh.status()

mongos> sh.status()
--- Sharding Status ---
  sharding version: {
        "_id" : 1,
        "minCompatibleVersion" : 5,
        "currentVersion" : 6,
        "clusterId" : ObjectId("5ede66c22c3262378c706d21")
  }
  shards:
        {  "_id" : "rs1",  "host" : "rs1/localhost:27020,localhost:27021,localhost:27022",  "state" : 1 }
  active mongoses:
        "4.2.7" : 1
  autosplit:
        Currently enabled: yes
  balancer:
        Currently enabled:  yes
        Currently running:  no
        Failed balancer rounds in last 5 attempts:  5
        Last reported error:  Could not find host matching read preference { mode: "primary" } for set rs1
        Time of Reported error:  Tue Jun 09 2020 15:25:03 GMT+0530 (India Standard Time)
        Migration Results for the last 24 hours:
                No recent migrations
  databases:
        {  "_id" : "config",  "primary" : "config",  "partitioned" : true }
                config.system.sessions
                        shard key: { "_id" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                rs1     1024
                        too many chunks to print, use verbose if you want to force print
        {  "_id" : "geekFlareDB",  "primary" : "rs1",  "partitioned" : true,  "version" : {  "uuid" : UUID("a770da01-1900-401e-9f34-35ce595a5d54"),  "lastMod" : 1 } }
                geekFlareDB.geekFlareCol
                        shard key: { "key" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                rs1     1
                        { "key" : { "$minKey" : 1 } } -->> { "key" : { "$maxKey" : 1 } } on : rs1 Timestamp(1, 0)
                geekFlareDB.geekFlareCollection
                        shard key: { "product" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                rs1     1
                        { "product" : { "$minKey" : 1 } } -->> { "product" : { "$maxKey" : 1 } } on : rs1 Timestamp(1, 0)
        {  "_id" : "test",  "primary" : "rs1",  "partitioned" : false,  "version" : {  "uuid" : UUID("fbc00f03-b5b5-4d13-9d09-259d7fdb7289"),  "lastMod" : 1 } }

mongos>

데이터 배포

Mongos 라우터는 샤드 키를 기반으로 샤드 간에 부하를 분산하고 데이터를 고르게 분산합니다. 밸런서가 작동합니다.

  최신 애플리케이션 구축을 위한 10가지 AI 플랫폼

샤드 간에 데이터를 배포하는 핵심 구성 요소는 다음과 같습니다.

  • 밸런서는 샤딩된 노드 간에 데이터 하위 집합의 균형을 맞추는 역할을 합니다. 밸런서는 Mongos 서버가 샤드 간에 부하 분산을 시작할 때 실행됩니다. 일단 시작되면 밸런서는 데이터를 더 고르게 분배했습니다. 밸런서의 상태를 확인하려면 sh.status() 또는 sh.getBalancerState() 또는sh.isBalancerRunning()을 실행합니다.
mongos> sh.isBalancerRunning()
true
mongos>

또는

mongos> sh.getBalancerState()
true
mongos>

데이터를 삽입한 후 Mongos 데몬에서 특정 샤드에 대한 일부 청크 등을 이동한다는 일부 활동을 확인할 수 있습니다. 밸런서를 실행하면 성능 문제가 발생할 수 있습니다. 따라서 특정 범위 내에서 밸런서를 실행하는 것이 좋습니다. 밸런서 창.

mongos> sh.status()
--- Sharding Status ---
  sharding version: {
        "_id" : 1,
        "minCompatibleVersion" : 5,
        "currentVersion" : 6,
        "clusterId" : ObjectId("5efbeff98a8bbb2d27231674")
  }
  shards:
        {  "_id" : "rs1",  "host" : "rs1/127.0.0.1:27020,127.0.0.1:27021,127.0.0.1:27022",  "state" : 1 }
        {  "_id" : "rs2",  "host" : "rs2/127.0.0.1:27023,127.0.0.1:27024,127.0.0.1:27025",  "state" : 1 }
  active mongoses:
        "4.2.7" : 1
  autosplit:
        Currently enabled: yes
  balancer:
        Currently enabled:  yes
        Currently running:  yes
        Failed balancer rounds in last 5 attempts:  5
        Last reported error:  Could not find host matching read preference { mode: "primary" } for set rs2
        Time of Reported error:  Wed Jul 01 2020 14:39:59 GMT+0530 (India Standard Time)
        Migration Results for the last 24 hours:
                1024 : Success
  databases:
        {  "_id" : "config",  "primary" : "config",  "partitioned" : true }
                config.system.sessions
                        shard key: { "_id" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                rs2     1024
                        too many chunks to print, use verbose if you want to force print
        {  "_id" : "geekFlareDB",  "primary" : "rs2",  "partitioned" : true,  "version" : {  "uuid" : UUID("a8b8dc5c-85b0-4481-bda1-00e53f6f35cd"),  "lastMod" : 1 } }
                geekFlareDB.geekFlareCollection
                        shard key: { "key" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                rs2     1
                        { "key" : { "$minKey" : 1 } } -->> { "key" : { "$maxKey" : 1 } } on : rs2 Timestamp(1, 0)
        {  "_id" : "test",  "primary" : "rs2",  "partitioned" : false,  "version" : {  "uuid" : UUID("a28d7504-1596-460e-9e09-0bdc6450028f"),  "lastMod" : 1 } }

mongos>
  • 샤드 키는 샤드 컬렉션의 문서를 샤드 간에 배포하는 논리를 결정합니다. 샤드 키는 삽입할 컬렉션의 모든 문서에 있어야 하는 인덱스 필드 또는 인덱스 복합 필드일 수 있습니다. 데이터는 청크로 분할되고 각 청크는 범위 기반 샤드 키와 연결됩니다. 범위 쿼리 라우터는 청크를 저장할 샤드를 결정합니다.

5가지 속성을 고려하여 Shard Key를 선택할 수 있습니다.

  • 카디널리티
  • 쓰기 배포
  • 배포판 읽기
  • 타겟팅 읽기
  • 지역 읽기

이상적인 샤드 키는 MongoDB가 모든 샤드에 부하를 고르게 분산하도록 합니다. 좋은 샤드 키를 선택하는 것은 매우 중요합니다.

이미지: 몽고DB

샤드 노드 제거

클러스터에서 샤드를 제거하기 전에 사용자는 데이터를 나머지 샤드로 안전하게 마이그레이션해야 합니다. MongoDB는 필요한 샤드 노드를 제거하기 전에 데이터를 다른 샤드 노드로 안전하게 드레이닝합니다.

아래 명령을 실행하여 필요한 샤드를 제거하십시오.

1 단계

먼저 제거할 샤드의 호스트 이름을 결정해야 합니다. 아래 명령은 샤드의 상태와 함께 클러스터에 있는 모든 샤드를 나열합니다.

db.adminCommand( { listShards: 1 } )

mongos> db.adminCommand( { listShards: 1 } )
{
        "shards" : [
                {
                        "_id" : "rs1",
                        "host" : "rs1/127.0.0.1:27020,127.0.0.1:27021,127.0.0.1:27022",
                        "state" : 1
                },
                {
                        "_id" : "rs2",
                        "host" : "rs2/127.0.0.1:27023,127.0.0.1:27024,127.0.0.1:27025",
                        "state" : 1
                }
        ],
        "ok" : 1,
        "operationTime" : Timestamp(1593572866, 15),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1593572866, 15),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}

2 단계

아래 명령을 실행하여 클러스터에서 필요한 샤드를 제거하십시오. 일단 발행되면, 밸런서는 드레이닝 샤드 노드에서 청크 제거를 처리한 다음 나머지 샤드 노드 간에 나머지 청크 분포의 균형을 맞춥니다.

db.adminCommand( { removeShard: “shardedReplicaNodes” } )

mongos> db.adminCommand( { removeShard: "rs1/127.0.0.1:27020,127.0.0.1:27021,127.0.0.1:27022" } )
{
        "msg" : "draining started successfully",
        "state" : "started",
        "shard" : "rs1",
        "note" : "you need to drop or movePrimary these databases",
        "dbsToMove" : [ ],
        "ok" : 1,
        "operationTime" : Timestamp(1593572385, 2),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1593572385, 2),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}

3단계

드레이닝 샤드의 상태를 확인하려면 동일한 명령을 다시 실행하십시오.

db.adminCommand( { removeShard: "rs1/127.0.0.1:27020,127.0.0.1:27021,127.0.0.1:27022" } )

데이터 드레이닝이 완료될 때까지 기다려야 합니다. msg 및 state 필드는 다음과 같이 데이터 드레이닝이 완료되었는지 여부를 표시합니다.

"msg" : "draining ongoing",
"state" : "ongoing",

sh.status() 명령으로 상태를 확인할 수도 있습니다. 제거된 샤딩된 노드는 출력에 반영되지 않습니다. 하지만 드레이닝이 계속 진행된다면 샤딩된 노드는 드레이닝 상태가 true가 됩니다.

4단계

필요한 샤드가 완전히 제거될 때까지 위의 동일한 명령으로 드레이닝 상태를 계속 확인합니다.
완료되면 명령의 출력에 메시지와 완료 상태가 반영됩니다.

"msg" : "removeshard completed successfully",
"state" : "completed",
"shard" : "rs1",
"ok" : 1,

5단계

마지막으로 클러스터에 남아 있는 샤드를 확인해야 합니다. 상태를 확인하려면 sh.status() 또는 db.adminCommand( { listShards: 1 } )를 입력하세요.

mongos> db.adminCommand( { listShards: 1 } )
{
        "shards" : [
                {
                        "_id" : "rs2",
                        "host" : "rs2/127.0.0.1:27023,127.0.0.1:27024,127.0.0.1:27025",
                        "state" : 1
                }
        ],
        "ok" : 1,
        "operationTime" : Timestamp(1593575215, 3),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1593575215, 3),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}

여기에서 제거된 샤드가 샤드 목록에 더 이상 존재하지 않는 것을 볼 수 있습니다.

복제보다 샤딩의 이점

  • 복제에서 기본 노드는 모든 쓰기 작업을 처리하는 반면 보조 서버는 백업 복사본을 유지 관리하거나 읽기 전용 작업을 제공하는 데 필요합니다. 그러나 레플리카 세트와 함께 샤딩을 하면 부하가 여러 서버에 분산됩니다.
  • 단일 레플리카 세트는 12개의 노드로 제한되지만 샤드 수에는 제한이 없습니다.
  • 복제에는 대규모 데이터 세트를 처리하기 위해 고급 하드웨어 또는 버티클 스케일링이 필요하며, 이는 샤딩에 서버를 추가하는 것보다 비용이 너무 많이 듭니다.
  • 복제에서는 더 많은 슬레이브/보조 서버를 추가하여 읽기 성능을 향상시킬 수 있지만 샤딩에서는 더 많은 샤드 노드를 추가하여 읽기 및 쓰기 성능이 모두 향상됩니다.

샤딩 제한

  • 샤드 클러스터는 고유 인덱스가 전체 샤드 키 접두사로 붙을 때까지 샤드에서 고유 인덱싱을 지원하지 않습니다.
  • 하나 이상의 문서에서 분할된 컬렉션에 대한 모든 업데이트 작업은 쿼리에 분할된 키 또는 _id 필드를 포함해야 합니다.
  • 컬렉션의 크기가 지정된 임계값을 초과하지 않으면 컬렉션을 샤딩할 수 있습니다. 이 임계값은 모든 샤드 키의 평균 크기와 구성된 청크 크기를 기반으로 추정할 수 있습니다.
  • 샤딩은 최대 컬렉션 크기 또는 분할 수에 대한 운영 제한으로 구성됩니다.
  • 성능에 영향을 줄 수 있는 잘못된 샤드 키를 선택합니다.

결론

MongoDB는 성능 저하 없이 대규모 데이터베이스를 구현하기 위해 내장 샤딩을 제공합니다. 위의 내용이 MongoDB 샤딩을 설정하는 데 도움이 되었기를 바랍니다. 다음으로 일반적으로 사용되는 일부 MongoDB 명령에 익숙해질 수 있습니다.