Notice
Recent Posts
Recent Comments
Dharma
[MongoDB] 몽고디비 실전 적용 복제 셋 (Replication set) 과 샤드 ( Shard )를 동시에 적용하는 방법 본문
샤딩 (Sharding) 을 하는 방법 또는 복제 셋 (Replication) 을 하는 방법에 관한 예제는 잘 나와 있습니다. 그런데 실전에서는 복제와 샤딩을 동시에 하는 것이 일반적일 것입니다. 이것에 관한 예제가 많이 없더군요. 어쩌다 찾은 것이 한개 있지만 한 기계에서 가상으로 돌려보는 예제 입니다. 이러한 예제로는 샤딩을 제대로 테스트 할 수가 없더군요. 하지만 그 문서를 바탕으로 실제로 샤딩과 복제를 클러스터 환경에서 테스트 해 봤습니다.
http://cookbook.mongodb.org/operations/convert-replica-set-to-replicated-shard-cluster/
http://cookbook.mongodb.org/operations/convert-replica-set-to-replicated-shard-cluster/
위 내용은 한 기계안에서 샤딩과 복제 셋을 테스트 하는 예제 입니다.
원칙대로라면 복제 셋 (Replication Set) 을 설정할 때 한 머신에서 동작시키는 것이 아니라 서로 다른 서버에서 구동되게 설계를 해야 하지만 그것 까지 세팅하기가 매우 귀찮기 때문에 다음 과 같이 설계를 해 봤습니다.
Machine 1 :
- name : super1
- replication : first * 3
Machine 2 :
- name : super2
- replication : second * 3
즉 2대의 머신에서 샤딩이 이루어 지게 세팅을 하는 것인데, 각각의 머신은 3개의 복제 셋을 가지게 구성 되는 것입니다.
mongoDB 의 bin 이 path 에 걸려 있다는 가정 하에 진행 합니다.
super1 부터 설정을 시작합니다.
먼저 데이터들이 저장될 db 디렉토리를 만들어 줍니다.
$ mkdir ~/db/first1
$ mkdir ~/db/first2
$ mkdir ~/db/first3
로그를 저장할 공간도 만들어 줍니다.
$ mkdir ~/db/log
이제 몽고 데몬들을 띄워줍니다.
$ mongod --dbpath ~/db/first1 --port 10001 --replSet first > ~/db/log/first1.log &
$ mongod --dbpath ~/db/first2 --port 10002 --replSet first > ~/db/log/first2.log &
$ mongod --dbpath ~/db/first3 --port 10003 --replSet first > ~/db/log/first3.log &
이제 이 세개의 몽고 디비 프로세스들을 한개의 복제셋 (여기서는 first )으로 묶어주는 작업을 합니다.
$ mongo localhost:10001/admin
> db.runCommand({"replSetInitiate" : {"_id" : "first", "members" : [{"_id" : 1, "host" : "super1:10001"}, {"_id" : 2, "host" : "super1:10002"}, {"_id" : 3, "host" : "super1:10003"}]}})
{
"info" : "Config now saved locally. Should come online in about a minute.",
"ok" : 1
}
이러면 성공적으로 복제 셋이 만들어 진것 입니다. 이제 데이타를 실제로 넣어보기로 하겠습니다.
PRIMARY> use test
switched to db test
PRIMARY> people = ["Marc", "Bill", "George", "Eliot", "Matt", "Trey", "Tracy", "Greg", "Steve", "Kristina", "Katie", "Jeff"];
PRIMARY> for(var i=0; i<1000000; i++){
name = people[Math.floor(Math.random()*people.length)];
user_id = i;
boolean = [true, false][Math.floor(Math.random()*2)];
added_at = new Date();
number = Math.floor(Math.random()*10001);
db.test_collection.save({"name":name, "user_id":user_id, "boolean": boolean, "added_at":added_at, "number":number });
}
이름을 백만건 정도 랜덤으로 순서를 매겨서 집어넣는 소스코드 입니다.
이제는 구성된 복제 셋을 가지고 샤딩으로 추가해 주는 작업을 해 줘야 할 차례 입니다. 역시 super1 서버에서 작업을 해 줍니다.
config 서버를 띄워줄 차례 입니다. 먼저 config 데이타들이 저장 될 디렉토리를 만들어 줘야 합니다.
$ mkdir ~/db/config1
$ mkdir ~/db/config2
$ mkdir ~/db/config3
컨피그 서버는 1대 아니면 3대를 추천합니다. (제가 아니라 몽고디비 쪽이 추천하는 것입니다)
$ mongod --configsvr --dbpath ~/db/config1 --port 20001 > ~/db/log/config1.log &
$ mongod --configsvr --dbpath ~/db/config2 --port 20002 > ~/db/log/config2.log &
$ mongod --configsvr --dbpath ~/db/config3 --port 20003 > ~/db/log/config3.log &
혹시 컨피그 서버가 제대로 띄워지지 않으면 다른 포트로 띄워주시면 됩니다. 이제 컨피그 서버에서 정보를 가져오는 mongos (라우터 개념)를 띄워줄 차례 입니다.
$ mongos --configdb super1:20001,super2:20002,super3:20003 --chunkSize 1 > ~/db/log/mongos.log &
chunkSize 는 테스트에서만 추가하는 것으로 생각하시면 됩니다. 크기를 1메가로 만드는 것입니다. (기본은 64메가 입니다) 이제 띄워논 mongos 에 접속해야 한다.
$ mongo super1/admin
mongos> db.runCommand( { addshard : "first/super1:10001,super2:10002,super3:10003" } )
{ "shardAdded" : "first", "ok" : 1 }
mongos>
이제 두번째 기계에서 세팅을 할 차례 입니다. super2 (Machine 2) 입니다. 먼저 데이타베이스가 저장될 디렉토리를 만들어 줍니다.
$ mkdir ~/db/second1
$ mkdir ~/db/second2
$ mkdir ~/db/second3
로그용 디렉토리도 만들어 줍니다.
$ mkdir ~/db/log
몽고디비 데몬을 띄워줍니다.
$ mongod --dbpath ~/db/second1 --port 10001 --replSet second > ~/db/log/second1.log &
$ mongod --dbpath ~/db/second2 --port 10002 --replSet second > ~/db/log/second2.log &
$ mongod --dbpath ~/db/second3 --port 10003 --replSet second > ~/db/log/second3.log &
이제 이 프로세스들을 한 개의 복제 셋(replication set)으로 묶어 줍니다.
$ mongo super2:10001/admin
> db.runCommand({"replSetInitiate" : {"_id" : "second", "members" : [{"_id" : 1, "host" : "super2:10001"}, {"_id" : 2, "host" : "super2:10002"}, {"_id" : 3, "host" : "super2:10003"}]}})
{
"info" : "Config now saved locally. Should come online in about a minute.",
"ok" : 1
}
방금 만들어 진 복제 셋 (replication set) 을 새롭게 샤드 (shard) 에 추가해 줍니다. 먼저 mongos 를 띄워줍니다. 지금 super2 서버고 mongos 도 super2 에서 띄우는 것이지만 바라보는 컨피그 서버 는 super1 에서 띄운 것을 쳐다봐야 합니다.
$ mongos --configdb super1:20001,super2:20002,super3:20003 --chunkSize 1 > ~/db/log/mongos.log &
몽고 shell 을 이용해서 mongos (이건 super2 에 띄워 놓은 것입니다) 에 접속합니다.
$ mongo super2/admin
mongos> use admin
switched to db admin
mongos> db.runCommand( { addshard : "second/super2:10001,super2:10002,super3:10003" } )
{ "shardAdded" : "secondset", "ok" : 1 }
이러면 두번째 복제 셋 (replication set) 을 샤드에 추가 해 주었습니다. 제대로 되어 있는지 테스트를 확인 해 보기로 합니다.
mongos> db.runCommand({listshards:1})
{
"shards" : [
{
"_id" : "first",
"host" : "first/super1:10001,super1:10003,super1:10002"
},
{
"_id" : "second",
"host" : "second/super2:10001,super2:10002,super2:10003"
}
],
"ok" : 1
}
샤드로 설정되어 있는 것하고 샤드를 직접적으로 하는 것은 차이가 있습니다. 실제로 샤드를 구현해 보겠습니다. mongos 에 접속되어 있는 상태에서
mongos> db.runCommand( { enablesharding : "test" } )
{ "ok" : 1 }
위 처럼 입력해 주면 'test' db 를 샤딩하겠다고 정해주는 것입니다. 이제 샤딩 키 (Sharding Key) 를 정해줘야 합니다. 샤딩 키를 바탕으로 (이 키로 정렬한다는 뜻입니다) 샤드들이 나눠지게 되기 때문에 샤딩키를 적절하게 정해주는 것은 아주 중요합니다. 인덱스를 정해준다고 보셔도 무방합니다.
mongos> use test
switched to db test
mongos> db.test_collection.ensureIndex({number:1})
생각 난 김에 인덱스도 정해줍니다. test 디비에 test_collection 이라는 컬렉션에서 number 라는 컬럼을
인덱스로 지정해 주라는 명령입니다.
mongos> use admin
switched to db admin
mongos> db.runCommand( { shardcollection : "test.test_collection", key : {"number":1} })
{ "collectionsharded" : "test.test_collection", "ok" : 1 }
mongos>
test 디비에 test_collection 이라는 컬렉션에서 number 라는 컬럼을 샤딩키로 해서 샤딩을 해 주라는 명령입니다.
제대로 됐는지 확인을 해 보겠습니다.
mongos> use test
switched to db test
mongos> db.stats()
db.stats() 나 db.printShardingStatus() 로 확인하시면 됩니다.