Database/MongoDB 실습

[MongoDB] 레인지샤딩 범위나누는 방법

꽁담 2024. 7. 31. 10:11

1. MongoDB 레인지샤딩

사용자가 샤드별로 가지는 데이터 범위를 할당하여 샤드별로 데이터를 분산할 수 있는 방법이다.

 

2. MongoDB 테스트 버전

유형 버전 구성
mongosh 2.2.10  
mongodb 7.0.12 Config : 1개, 포트 20000
Route : 1개, 포트 20001
Shard1 : 1개, 포트 30001
Shard2 : 1개, 포트 40001

 

3. 전제조건

mongodb 는 2개의 샤드서버가 구성되어 있는 상태이다.

또 rangeShardDB 데이터베이스는 레인지샤딩으로 구성되어 있다.

[direct: mongos] test> sh.status();
shardingVersion
{ _id: 1, clusterId: ObjectId('66838519ea100ebaf5ee3cc8') }
---
shards
[
  {
    _id: 'rs1',
    host: 'rs1/127.0.0.1:30001',
    state: 1,
    topologyTime: Timestamp({ t: 1719896113, i: 1 })
  },
  {
    _id: 'rs2',
    host: 'rs2/127.0.0.1:40001',
    state: 1,
    topologyTime: Timestamp({ t: 1719896932, i: 2 })
  }
]
---
active mongoses
[ { '7.0.12': 1 } ]
[direct: mongos] test> sh.status()
  {
    database: {
      _id: 'rangeShardDB',
      primary: 'rs1',
      partitioned: false,
      version: {
        uuid: UUID('d6db39d1-0b81-40a7-a539-327cf5158922'),
        timestamp: Timestamp({ t: 1722242803, i: 1 }),
        lastMod: 1
      }
    },
    collections: {
      'rangeShardDB.collection1': {
        shardKey: { index: 1 },
        unique: false,
        balancing: true,
        chunkMetadata: [ { shard: 'rs1', nChunks: 1 } ],
        chunks: [
          { min: { index: MinKey() }, max: { index: MaxKey() }, 'on shard': 'rs1', 'last modified': Timestamp({ t: 1, i: 0 }) }
        ],
        tags: []
      }
    }
  }

 

4. 레인지샤딩 범위할당

범위는 splitAt 이라는 명령어를 사용하여 분할이 가능하다.

# splitAt 은 '데이터베이스명.컬렉션명, 분할키 : 범위' 작성
[direct: mongos] rangeShardDB> sh.splitAt("rangeShardDB.collection1", { "index": 1000 } )
{
  ok: 1,
  '$clusterTime': {
    clusterTime: Timestamp({ t: 1722388045, i: 5 }),
    signature: {
      hash: Binary.createFromBase64('AAAAAAAAAAAAAAAAAAAAAAAAAAA=', 0),
      keyId: Long('0')
    }
  },
  operationTime: Timestamp({ t: 1722388045, i: 5 })
}

[direct: mongos] rangeShardDB> sh.splitAt("rangeShardDB.collection1", { "index": 2000 } )
{
  ok: 1,
  '$clusterTime': {
    clusterTime: Timestamp({ t: 1722388049, i: 10 }),
    signature: {
      hash: Binary.createFromBase64('AAAAAAAAAAAAAAAAAAAAAAAAAAA=', 0),
      keyId: Long('0')
    }
  },
  operationTime: Timestamp({ t: 1722388049, i: 10 })
}

 

메타정보를 확인하면 범위가 분할된 것을 확인할 수 있다.

[direct: mongos] rangeShardDB> sh.status()
  {
    database: {
      _id: 'rangeShardDB',
      primary: 'rs1',
      partitioned: false,
      version: {
        uuid: UUID('d6db39d1-0b81-40a7-a539-327cf5158922'),
        timestamp: Timestamp({ t: 1722242803, i: 1 }),
        lastMod: 1
      }
    },
    collections: {
      'rangeShardDB.collection1': {
        shardKey: { index: 1 },
        unique: false,
        balancing: true,
        chunkMetadata: [ { shard: 'rs1', nChunks: 3 } ],
        chunks: [
          { min: { index: MinKey() }, max: { index: 1000 }, 'on shard': 'rs1', 'last modified': Timestamp({ t: 1, i: 1 }) },
          { min: { index: 1000 }, max: { index: 2000 }, 'on shard': 'rs1', 'last modified': Timestamp({ t: 1, i: 3 }) },
          { min: { index: 2000 }, max: { index: MaxKey() }, 'on shard': 'rs1', 'last modified': Timestamp({ t: 1, i: 4 }) }
        ],
        tags: []
      }
    }
  }

 

또 꼭 같은 데이터유형 (숫자면 숫자) 로 지정할 필요는 없다.

숫자로 분할된 레인지샤딩에서 문자로도 추가할 수 있다.

[direct: mongos] rangeShardDB> sh.splitAt("rangeShardDB.collection1", { "index": "가" } )
{
  ok: 1,
  '$clusterTime': {
    clusterTime: Timestamp({ t: 1722388105, i: 6 }),
    signature: {
      hash: Binary.createFromBase64('AAAAAAAAAAAAAAAAAAAAAAAAAAA=', 0),
      keyId: Long('0')
    }
  },
  operationTime: Timestamp({ t: 1722388105, i: 5 })
}

[direct: mongos] rangeShardDB> sh.status()
  {
    database: {
      _id: 'rangeShardDB',
      primary: 'rs1',
      partitioned: false,
      version: {
        uuid: UUID('d6db39d1-0b81-40a7-a539-327cf5158922'),
        timestamp: Timestamp({ t: 1722242803, i: 1 }),
        lastMod: 1
      }
    },
    collections: {
      'rangeShardDB.collection1': {
        shardKey: { index: 1 },
        unique: false,
        balancing: true,
        chunkMetadata: [ { shard: 'rs1', nChunks: 4 } ],
        chunks: [
          { min: { index: MinKey() }, max: { index: 1000 }, 'on shard': 'rs1', 'last modified': Timestamp({ t: 1, i: 1 }) },
          { min: { index: 1000 }, max: { index: 2000 }, 'on shard': 'rs1', 'last modified': Timestamp({ t: 1, i: 3 }) },
          { min: { index: 2000 }, max: { index: '가' }, 'on shard': 'rs1', 'last modified': Timestamp({ t: 1, i: 5 }) },
          { min: { index: '가' }, max: { index: MaxKey() }, 'on shard': 'rs1', 'last modified': Timestamp({ t: 1, i: 6 }) }
        ],
        tags: []
      }
    }
  }