'데이터베이스'에 해당되는 글 2건

  1. 맥미니 몽고디비 분산 시스템 (5) - Aggregate
  2. 맥미니 몽고디비 분산 시스템 (4) - Replica Set (3)

1. Sharding을 위한 Shard key 생성

Sharding을 위해서는 Shard Key를 생성해야 하며, 생성된 Shard Key에는 반드시 인덱스의 생성이 요구됩니다.

$ mongo 192.168.3.2:27017/admin
mongos>
mongos> db.runCommand( {enablesharding : "test"} )  // test db 의 Shard 기능 활성화 
mongos>
mongos> use test
mongos> db.things.ensureIndex( {empno : 1} )  // empno 항목에 대한 오름차순 색인 생성 
mongos>
mongos> use admin
mongos> db.runCommand( {shardcollection : "test.things", key : {empno : 1}} )


2. 테스트 데이터 입력

mongos의 test db에 접속해서 50,000,000건의 pseudo 데이터를 입력하고, 입력된 데이터로부터 aggregate()을 해보겠습니다. 입력하고자 하는 pseudo 데이터는 회사의 고용자들에 대한 정보로서 사원번호, 소속 부서의 번호(0~100까지), 그리고 데이터가 입력된 시간 정보를 포함하고 있습니다. 소속 부서의 번호는 무작위Random 방법 으로 0부터 100까지의 숫자가 할당되며, 데이터가 입력된 후에는 소속 부서별로 몇 명의 인원 이 할당되어 있는지 Map-Reduce 방법을 통해서 계산하는 예제도 시현해 보려고 합니다. 현재의 시 스템 구성에서 데이터를 입력하는데 약 90분 정도 소요되며, 입력된 데이터의 크기는 약 20GB 물리적 공간을 차지합니다.

$ mongo 192.168.3.2:27017/test ← test db에 접속한다 mongos>
mongos> for (var n=10000000; n<60000000; n++) {
                         var deptno = Math.round(Math.random()*100);
                         var added_at = new Date();
                         db.things.insert( {"empno": n, "deptno": deptno, "added_at": added_at} )
              }


3. aggregate() 메써드를 통한 Map-Reduce

MongoDB 2.1.2 이상 버전에서는 내장되어 있는 mapReduce() 메써드 이외에도 aggregate() 메써드를 통해서도 Map-Reduce를 시행할 수 있습니다. 50,000,000건의 데이터에서 소속 부서별로 인 원수를 집계하는 Map-Reduce 계산은 aggregate() 메써드를 이용하면 수분 이면 충분합니다.

$ mongo 192.168.3.2:27017/test   // test db에 접속한다
mongos>
mongos> db.things.aggregate( {$group : {_id : "$deptno", total : {"$sum":1}}} )


1. Replica Sets + Sharding 시스템 구성

대용량 처리를 위한 분산 확장이 가능하고 안전성과 높은 가용성 보장을 위해 다음 그림과 같 이 Replica Sets을 구성하고, 이것을 토대로 Sharding 시스템을 구성할 수 있습니다.

4대의 맥미니를 이용하여 Replica Sets + Sharding 시스템을 구성 하는 것을 설명해 드리고자 합니다. 우선 각각의 노드에 다음과 같이 Config 서버와 Replica Set 서버 가 작동하도록 설정해 줍니다. Replica Set1은 모두 10001번 포트를 사용하고, Replica Set2는 모두 10002번 포트를 사용하며, Replica Set3은 모두 10003번 포트를 사용하도록 설정합니다.

node1: 192.168.3.1

$ mkdir /data/config1 /data/replset1 /data/replset3
$ mongod --dbpath /data/config1 --port 20001 &
$ mongod --dbpath /data/replset1 --port 10001 --replSet replset1 --oplogSize 1000 & 
$ mongod --dbpath /data/replset3 --port 10003 --replSet replset3 --oplogSize 1000 &

node2: 192.168.3.2

$ mkdir /data/replset1 /data/replset2
$ mongod --dbpath /data/replset1 --port 10001 --replSet replset1 --oplogSize 1000 & 
$ mongod --dbpath /data/replset2 --port 10002 --replSet replset2 --oplogSize 1000 &

node3: 192.168.3.3

