샤딩의 설정은 다음과 같이 크게 두 가지 과정으로 나눌 수 있습니다:
서버 시작하기, 데이터에 샤딩 방식 결정
샤딩은 기본적으로 다음과 같이 세 가지 요소를 포함합니다:
-
샤드
샤드는 컬렉션의 데이터를 부분적으로 담는 그릇입니다. 샤드는 하나의 mongod 서버(개발 및 테스트용)이거나 리플리카 세트(실제 서비스용)입니다.
-
mongos
(Query Router)mongos
는 라우터 프로세스이며 MongoDB 분산을 동반합니다. 기본적으로 요청을 라우팅하거나 응답을 모읍니다.mongos
는 어떠한 데이터도 저장하지 않으며 환경설정에 대한 정보도 저장하지 않습니다. -
Config Server (환경설정 서버)
환경설정 서버는 클러스터의 환경설정을 저장합니다. 즉 어느 데이터가 어느 샤드에 있는지를 저장합니다.
이제 본격적으로 샤딩을 위한 서버와 클러스터를 구성해 보도록 하겠습니다. 우선은 테스트 및 샤드 구성을 위한 단계이므로 1대의 머쉰에서 로컬호스트로 구성하는 방법에 대해 알아보도록 하겠습니다.
테스트가 아닌 프로덕션 레벨에서는 최소 머쉰 2대 상에서 샤드 환경을 구성하는 방법에 대해 알아 보겠습니다.
샤딩을 위한 서버 구성은 크게 1. Config Server, 2. Routing Server, 3. Cluster(Shards)로 분류할 수 있으며, 이에 대한 구성도는 다음 그림과 같습니다:
각 서버에 대한 인스턴스와 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.]과 같이 각 서버에 대한 dbpath
(데이터를 저장할 폴더)를 만듭니다.
-
Config Server 실행하기
Config Server는 샤딩을 위한 환경설정에 관련된 서버입니다. 샤딩을 할 때 가장 먼저해야 할 일이 Config Server를 실행하는 것이며, 샤딩에 대한 정보를 저장하지만 큰 용량은 아니므로 큰 저장공간이 필요한 것은 아닙니다. 대략 200MB의 실제 데이터 당 1KB 정도의 저장공간을 확보하면 됩니다.
Config Server의 인스턴스 실행은 여느
mongod
실행과 다르지 않습다. 단,--configsvr
옵션이 필요합니다 (하지만 생략해도 큰 문제는 없습니다). Config Server 인스턴스 실행에 대한 프로토타입은 다음과 같습니다:$ mongod --configsvr --dbpath <path> --port <port>
[표 1.]과 같이
dbpath
와port
를 설정합니다:$ mongod --configsvr --dbpath /[YOUR_DB_PATH]/config --port 10000
-
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와 연결됩니다.만약 다중의 Config Server를 연결하는
mongos
인스턴스를 실행하는 예는 다음과 같습니다:$ mongos --configdb <hostname1:port1>, <hostname2:port2>, <hostname3:port3>
현재는 Config Server가 1개만 설정되어 있으므로 이 부분은 일단 참고만하고 넘어가겠습니다. 다중의 Config Server 설정에 대한 내용은 다음 글에서 다루도록 하겠습니다.
-
Shard 1 서버 인스턴스 실행하기
mongod 인스턴스를 통해
port
번호 30000으로 shard 1 에 대한 서버 인스턴스를 실행합니다:$ mongod --dbpath /[YOUR_DB_PATH]/shard1 --port 30000
-
Shard 2 서버 인스턴스 실행하기
shard 1과 마찬가지로 port 번호와 dbpath만 다르게 서버 인스턴스를 실행합다:
$ mongod --dbpath /[YOUR_DB_PATH]/shard2 --port 40000
-
클러스터에 Shard 1 추가하기
이제 실행 중인
mongos
프로세스에 연결하고 클러스터에 샤드를 추가한다. 이에 대한 프로토타입은 다음과 같습니다:$ mongo --host <hostname or machine running mongos> --port <port mongos listens on>
본 예제에서는
mongos
인스턴스에 대한port
번호는 20000이므로 다음과 같이 입력합니다:$ mongo --host localhost --port 20000
연결 시, 초기
db
는admin
인데, 샤드 추가는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.]과 같습니다. -
클러스터에 Shard 2 추가하기
Shard 1을 추가한 방법과 유사합니다. Shard 2에 대한
port
번호는 40000이므로 Shard 2을 추가하는 명령은 다음과 같습니다:mongos> db.runCommand({addshard : "localhost:40000", allowLocal : true}) { "shardAdded" : "shard0001", "ok" : 1 }
지금까지의 구성도를 그림으로 표현하면 [그림 4.]와 같습니다.
이로써 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 }