05-03 07:38
Notice
Recent Posts
Recent Comments
관리 메뉴

Scientific Computing & Data Science

[MongoDB] Sharding / Setting Up Sharding 본문

Data Science/MongoDB

[MongoDB] Sharding / Setting Up Sharding

cinema4dr12 2014. 4. 22. 00:21

by Geol Choi | 

샤딩의 설정은 다음과 같이 크게 두 가지 과정으로 나눌 수 있다:

1. 서버 시작하기, 2. 데이터에 샤딩 방식 결정


샤딩은 기본적으로 다음과 같이 세 가지 요소를 포함한다:

1. 샤드

샤드는 컬렉션의 데이터를 부분적으로 담는 그릇이다. 샤드는 하나의 mongod 서버(개발 및 테스트용)이거나 리플리카 세트(실제 서비스용)이다.

2. mongos(Query Router)

mongos는 라우터 프로세스이며 MongoDB 분산을 동반한다. 기본적으로 요청을 라우팅하거나 응답을 모은다. mongos는 어떠한 데이터도 저장하지 않으며 환경설정에 대한 정보도 저장하지 않는다.

3. Config Server(환경설정 서버)

환경설정 서버는 클러스터의 환경설정을 저장한다. 즉 어느 데이터가 어느 샤드에 있는지를 저장한다.


이제 본격적으로 샤딩을 위한 서버와 클러스터를 구성해 보도록 하자. 우선은 테스트 및 샤드 구성을 위한 단계이므로 1대의 머쉰에서 로컬호스트로 구성하는 방법에 대해 알아보도록 하겠다.

테스트가 아닌 프로덕션 레벨에서는 최소 머쉰 2대 상에서 샤드 환경을 구성하는 방법에 대해 알아 보겠다.

샤딩을 위한 서버 구성은 크게 1. Config Server, 2. Routing Server, 3. Cluster(Shards)로 분류할 수 있으며, 이에 대한 구성도는 다음 그림과 같다:

    [그림 1.] 샤딩을 위한 서버 및 클러스터 구성도.


각 서버에 대한 인스턴스와 DB경로, 포트번호 등은 다음 표와 같이 정리하였다:


[표 1.] 각 서버 실행 정보

 

 instance

 dbpath

 port

 configdb

 Config Server

 mongod

 config

 10000

-

 Routing  Server

 mongos

-

 20000

 localhost:1000

 Shard 1

 mongod

 shard1

 30000

-

 Shard 2 mongod shard2

 40000

-


일단 [표 1.]은 향후 참고용이니 지금 단계에서는 훑어보고 지나가도록 한다. 단, Routing Server의 인스턴스가 mongos로 실행됨에 주목할 필요가 있다. 이 부분은 "1. 서버 시작하기"에서 자세히 다루도록 하겠다.


서버 시작하기

각 서버의 인스턴스 실행에 앞서 [표 1.]과 같이 각 서버에 대한 dbpath(데이터를 저장할 폴더)를 만든다.

1. Config Server 실행하기

Config Server는 샤딩을 위한 환경설정에 관련된 서버이다. 샤딩을 할 때 가장 먼저해야 할 일이 Config Server를 실행하는 것이며, 샤딩에 대한 정보를 저장하지만 큰 용량은 아니므로 큰 저장공간이 필요한 것은 아니다. 대략 200MB의 실제 데이터 당 1KB 정도의 저장공간을 확보하면 된다.

Config Server의 인스턴스 실행은 여느 mongod 실행과 다르지 않다. 단, --configsvr 옵션이 필요하다(하지만 생략해도 큰 문제는 없다). Config Server 인스턴스 실행에 대한 프로토타입은 다음과 같다:

$ mongod --configsvr --dbpath <path> --port <port>

 

[표 1.]과 같이 dbpathport를 설정한다:

$ mongod --configsvr --dbpath /[YOUR_DB_PATH]/config --port 10000

2. Routing Server 실행하기

Routing Server는 클라이언트 어플리케이션에 대한 인터페이스 역할을 하는 서버이다. mongos 인스턴스에 의해 실행되며 configdb 옵션을 갖는다. 프로토타입은 다음과 같다:

$ mongos --configdb <config server hostnames>


예를 들어, port 번호 20000에 localhost:10000의 Config Server에 연결하는 mongos 인스턴스 실행은 다음과 같다:

$ mongos --port 20000 --configdb localhost:10000


port는 [표 1.]과 같으며 --configdb 옵션을 통해 port 번호 10000인 Config Server와 연결된다.


    [그림 2.] mongos 인스턴스 실행을 통한 routing server와 config server 연결.


만약 다중의 Config Server를 연결하는 mongos 인스턴스를 실행하는 예는 다음과 같다:

$ mongos --configdb <hostname1:port1>, <hostname2:port2>, <hostname3:port3>

현재는 Config Server가 1개만 설정되어 있으므로 이 부분은 일단 참고만하고 넘어간다. 다중의 Config Server 설정에 대한 내용은 다음 글에서 다루도록 하겠다.

3. Shard 1 서버 인스턴스 실행하기

mongod 인스턴스를 통해 port 번호 30000으로 shard 1 에 대한 서버 인스턴스를 실행한다:

$ mongod --dbpath /[YOUR_DB_PATH]/shard1 --port 30000

4. Shard 2 서버 인스턴스 실행하기

shard 1과 마찬가지로 port 번호와 dbpath만 다르게 서버 인스턴스를 실행한다:

$ mongod --dbpath /[YOUR_DB_PATH]/shard2 --port 40000

5. 클러스터에 Shard 1 추가하기

이제 실행 중인 mongos 프로세스에 연결하고 클러스터에 샤드를 추가한다. 이에 대한 프로토타입은 다음과 같다:

