Database/MongoDB 실습

[MongoDB] 해시샤딩 만들기와 메타 조회방법

꽁담 2024. 7. 29. 17:38

 

 

 

 

1. MongoDB 해시샤딩

데이터와 서버의 부하를 분산하기 위해 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개의 샤드서버가 구성되어 있는 상태이다.

[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 } ]

 

 

4. 해시샤딩 만들기

4-1. 데이터베이스 샤드 활성화

데이터베이스를 생성 후 샤드를 활성화 해준다.

샤딩 활성화는 enableSharding 명령어를 사용한다.

[direct: mongos] admin> use hashShardDB
switched to db hashShardDB

[direct: mongos] hashShardDB> sh.enableSharding("hashShardDB")
{
  ok: 1,
  '$clusterTime': {
    clusterTime: Timestamp({ t: 1722241448, i: 6 }),
    signature: {
      hash: Binary.createFromBase64('AAAAAAAAAAAAAAAAAAAAAAAAAAA=', 0),
      keyId: Long('0')
    }
  },
  operationTime: Timestamp({ t: 1722241448, i: 2 })
}

 

4-2. 컬렉션에 샤드 키 설정

컬렉션을 사딩하려면 shardCollection 명령어를 사용한다.

 

샤드 키에 hashed 를 입력하면 입력한 키로 샤딩된다.

hashShardDB 의 collection1 의 index 필드를 hashed 기준으로 샤딩하는 의미이다.

[direct: mongos] hashShardDB> sh.shardCollection("hashShardDB.collection1", {index: "hashed"})
{
  collectionsharded: 'hashShardDB.collection1',
  ok: 1,
  '$clusterTime': {
    clusterTime: Timestamp({ t: 1722241591, i: 43 }),
    signature: {
      hash: Binary.createFromBase64('AAAAAAAAAAAAAAAAAAAAAAAAAAA=', 0),
      keyId: Long('0')
    }
  },
  operationTime: Timestamp({ t: 1722241591, i: 43 })
}

 

여기까지 하면 해시샤딩 컬렉션이 생성된다.

 

4-3. 컬렉션에 데이터 적재

컬렉션에 1000 건을 적재한다.

 

[direct: mongos] hashShardDB> for (var n = 1; n <= 1000; n++) { db.collection1.insert({index: n, value: "Test Value"}) }
{
  acknowledged: true,
  insertedIds: { '0': ObjectId('66a7540d91ba31c2101b1d4c') }
}

 

 

4-4. 샤드별로 데이터 조회

# mongosh 127.0.0.1:30001
rs1 [direct: primary] test> use hashShardDB
switched to db hashShardDB
rs1 [direct: primary] hashShardDB> db.getCollection("collection1").find({}).count()
520


# mongosh 127.0.0.1:40001
rs2 [direct: primary] test> use hashShardDB
switched to db hashShardDB
rs2 [direct: primary] hashShardDB> db.getCollection("collection1").find({}).count()
480

 

 

5. 해시샤딩 메타정보 보기

해시샤딩 메타정보는 라우터에서 sh.status 로 확인할 수 있다.

collections 를 보면 index 필드가 hashed 로 샤드키 되어있으며 

chunkMetadata 와 chunks 에서 각 청크별 값의 범위 위치한 샤드서버를 알 수 있다.

[direct: mongos] test> sh.status()
  {
    database: {
      _id: 'hashShardDB',
      primary: 'rs1',
      partitioned: false,
      version: {
        uuid: UUID('352fc813-f311-44f5-be6e-2e86c8e26380'),
        timestamp: Timestamp({ t: 1722241447, i: 1 }),
        lastMod: 1
      }
    },
    collections: {
      'hashShardDB.collection1': {
        shardKey: { index: 'hashed' },
        unique: false,
        balancing: true,
        chunkMetadata: [ { shard: 'rs1', nChunks: 2 }, { shard: 'rs2', nChunks: 2 } ],
        chunks: [
          { min: { index: MinKey() }, max: { index: Long('-4611686018427387902') }, 'on shard': 'rs2', 'last modified': Timestamp({ t: 1, i: 0 }) },
          { min: { index: Long('-4611686018427387902') }, max: { index: Long('0') }, 'on shard': 'rs2', 'last modified': Timestamp({ t: 1, i: 1 }) },
          { min: { index: Long('0') }, max: { index: Long('4611686018427387902') }, 'on shard': 'rs1', 'last modified': Timestamp({ t: 1, i: 2 }) },
          { min: { index: Long('4611686018427387902') }, max: { index: MaxKey() }, 'on shard': 'rs1', 'last modified': Timestamp({ t: 1, i: 3 }) }
        ],
        tags: []
      }
    }
  }