$ mkdir /data/config2 /data/replset1 /data/replset2 /data/replset3
$ mongod --dbpath /data/config2 --port 20001 &
$ mongod --dbpath /data/replset1 --port 10001 --replSet replset1 --oplogSize 1000 & 
$ mongod --dbpath /data/replset2 --port 10002 --replSet replset2 --oplogSize 1000 & 
$ mongod --dbpath /data/replset3 --port 10003 --replSet replset3 --oplogSize 1000 &

node4: 192.168.3.4

$ mkdir /data/config3 /data/replset2 /data/replset3
$ mongod --dbpath /data/config3 --port 20001&
$ mongod --dbpath /data/replset2 --port 10002 --replSet replset2 --oplogSize 1000 & 
$ mongod --dbpath /data/replset3 --port 10003 --replSet replset3 --oplogSize 1000 &

각 노드별 설정이 끝나면, Replica Set을 초기화해야 한다. Replica Set을 구성할 때 Primary 서버와 여러 대의 Replica 서버로 구성된 환경에서 Primary 서버에 장애가 발생하면 MongoDB는 10초 이내에 다음 Primary 서버가 되어야 할 노드 하나를 선택해 줍니다. 이 경우, 아비타 Arbiter 서버가 활성화 되어 있으면 아비타가 적절한 서버를 선택해 주지만 사용자가 각 서버 에 대한 우선순위를 설정해 둔 경우에는 가장 높은 값을 부여받은 서버가 Primary 서버가 됩니다.

node1 - setting replica set1 (arbiter server: node3)

$ mongo 192.168.3.1:10001/admin MongoDB shell version: 2.2.5 connecting to: 192.168.3.1:10001/admin > db.runCommand( {"replSetInitiate" : {"_id" : "replset1", "members" : [ {"_id" : 1, "host" : "192.168.3.1:10001"}, {"_id" : 2, "host" : "192.168.3.2:10001"}, {"_id" : 3, "host" : "192.168.3.3:10001", arbiterOnly:true} ] } } )

node2 - setting replica set2 (arbiter server: node4)

$ mongo 192.168.3.2:10002/admin MongoDB shell version: 2.2.5 connecting to: 192.168.3.2:10002/admin > db.runCommand( {"replSetInitiate" : {"_id" : "replset2", "members" : [ {"_id" : 1, "host" : "192.168.3.2:10002"}, {"_id" : 2, "host" : "192.168.3.3:10002"}, {"_id" : 3, "host" : "192.168.3.4:10002", arbiterOnly:true} ] } } )

node3 - setting replica set3 (arbiter server: node1)

$ mongo 192.168.3.3:10002/admin MongoDB shell version: 2.2.5 connecting to: 192.168.3.3:10002/admin > db.runCommand( {"replSetInitiate" : {"_id" : "replset3", "members" : [ {"_id" : 1, "host" : "192.168.3.3:10003"}, {"_id" : 2, "host" : "192.168.3.4:10003"}, {"_id" : 3, "host" : "192.168.3.1:10003", arbiterOnly:true} ] } } )

이제 Config 서버를 설정하고 Replica Set을 Sharding으로 구성하는 과정이 남았습니다. 우선 node1, node3, node4 에 설정되어 있는 Config 서버들을 mongos로 연결시켜야 합니다. mongos 프로세스 설정을 위해서 node2에 접속 한 후에 다음과 같은 방법으로 mongos 프로세스를 설정할 수 있습니다.

$ mongos --configdb 192.168.3.1:20001,192.168.3.3:20001,192.168.3.4:20001 --port 27017 --chunkSize 64

이제 node2의 mongos 프로세스에 접속해서 ‘addShard'를 통해서 Replica Sets을 Shard 서버로 등록하면 시스템 구축이 모두 마무리 됩니다.

$ mongo 192.168.3.2:27017/admin mongos> mongos> db.runCommand( {addShard : "replset1/192.168.3.1:10001,192.168.3.2:10001, 192.168.3.3:10001"} ) // add replset1 as shard server mongos> db.runCommand( {addShard : "replset2/192.168.3.2:10002,192.168.3.3:10002, 192.168.3.4:10002"} ) // add replset2 as shard server mongos> db.runCommand( {addShard : "replset3/192.168.3.3:10003,192.168.3.4:10003, 192.168.3.1:10003"} ) // add replset3 as shard server mongos> mongos> use config // Config 설정에서 샤딩과 관련된 사항을 확인할 수 있다 mongos> db.shards.find() // Shard 서버 목록 확인 mongos> sh.status() // Shard 서버의 상태 확인