$ mongo --host <hostname or machine running mongos> --port <port mongos listens on>


본 예제에서는 mongos 인스턴스에 대한 port 번호는 20000이므로 다음과 같이 입력한다:

$ mongo --host localhost --port 20000


연결 시, 초기 dbadmin인데, 샤드 추가는 db를 admin으로 사용 중일 때에만 가능하기 때문이다. mongos에 연결되면 다음과 같이 프롬프트가 표시될 것이다:

Last login: Wed Apr 23 20:55:07 on ttys003
gchoiui-MacBook-Pro:~ gchoi$ mongo localhost:20000/admin
MongoDB shell version: 2.6.0
connecting to: localhost:20000/admin


샤드 추가는 runCommand 명령으로 실행되며 프로토타입은 다음과 같다:

{ addShard: "<hostname><:port>", maxSize: <size>, name: "<shard_name>" }


앞서 실행한 Shard 1에 대한 port 번호는 30000이므로 Shard 1을 추가하는 명령은 다음과 같다:

mongos> db.runCommand({addshard : "localhost:30000", allowLocal : true})
{ "shardAdded" : "shard0000", "ok" : 1 }

성공적으로 샤드가 추가되면 메시지에 "ok"가 1로 표시된다. allowLocal 키는 localhost에서 샤드가 실행 시 필요한 옵션이다. 지금까지의 구성도를 그림으로 표현하면 [그림 3.]과 같다.


    [그림 3.] shard 1 추가.

6. 클러스터에 Shard 2 추가하기

Shard 1을 추가한 방법과 유사하다. Shard 2에 대한 port 번호는 40000이므로 Shard 2을 추가하는 명령은 다음과 같다:

mongos> db.runCommand({addshard : "localhost:40000", allowLocal : true})
{ "shardAdded" : "shard0001", "ok" : 1 }


지금까지의 구성도를 그림으로 표현하면 [그림 4.]와 같다.

    [그림 4.] shard 2 추가.


이로써 Shard 1과 Shard 2를 포함하는 클러스터가 구성되었다. 이제 데이터를 샤딩하는 방법에 대해 알아보도록 하겠다.


데이터 샤드

우선 샤딩할 데이터를 준비하도록 하자. db 이름은 "jobs"이고 컬렉션은 "tasks"이다. 우선 db를 "job"로 이동한다:

mongos> use jobs
switched to db jobs


현재 db에 다음과 같이 데이터를 입력한다:

mongos> db.tasks.insert({todo : "shopping", status : "READY", priority : "4"})
mongos> db.tasks.insert({todo : "studying Mongo DB", status : "READY", priority : "1"})
mongos> db.tasks.insert({todo : "reporting the current job", status : "DONE", priority : "8"})
mongos> db.tasks.insert({todo : "cleaning my room", status : "READY", priority : "3"})
mongos> db.tasks.insert({todo : "meeting friends", status : "DONE", priority : "7"})
mongos> db.tasks.insert({todo : "depositing money", status : "RUNNING", priority : "6"})
mongos> db.tasks.insert({todo : "take a walk", status : "RUNNING", priority : "5"})
mongos> db.tasks.insert({todo : "sending an email", status : "READY", priority : "2"})


데이터가 잘 입력되었는지 확인한다:

mongos> db.tasks.find().pretty()
{
        "_id" : ObjectId("5357c35f2a6efd9e3fa1b97a"),
        "todo" : "shopping",
        "status" : "READY",
        "priority" : "4"
}
{
        "_id" : ObjectId("5357c35f2a6efd9e3fa1b97b"),
        "todo" : "studying Mongo DB",
        "status" : "READY",
        "priority" : "1"
}
{
        "_id" : ObjectId("5357c35f2a6efd9e3fa1b97c"),
        "todo" : "reporting the current job",
        "status" : "DONE",
        "priority" : "8"
}
{
        "_id" : ObjectId("5357c35f2a6efd9e3fa1b97d"),
        "todo" : "cleaning my room",
        "status" : "READY",
        "priority" : "3"
}
{
        "_id" : ObjectId("5357c35f2a6efd9e3fa1b97e"),
        "todo" : "meeting friends",
        "status" : "DONE",
        "priority" : "7"
}
{
        "_id" : ObjectId("5357c35f2a6efd9e3fa1b97f"),
        "todo" : "depositing money",
        "status" : "RUNNING",
        "priority" : "6"
}
{
        "_id" : ObjectId("5357c35f2a6efd9e3fa1b980"),
        "todo" : "take a walk",
        "status" : "RUNNING",
        "priority" : "5"
}
{
        "_id" : ObjectId("5357c3602a6efd9e3fa1b981"),
        "todo" : "sending an email",
        "status" : "READY",
        "priority" : "2"
}


데이터가 잘 입력된 것을 확인이 완료되면, 다시 db를 "admin"으로 이동한다:

mongos> use admin
switched to db admin

"admin"으로 이동하는 이유는 "admin"에서만 데이터 샤딩을 설정할 수 있기 때문이다.


이제 "jobs" db의 "tasks" 컬렉션의 데이터를 샤딩할 것이다. 샤드 키는 "_id"를 사용한다. 우선 enablesharding 명령을 통해 db 레벨에서 샤드를 활성화한다:

mongos> db.runCommand({"enablesharding" : "jobs"})
{ "ok" : 1 }


db 레벨에서 샤드 활성화가 완료되면, shardcollection 명령을 통해 컬렉션 레벨에서 컬렉션을 샤딩한다:

mongos> db.runCommand({"shardcollection" : "jobs.tasks", "key" : {"_id" : 1}})
{ "collectionsharded" : "jobs.tasks", "ok" : 1 }


Comments