Sharding 활성화하기

대용량 데이터를 다루기 위해서는 확장이 가능한 Sharded Cluster를 사용해야 한다.

<aside> ✔️ Sharded Cluster 복습

// nodb : db에 붙지 않겠다.
// norc : 들어갈 때 실행되는 스크립트를 실행하지 않겠다.
./mongo --nodb --norc

MongoRunner.dataPath = "/Users/seowon.jung/fastcampus/mongodb"

st = ShardingTest({
    name: "test-shard",
    chunkSize: 1,
    shards: 3,
    rs: {
        nodes: 3,
        oplogSize: 10
    },
    other: {
        enableBalancer: true
    }
})

// Shard의 상태 확인
sh.status()
// shard 3개가 구성되어 있는 것 + autosplit 활성화 + balancer 활성화 등 확인 가능

// 데이터 생성 후 상태 재확인
sh.status()
// 데이터베이스가 생성되고, primary가 3개의 shard 중 test-shard-rs0인 것 
// + partitioned false인 것 확인 가능
// -> sharded cluster의 주요 기능인 분산처리 및 scaling이 되지 않음

// sharding 활성화
sh.enableSharding('test')    // test : database명

// 상태 다시 확인
sh.status()
// partitioned true인 것 확인 가능
// 하지만 아직 분산이 되는 것은 아님 (index, shardKey가 없으므로)

// Index 생성 및 shardKey로 사용
db.testing.createIndex({index: 1})
sh.shardCollection("test.testing", {index: 1})

// 상태 다시 확인
sh.status()
// collection에 정보 들어감
// 아직은 migration이 완료되지 않음 -> nChunks: 5가 모두 primary shard에 포함되어 있음

// 잠시 후 상태 다시 확인
sh.status()
// 균등하게 분배가 됨
// 3개의 shard에 각각 2개, 1개, 2개로 분산되어 있음

Untitled

분산 작업 완료 전

Untitled

분산 작업 완료 후

ShardKey를 잘 설정하는 것이 중요한데, 잘못 지정한 경우 수정할 수 있다. (버전 5.0 이후부터 가능)

// Index 생성
db.testing.createIndex({text: "hashed"})

// reshard
sh.reshardCollection("test.testing", {text: "hashed"})

// 상태 재확인
sh.status()

Untitled

hash sharding의 경우 chunk를 본다고 하더라도 그 값 자체가 어떻게 나누어져 있는지는 명확히 확인할 수 없다.

불편하고 관리하기에 복잡해진다.

가능하면 Replica Set을 사용하는 것이 좋고, Sharded cluster는 확장이 꼭 필요한 경우에만 사용하자.


MongoDB는 대용량 데이터를 처리하는 데이터베이스일까

대용량 데이터의 기준 : 1PB (보통 내가 다루어보지 못한 데이터의 단위로 잡는 경우가 많음)

그렇다면 MongoDB가 데이터를 어느정도까지 감당할 수 있을까?

Untitled

하나의 Shard가 4TB라고 가정해보면,

1PB(= 1024TB) / 4TB = 256

즉, 256개의 Shard가 필요

실제 서비스 시에는 여유공간이 필요하므로, 대략 300개의 Shard가 필요하다고 볼 수 있다.

1시간에 35 * 300 = 10,500불, 하루에는 252,000불, 1년에 약 9천 200만불 (약 1200억) 정도의 비용이 발생