블로그 이미지
윤영식
Full Stacker, Application Architecter, KnowHow Dispenser and Bike Rider

Publication

Category

Recent Post

2013. 1. 8. 20:12 Git, GitHub/Git Lec02

SVN의 Tag처럼 Git에도 Tag가 있다. 어떻게 사용하는지 보자 


1) Tag 조회하기 : git tag 

  - 특정 버전 조회시 git tag -l 'v1.4.2.*' 식으로 조회한다


2) Annotated Tag 붙이기 : git tag -a [버전] -m '[메시지]'

  - Tag를 만든 사람의 이름, 이메일, 날짜, 메시지를 저장함. 단순 Tag일때는 Lightweight Tag를 사용함 

  - Tag 정보와 커밋 정보 보기 : git show [버전]

$ git tag -a v1.1 -m 'pro git version 1.1'


$ git tag

v1.1


$ git show v1.1

tag v1.1

Tagger: Yun DoWon <ysyun@yuwin.co.kr>

Date:   Tue Jan 8 19:40:20 2013 +0900


pro git version 1.1


commit 329db048ff7af2d417588e28da50a6c53fb1bd84

Author: Yun DoWon <ysyun@yuwin.co.kr>

Date:   Thu Dec 27 11:07:26 2012 +0900


    add content in build.gradle


3) Lightweight Tag : git tag [버전]

  - 브랜치처럼 가리키는 지점을 최신 커밋으로 이동시키지 않는다. 단순 특정 커밋에 대한 포인터일 뿐임 (체크섬만을 저장할 뿐)

  - -a, -s, -m 등의 옵션을 사용하지 않는다 

$ git tag v1.1w


$ git tag

v1.1

v1.1w


// 단순히 커밋 정보만 보여준다

$ git show

commit 329db048ff7af2d417588e28da50a6c53fb1bd84

Author: Yun DoWon <ysyun@yuwin.co.kr>

Date:   Thu Dec 27 11:07:26 2012 +0900


    add content in build.gradle


4) Tag 검증하기 : git tag -v [버전]

  - GPG 서명을 검증하는 것으로 공개키가 필요하다

  - 서명 메시지가 없으면 하기와 같은 error 메시지가 나옴 (다음 기회에 다시 알아보자)

 $ git tag -v v1.1

object 329db048ff7af2d417588e28da50a6c53fb1bd84

type commit

tag v1.1

tagger Yun DoWon <ysyun@yuwin.co.kr> 1357641620 +0900


pro git version 1.1

error: no signature found

error: could not verify the tag 'v1.1'


5) 나중에 Tag 하기 : git tag -a v1.2 [해쉬값 앞 7자리] -m '[메시지]'

  - 과거 특정 커밋에 대해서 Tag를 달 수 있다. 커밋 내역 확인하기 : git log --pretty=oneline

$ git log --pretty=oneline

329db048ff7af2d417588e28da50a6c53fb1bd84 add content in build.gradle

f856853c5b0ac53483f9d14fe1b3ec6ef0fdbca7 Update build.gradle

03ca40a6026b9144f15cc8988ad6539049d36486 Create build.gradle

49c657f59b787b0ee8409782cd1d5ff16b78033d Initial commit


// 메시지를 -m을 넣지 않으면 하기와 같이 오류 발생함

$ git tag -a v1.2 03ca40a

fatal: no tag message?


$ git tag -a v1.0.1 03ca40a -m 'v1.0.1'


$ git tag

v1.0.1

v1.1

v1.1w


$ git show v1.0.1

tag v1.0.1

Tagger: Yun DoWon <ysyun@yuwin.co.kr>

Date:   Tue Jan 8 19:57:06 2013 +0900


v1.0.1


commit 03ca40a6026b9144f15cc8988ad6539049d36486

Author: 윤도원 (영식) <ysyun@yuwin.co.kr>

Date:   Wed Dec 26 17:55:01 2012 -0800


    Create build.gradle


6) Tag 공유하기 : git push origin [버전]

  - 서버로 Branch를 push 하는 것과 동일하다 

  - 한번에 여러 개의 tag를 push 하기 : git push origin --tags

$ git push origin v1.1

Username for 'https://github.com':

Password for 'https://ysyun@yuwin.co.kr@github.com':

Counting objects: 1, done.

Writing objects: 100% (1/1), 169 bytes, done.

Total 1 (delta 0), reused 0 (delta 0)

To https://github.com/ysyun/pro_git.git

 * [new tag]         v1.1 -> v1.1


$ git push origin --tags

Username for 'https://github.com':

Password for 'https://ysyun@yuwin.co.kr@github.com':

Counting objects: 1, done.

Writing objects: 100% (1/1), 159 bytes, done.

Total 1 (delta 0), reused 0 (delta 0)

To https://github.com/ysyun/pro_git.git

 * [new tag]         v1.0.1 -> v1.0.1

 * [new tag]         v1.1w -> v1.1w


posted by 윤영식
2013. 1. 7. 22:42 CI/Jenkins, Travis

Jenkins를 설치하고 로그인 Security 설정하는 법을 알아보자. 


1) 우선 jenkins.war 을 다운로드 받는다. 

  - http://jenkins-ci.org 사이트 방문

  - war 파일 다운로드 하기 (윈도우의 exe 버전은 받지 말자)

    


2) 특정 디렉토리에 jenkins.war파일을 놓고, bat 파일을 만들자

  - d:/jenkins/jenkins.war 파일 놓기 

  - d:/jenkins/startJenkins.bat 파일 만들기 (물론 JDK1.5 이상 버전으로 pre-install 되어 있어야 한다)

java -jar ./jenkins.war


3) jenkins를 실행하고 브라우져에서 호출하기 

  - startJenkins.bat파일을 수행하였다면 다음과 같은 메세지가 나온다

   


  - 브라우져에서 호출을 한다. 이때 http://yourdomain.wowip.kr:8080/ 방식으로 호출하고 싶다면 jenkins 설치 PC에 WOWIP를 설치하자. (설치가 안되었다면 우선 http://127.0.0.1:8080/ 으로 호출한다)


  - "Jenkins 관리" 메뉴 클릭 -> "Configure Global Security" 클릭 한다


4) Security를 설장한다

  - "Enable security" 를 체크한다 

  - Security Realm 그룹에서 "Jenkins's own user database"를 클릭하고 하위의 "Allow users to sign up"을 체크한다

  - Authroization 그룹에서 "Matrix-based security"를 체크한다

 


5) "Matrix-based security"를 체크하였다면 로그인 아이디를 입력하고 "add" 한 후 설정하고 싶은 권한을 체크한다

 

- 화면 하단의 "Save" 버튼을 클릭하여 적용한다 


6) 등록된 아이디에 대해서 "가입"을 한다. 

  - 메인 화면으로 나오면 상단 오른쪽의 "가입"을 클릭한다

  


  - 등록된 계정에 대하여 입력하고 설정하려는 패스워드와 e-mail주소를 입력한다

  


7) 이제 로그인을 하면 설정된 권한의 메뉴가 좌측에 나온다

  


* 참조 : Jenkins Standard Security Setup

'CI > Jenkins, Travis' 카테고리의 다른 글

[Travis] GitHub과 Travis CI 연동하기  (0) 2013.08.14
[Jenkins] Jenkins와 Gradle 그리고 JavaScript  (0) 2012.12.26
posted by 윤영식
2013. 1. 5. 17:06 MongoDB

http://mongoosejs.com (GitHub)에 대하여 알아보자. (mongoose의 light-weight ORM version으로 몽고리안-mongolian-도 존재한다)


1) mongoose의 schema는 extension = controller 이다 : Node.js 소스 

/**

* Module dependencies.

*/


var express = require('express')

, routes = require('./routes');


var mongoose = require('mongoose');

var Schema = mongoose.Schema;


mongoose.connect('mongodb://localhost/mydb');


var UserSchema = new Schema({ // MVC controller

age : Number,

name: String,

sex: Boolean

});


var UserModel = mongoose.model('users', UserSchema); // Model ---> collection


var app = module.exports = express.createServer();


// Configuration


app.configure(function(){

app.set('views', __dirname + '/views');

app.set('view engine', 'jade');

app.use(express.bodyParser());

app.use(express.methodOverride());

app.use(app.router);

app.use(express.static(__dirname + '/public'));

});


app.configure('development', function(){

app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));

});


app.configure('production', function(){

app.use(express.errorHandler());

});


// Routes


app.get('/', routes.index);


app.param('name', function (req, res, next, name) {

UserModel.find({ name: name }, function (err, docs) {

req.user = docs[0];

next();

});

});


app.get('/users/:name', function (req, res) {

// res.json({ user: req.user });

res.render('./show',{ title: 'Express User',user: req.user });

});


app.get('/users/:name/edit', function (req, res) {

res.render('./edit',{ title: 'Express User',user: req.user });

});


app.get('/users', function (req, res) {

// res.json({ user: req.user });

UserModel.find({},function(err,docs) {

res.render('./users', { title: 'Express User', users: docs });

});

});


app.get('/user/new', function (req, res) {

res.render('new',{layout:false}); //,user:{name:'',age:0,sex:false}}); //,{ title: 'Express User'});

});


app.del('/users/:name', function (req, res) {


UserModel.remove({ name: req.params.name }, function (err) {

res.redirect('/users');

});


});


app.post('/users', function (req, res) {

var b = req.body;

new UserModel({

name: b.name,

age: b.age,

sex:b.sex

}).save(function (err, user) {

if (err) res.json(err);


res.redirect('/users/' + user.name);

});

});


app.put('/users/:name/edit', function (req, res) {

var b = req.body;

UserModel.update(

{ name: req.params.name },

{ name: b.name, age: b.age, sex: b.sex },

function (err) {

res.redirect('/users/' + b.name);

}

);


});


app.listen(process.env.port || 3000);

console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);


  - Jade 소스

h1 Edit User


form(method='POST', action('/users/#{user.name}'))

input(type='hidden',name='_method',value='PUT')

p Name:

input#name(type='text', name='name', value='#{user.name}')

p Age:

input#age(type='number', name='age', value='#{user.age}')

p Sex:

input#sex(type='boolean', name='sex', value='#{user.sex}')

p

button(type='submit') Update


h1 New User


form(method='POST', action= '/users')

p Name:

input#name(type='text',name='name')

p Age:

input#age(type='number',name='age')

p Sex:

input#sex(type='boolean',name='sex')

button(type='submit') Create


h1 #{user.name}


ul

li Age: #{user.age}

li Sex: #{user.sex}


ul

li: a(href='/users/#{user.name}/edit') Edit

li

form(action='/users/#{user.name}' , method='POST')

input(type='hidden',name='_method',value='DELETE')

button(type='submit') Delete


h1 All Users


ul

each user in users

li: a(href='/users/#{user.name}') #{user.name} #{user.age} #{user.sex}


2) v3에서 변경된 것들



< 참조 > 

- Mongoose 2.3.9 온라인 매뉴얼

http://nodejs-kr.org/insidejs/archives/536


- Mongoose : Elegant MongoDB object modeling for Node.js (GitHub)

http://mongoosejs.com/


- Node.js 

http://www.mongodb.org/display/DOCS/Node.js


- masylum / mongolia 

https://github.com/masylum/mongolia

'MongoDB' 카테고리의 다른 글

[MongoDB] Ubuntu 에 설치하기  (0) 2012.11.14
posted by 윤영식
2013. 1. 5. 16:26 MongoDB/Prototyping

MongoDB에서 Replica Set을 구성하였을 때 mongodb를 접속하는 client에 대하여 routing 서비스를 하는 mongos(몽고스)에 대해 알아보자.



1. 구성 아키텍쳐

  - Shard 한개에 mongod 한개를 맵핑한다

  - config 한개에 mongod 한개만 사용한다



2) 구성하기 

  - shard1, shard2, shard3, config, mongos를 간단히 만들어 보자 (shard를 replica set으로 구성은 배재, 참조)

  - Shard server 3개 띄우기 : sdb01, sdb02, sdb03 디렉토리는 미리 만들어 놓는다. (기동은 개별 콘솔에서 실행함)

$ ./mongod --shardsvr --dbpath /home/dowon/MongoDB/sdb01 --port 10000

Fri Jan  4 22:25:03 

Fri Jan  4 22:25:03 warning: 32-bit servers don't have journaling enabled by default. Please use --journal if you want durability.

.. 중략 ...

Fri Jan  4 22:25:03 [initandlisten] build info: Linux domU-12-31-39-01-70-B4 2.6.21.7-2.fc8xen #1 SMP Fri Feb 15 12:39:36 EST 2008 i686 BOOST_LIB_VERSION=1_49

Fri Jan  4 22:25:03 [initandlisten] options: { dbpath: "/home/dowon/MongoDB/sdb01", port: 10000, shardsvr: true }

Fri Jan  4 22:25:03 [websvr] admin web console waiting for connections on port 11000


./mongod --shardsvr --dbpath /home/dowon/MongoDB/sdb02 --port 20000
./mongod --shardsvr --dbpath /home/dowon/MongoDB/sdb03 --port 30000

////////////////////////////
// config srever를 띄웠다. 
$ ./mongod --configsvr --dbpath /home/dowon/MongoDB/sdb04c --port 40000
Fri Jan  4 22:29:47 
Fri Jan  4 22:29:47 warning: 32-bit servers don't have journaling enabled by default. Please use --journal if you want durability.
Fri Jan  4 22:29:47 
Fri Jan  4 22:29:47 [initandlisten] MongoDB starting : pid=8201 port=40000 dbpath=/home/dowon/MongoDB/sdb04c 32-bit host=localhost.localdomain
Fri Jan  4 22:29:48 [initandlisten] waiting for connections on port 40000
Fri Jan  4 22:29:48 [websvr] admin web console waiting for connections on port 41000

////////////////////////////
// mongos 띄우기 : chunksize 정하지 않으며 1Mbytes이다. 
$ ./mongos --configdb localhost:40000 --chunkSize 1
Fri Jan  4 22:32:04 warning: running with 1 config server should be done only for testing purposes and is not recommended for production
Fri Jan  4 22:32:04 [mongosMain] MongoS version 2.2.2 starting: pid=8239 port=27017 32-bit host=localhost.localdomain (--help for usage)
Fri Jan  4 22:32:04 [mongosMain] git version: d1b43b61a5308c4ad0679d34b262c5af9d664267
Fri Jan  4 22:32:04 [mongosMain] build info: Linux domU-12-31-39-01-70-B4 2.6.21.7-2.fc8xen #1 SMP Fri Feb 15 12:39:36 EST 2008 i686 BOOST_LIB_VERSION=1_49
Fri Jan  4 22:32:11 [Balancer] distributed lock 'balancer/localhost.localdomain:27017:1357367525:1804289383' unlocked. 
Fri Jan  4 22:32:17 [Balancer] distributed lock 'balancer/localhost.localdomain:27017:1357367525:1804289383' acquired, ts : 50e7c8f1b1a36d7262b31138


3) mongos 에서 환경 구성하기

  - mongo shell로 들어가서 shard 환경을 만든다 : 자동으로 mongos로 들어간다 (프롬프트 명칭이 mongos가 됨)

$ ./mongo

MongoDB shell version: 2.2.2

connecting to: test

mongos> use admin

switched to db admin

mongos> db

admin

mongos> show dbs

config 0.046875GB

mongos> use peopleDB
switched to db peopleDB
// config 셋팅을 하지 않고 사용하면 다음과 같은 에러가 발생한다. 
mongos> db.people.save({_id:1, age:11, name:'dowon1', sex:false});
Fri Jan  4 22:38:03 uncaught exception: error {
"$err" : "error creating initial database config information :: caused by :: can't find a shard to put new db on",
"code" : 10185
}
mongos> 

/////////////////////////
// 다시 mongo로 들어온다. 
// 그리고 shard에 서버를 추가해 준다.
$ ./mongo
MongoDB shell version: 2.2.2
connecting to: test
mongos> db
test
mongos> use admin
switched to db admin
mongos> db
admin
mongos> db.runCommand({addshard:'localhost:10000'});
{ "shardAdded" : "shard0000", "ok" : 1 }
mongos> db.runCommand({addshard:'localhost:20000'});
{ "shardAdded" : "shard0001", "ok" : 1 }
mongos> db.runCommand({addshard:'localhost:30000'});
{ "shardAdded" : "shard0002", "ok" : 1 }

////////////////////////////////
// mongos를 통하여 CRUD를 한다
// 과연 입력한 데이터는 Shard가 되었을까? 
mongos> 
mongos> use testShard
switched to db testShard
mongos> db
testShard
mongos> db.people.save({_id:1, age:11, name:'dowon1', sex:false});
mongos> db.people.save({_id:2, age:22, name:'dowon2', sex:true});
mongos> db.people.save({_id:3, age:33, name:'dowon3', sex:false});
mongos> db.people.find();
{ "_id" : 1, "age" : 11, "name" : "dowon1", "sex" : false }
{ "_id" : 2, "age" : 22, "name" : "dowon2", "sex" : true }
{ "_id" : 3, "age" : 33, "name" : "dowon3", "sex" : false }

/////////////////////////////////////
// 결과 확인 : auto shard가 안되어 있다
// sdb01에만 데이터가 저장되어 있다. 이유 : config server를 가동시키지 않았기 때문이다.
[dowon@localhost MongoDB]$ cd sdb01
[dowon@localhost sdb01]$ ll
total 65548
-rwxrwxr-x. 1 dowon dowon        5 Jan  4 22:25 mongod.lock
-rw-------. 1 dowon dowon 16777216 Jan  4 22:43 testShard.0
-rw-------. 1 dowon dowon 33554432 Jan  4 22:42 testShard.1
-rw-------. 1 dowon dowon 16777216 Jan  4 22:43 testShard.ns
drwxrwxr-x. 2 dowon dowon     4096 Jan  4 22:42 _tmp
[dowon@localhost sdb01]$ cd ../sdb02
[dowon@localhost sdb02]$ ll
total 4
-rwxrwxr-x. 1 dowon dowon 5 Jan  4 22:25 mongod.lock
[dowon@localhost sdb02]$ cd ../sdb03
[dowon@localhost sdb03]$ ll
total 4
-rwxrwxr-x. 1 dowon dowon 5 Jan  4 22:25 mongod.lock


4) Shard 테스트를 위한 데이터 만들고 확인하기 

  - shard 연결 환경을 설정한다. (참조 동영상, Shard Guide blog)

////////////////////////////////

// 10000 port mongodb로 들어가자

// 이것은 10000 port의 mongodb로 direct 들어가는 것이다. 

$ ./mongo localhost:10000

MongoDB shell version: 2.2.2

connecting to: localhost:10000/test

> show dbs

local (empty)

testShard 0.0625GB

> use testShard

switched to db testShard

> db

testShard

> show collections

people

system.indexes

> db.people.find();

{ "_id" : 1, "age" : 11, "name" : "dowon1", "sex" : false }

{ "_id" : 2, "age" : 22, "name" : "dowon2", "sex" : true }

{ "_id" : 3, "age" : 33, "name" : "dowon3", "sex" : false }


////////////////////////////
// 20000, 30000 port로 mongos를 통하지 않고 mongodb로 바로 접속하면 
// testShard DB는 없다. 
$ ./mongo localhost:20000
MongoDB shell version: 2.2.2
connecting to: localhost:20000/test
> show dbs
local (empty)

/////////////////////////////////
// mongos로 들어간다. use admin 
// Sharding 환경설정하기
$ ./mongo
MongoDB shell version: 2.2.2
connecting to: test
mongos> dbs
Fri Jan  4 22:54:15 ReferenceError: dbs is not defined (shell):1
mongos> show dbs
config 0.046875GB
testShard 0.0625GB
mongos> use admin
switched to db admin
mongos> db
admin
mongos> db.runCommand({enablesharding:'testShard'});
{ "ok" : 1 }
mongos> db.runCommand({shardcollection:'people', key:{_id:1}});
{ "ok" : 0, "errmsg" : "bad ns[people]" } <-- namespace 에러 
mongos> db.runCommand({shardcollection:'testShard.people', key:{_id:1}});  // _id:1 의 1은 sorting
{ "collectionsharded" : "testShard.people", "ok" : 1 }

//////////////////////////////////////////////
// people collection에 데이터를 넣어보자
mongos> for(var i=6 ; i<100000 ; i++) {
      db.people.save({_id:i, age:44, name:'dowon'+i, sex:true});
   }

//////////////////////////////////////////////////////////////////////////
// 다른 mongo에서 show dbs를 해보면 testShard DB가 생성되었음을 볼 수 있다. 
// chunkSize 1Mbytes 이상이면 sharding이 이루어진다. 
[dowon@localhost mongodb]$ ./mongo localhost:20000
MongoDB shell version: 2.2.2
connecting to: localhost:20000/test
> show dbs
local (empty)
> show dbs
admin (empty)
local (empty)
testShard 0.0625GB
> use testShard
switched to db testShard
> db.people.find();
{ "_id" : 54053, "age" : 44, "name" : "dowon54053", "sex" : true } // 54053 번부터 Sharding 되었다. 
{ "_id" : 54054, "age" : 44, "name" : "dowon54054", "sex" : true }
{ "_id" : 54055, "age" : 44, "name" : "dowon54055", "sex" : true }
{ "_id" : 54056, "age" : 44, "name" : "dowon54056", "sex" : true }
{ "_id" : 54057, "age" : 44, "name" : "dowon54057", "sex" : true }

[dowon@localhost mongodb]$ ./mongo localhost:30000
MongoDB shell version: 2.2.2
connecting to: localhost:30000/test
local (empty)
> show dbs
admin (empty)
local (empty)
testShard 0.0625GB
> use testShard
switched to db testShard
> db.people.find();
{ "_id" : 22200, "age" : 44, "name" : "dowon22200", "sex" : true } // 22200 번부터 Sharding 되었다. 
{ "_id" : 22201, "age" : 44, "name" : "dowon22201", "sex" : true }
{ "_id" : 22202, "age" : 44, "name" : "dowon22202", "sex" : true }
{ "_id" : 22203, "age" : 44, "name" : "dowon22203", "sex" : true }

< 결론 > 
Sharding 시켜놓은 서버로 ChunkSize 크기에 따라 데이터가 분산되어 저장된다. 

 

* 요약 (명령 참조)

  - mongo admin 으로 들어간다

  - runCommand 통하여 세가지 설정을 수행한다. 

  - chunkSize에 따라서 Sharding이 이루어진다.


* Sharding 개념 다시 정리 하기


* MongoDB의 철학은?

데이터와 데이터로직의 분리 

 - 데이터 : JSON (실제 BSON : binary json 형태로 저장됨)

 - 데이터로직 : JavaScript


<참조>

  - 10gen 설정 튜토리얼

posted by 윤영식
2013. 1. 5. 14:56 MongoDB/Prototyping

MongoDB의 Replica Set을 만들어 보자. 먼저 Master/Slave와 Primary/Secondary 순으로 본다. Master/Slave는 Slave에서 Read가 된다. 그러나 Primary/Secondary에서 Secondary는 Read도 되지 않는다.  



1. Replica Set 만들기 위한 Master / Slave 에 대해 알아보자. (Replica Set은 아니다)

  - Master로 DB 수행하기 : master의 mongo에서 CRUD 가능

$ ./mongod -dbpath /home/dowon/MongoDB/db01 --master &

만일 db가 비정상 종료되었다면 

$ ./mongod -dbpath /home/dowon/MongoDB/db01 --master --repair &

수행후에 다시 $ ./mongod -dbpath /home/dowon/MongoDB/db01 --master & 를 수행한다. 


... 하기 메세지 나오면 정상 부팅

Fri Jan  4 19:29:59 [initandlisten] Unable to check for journal files due to: boost::filesystem::basic_directory_iterator constructor: No such file or directory: "/home/dowon/MongoDB/db01/journal"

Fri Jan  4 19:29:59 [initandlisten] waiting for connections on port 27017

Fri Jan  4 19:29:59 [websvr] admin web console waiting for connections on port 28017

   

  - Slave로 DB 수행하기 : -slave 옵션 

    + slave의 mongo에서 CUD 안됨. Read만 가능하다. 

    + source 지정하여 replica set 만들 master가 누구인지 알려준다. 

    + 기존에 single로 사용하던 mongod를 master/slave로 묶고자 할 경우 기존 데이터를 slave로 복제하기 잘 안됨

       -> 다른 디렉토리로 복사해서 그런가? 테스트 필요함

    + 신규로 master/slave를 띄워서 save 또는 insert 하였을 때 slave 쪽 디렉토리에 db 파일이 제대로 복제됨 

$ ./mongod --dbpath /home/dowon/MongoDB/db02 --port 27018 --slave --source localhost:27017 &

...

Fri Jan  4 19:12:46 [initandlisten] Unable to check for journal files due to: boost::filesystem::basic_directory_iterator constructor: No such file or directory: "/home/dowon/MongoDB/db02/journal"

Fri Jan  4 19:12:46 [initandlisten] waiting for connections on port 27018   <-- 정상 부팅

Fri Jan  4 19:12:46 [websvr] admin web console waiting for connections on port 28018

// 하기 메세지는 master에 있는 데이터 파일을 slave로 복사해 온다. 마치 git의 pull과 유사한 느낌 ^^ 

Fri Jan  4 19:12:47 [FileAllocator] done allocating datafile /home/dowon/MongoDB/db02/local.ns, size: 16MB,  took 0.001 secs

Fri Jan  4 19:12:48 [FileAllocator] allocating new datafile /home/dowon/MongoDB/db02/local.0, filling with zeroes...

Fri Jan  4 19:12:48 [replslave] build index done.  scanned 0 total records. 0 secs


// db02 디렉토리에 가보면 db01에 있던 데이터베이스 mydb가 copy되어 있는 것을 볼 수 있다. 

Fri Jan  4 19:12:48 [replslave] resync: dropping database mydb

Fri Jan  4 19:12:48 [replslave] resync: cloning database mydb to get an initial copy

Fri Jan  4 19:12:48 [FileAllocator] allocating new datafile /home/dowon/MongoDB/db02/mydb.ns, filling with zeroes...

Fri Jan  4 19:12:48 [FileAllocator] done allocating datafile /home/dowon/MongoDB/db02/mydb.ns, size: 16MB,  took 0.045 secs

Fri Jan  4 19:12:49 [replslave] resync: done with initial clone for db: mydb

Fri Jan  4 19:12:49 [FileAllocator] done allocating datafile /home/dowon/MongoDB/db02/mydb.1, size: 32MB,  took 0.085 secs



2. Replica Set default 만들기 

  - replica set 구동하기 : db11, db12, db13 3개를 띄운다. replica set 명칭은 dowon01 이다. 

  - 디렉토리를 3개 만들고 각 디렉토리별로 서로 다른 port로 replica set 1개를 만들어 본다.

  - mongod를 shutdown 시키고 싶을 경우 : mongo 쉘에서 db.shutdownServer({timeoutSecs: 60});  - 메뉴얼

  - 결론 : mongod를 여러개 띄워서 파일시스템의 약점을 극복한다 (High Availability - HA 구성)

//////////////////////////////////////

// Replica Set 을 1개 만든다 

$ ./mongod --replSet dowon01 --port 30000 --dbpath /home/dowon/MongoDB/db11

$ ./mongod --replSet dowon01 --port 40000 --dbpath /home/dowon/MongoDB/db12

$ ./mongod --replSet dowon01 --port 50000 --dbpath /home/dowon/MongoDB/db13


// 하기 환경설정관련 에러가 나온다 (정상 - 아직 환경설정 안했기 때문에 ^^)

... 중략 ...

Fri Jan 25 23:14:06 [rsStart] replSet can't get local.system.replset config from self or any seed (EMPTYCONFIG)

Fri Jan 25 23:14:23 [initandlisten] connection accepted from 127.0.0.1:34440 #1 (1 connection now open)

Fri Jan 25 23:14:26 [rsStart] replSet can't get local.system.replset config from self or any seed (EMPTYCONFIG)


/////////////////////////////////////

// mongo client 접속 하기

[dowon@localhost mongodb]$ ./mongo localhost:30000

MongoDB shell version: 2.2.2

connecting to: localhost:30000/test

> show dbs

local (empty)

> exit

bye

[dowon@localhost mongodb]$ ./mongo localhost:40000

MongoDB shell version: 2.2.2

connecting to: localhost:40000/test

> show dbs

local (empty)

> exit

bye

[dowon@localhost mongodb]$ ./mongo localhost:50000

MongoDB shell version: 2.2.2

connecting to: localhost:50000/test

> show dbs

local (empty)


  - Configuration 작업하기 

///////////////////////////////////////////////////

// PRIMARY + SECONDARY Replica Set 만들기 

[dowon@localhost mongodb]$ ./mongo localhost:30000

MongoDB shell version: 2.2.2

connecting to: localhost:30000/test

> var config={_id:'dowon01', members:[{_id:0, host:30000},

... {_id:1, host:40000}^C


// 환경 객체를 만든다 

var config={_id:'dowon01', members:[

    {_id:0, host:'localhost:30000'},

    {_id:1, host:'localhost:40000'},

    {_id:2, host:'localhost:50000'}]

  }


// replica set을 초기화 한다. 

> rs.initiate(config);

{

"info" : "Config now saved locally.  Should come online in about a minute.",

"ok" : 1

}


// 3000 port의 메세지를 보면 다음과 같다. 

// 1) config 없을 때 나오는 메세지이다. 

Fri Jan  4 21:20:29 [rsStart] replSet can't get local.system.replset config from self or any seed (EMPTYCONFIG)

Fri Jan  4 21:20:39 [rsStart] replSet can't get local.system.replset config from self or any seed (EMPTYCONFIG)

// 2) rs.initiate를 수행하면 하기와 같은 메세지가 나온다. 

Fri Jan  4 21:20:44 [conn2] replSet replSetInitiate admin command received from client

Fri Jan  4 21:20:44 [conn2] replSet replSetInitiate config object parses ok, 3 members specified

Fri Jan  4 21:20:44 [conn2] replSet replSetInitiate all members seem up

Fri Jan  4 21:20:44 [conn2] ******

Fri Jan  4 21:20:44 [conn2] replSet info saving a newer config version to local.system.replset

Fri Jan  4 21:20:44 [conn2] replSet saveConfigLocally done

Fri Jan  4 21:20:44 [conn2] replSet replSetInitiate config now saved locally.  Should come online in about a minute.

Fri Jan  4 21:20:44 [conn2] command admin.$cmd command: { replSetInitiate: { _id: "dowon01", members: [ { _id: 0.0, host: "localhost:30000" }, { _id: 1.0, host: "localhost:40000" }, { _id: 2.0, host: "localhost:50000" } ] } } ntoreturn:1 keyUpdates:0 locks(micros) W:431969 reslen:112 477ms

Fri Jan  4 21:20:49 [rsStart] replSet I am localhost:30000

Fri Jan  4 21:20:49 [rsStart] replSet STARTUP2

Fri Jan  4 21:20:49 [rsHealthPoll] replSet member localhost:40000 is up

Fri Jan  4 21:20:49 [rsHealthPoll] replSet member localhost:50000 is up

Fri Jan  4 21:20:50 [initandlisten] connection accepted from 127.0.0.1:43880 #3 (2 connections now open)

Fri Jan  4 21:20:50 [rsSync] replSet SECONDARY

... 중략 ...
>                                   <== enter key를 치면 하기와 같은 프롬프트로 자동 변경된다
dowon01:PRIMARY>   <== "replicaSet명칭:PRIMARY>" 명칭이 나온다 

////////////////////////////////////////////
// 40000, 50000 번의 client를 들어가 보자 
[dowon@localhost mongodb]$ ./mongo localhost:40000
MongoDB shell version: 2.2.2
connecting to: localhost:40000/test
dowon01:SECONDARY> 

[dowon@localhost mongodb]$ ./mongo localhost:50000
MongoDB shell version: 2.2.2
connecting to: localhost:50000/test
dowon01:SECONDARY> 

//////////////////////////////////////////
// SECONDARY 에서 하기와같은 에러 발생시 rs.slaveOk() 수행
[mongodb@localhost ~]$ ./mongo localhost:40000
MongoDB shell version: 2.2.2
connecting to: localhost:20000/test
dowon01:SECONDARY> show dbs
dowonDB 0.0625GB
local 0.125GB
test (empty)
dowon01:SECONDARY> use dowonDB
switched to db dowonDB
dowon01:SECONDARY> db
dowonDB
dowon01:SECONDARY> show collections
Fri Jan 25 23:45:06 uncaught exception: error: { "$err" : "not master and slaveOk=false", "code" : 13435 }
// primary 의 데이터를 가져온다
dowon01:SECONDARY> rs.slaveOk()
dowon01:SECONDARY> show collections
test
system.indexes

//////////////////////////////////////////
// PRIMARY 에서 데이터베이스 생성하기 
dowon01:PRIMARY> db
test
dowon01:PRIMARY> use peopleDB
switched to db peopleDB
dowon01:PRIMARY> db.people.insert({_id:1, age:11, name:'dowon1', sex:false});
dowon01:PRIMARY> db.people.insert({_id:2, age:22, name:'dowon2', sex:true});
dowon01:PRIMARY> db.people.insert({_id:3, age:33, name:'dowon3', sex:false});
dowon01:PRIMARY> db.people.find();
{ "_id" : 1, "age" : 11, "name" : "dowon1", "sex" : false }
{ "_id" : 2, "age" : 22, "name" : "dowon2", "sex" : true }
{ "_id" : 3, "age" : 33, "name" : "dowon3", "sex" : false }

////////////////////////////////////////////////////////////////////////
// SECONDARY에서 데이터베이스를 READ해 보면 에러가 발생한다
// Replica Set의 Secondary는 Slave가 아니기 때문에 사용할 수 없다. 
// 즉, Primary가 down 되어야 사용 가능하다.
// 단, 1)의 Master/Slave 구조에서 Slave는 READ가 가능하다.
[dowon@localhost mongodb]$ ./mongo localhost:50000
MongoDB shell version: 2.2.2
connecting to: localhost:50000/test
dowon01:SECONDARY> show dbs  // 데이터베이스 보기 
local 0.125GB
peopleDB 0.0625GB
dowon01:SECONDARY> use peopleDB // 해당 데이터베이스로 switching하여 사용하기 
switched to db peopleDB
dowon01:SECONDARY> show collections // 해당 데이터베이스의 테이블(?) 보기 
Fri Jan  4 21:31:59 uncaught exception: error: { "$err" : "not master and slaveOk=false", "code" : 13435 }
dowon01:SECONDARY> db
peopleDB
dowon01:SECONDARY> db.people.find();  // "db"는 peopleDB를 가르키는 포인터
error: { "$err" : "not master and slaveOk=false", "code" : 13435 }


위 명령의 구조는 다음과 같다. (참조 19page)



  - Primary를 종료하면 Sencodary가 Primary로 자동 변경된다

[dowon@localhost mongodb]$ ./mongo localhost:40000

MongoDB shell version: 2.2.2

connecting to: localhost:40000/test

... 중략

dowon01:SECONDARY> show collections

Fri Jan  4 21:31:33 uncaught exception: error: { "$err" : "not master and slaveOk=false", "code" : 13435 }

dowon01:SECONDARY> 

// 30000 port mongoDB를 down시키고 4000 port의 mongo client에서 enter를 치면 하기와 같이 primary로 바뀐다. 

dowon01:PRIMARY> 

// Primary 이므로 CRUD가 가능해 진다. 

dowon01:PRIMARY> show collections
people
system.indexes
dowon01:PRIMARY> db.people.insert({_id:4, age:44, name:'youngsik', sex:true});
dowon01:PRIMARY> db.people.find();
{ "_id" : 1, "age" : 11, "name" : "dowon1", "sex" : false }
{ "_id" : 2, "age" : 22, "name" : "dowon2", "sex" : true }
{ "_id" : 3, "age" : 33, "name" : "dowon3", "sex" : false }
{ "_id" : 4, "age" : 44, "name" : "youngsik", "sex" : true }

/////////////////////////////////////////////////////////////////////
// 다시 30000 port를 기동시키고, 3000 port client로 접속한다.
// 40000 port가 그대로 Primary로 존재하고, 30000 port는 Secondary로 된다. 
i Jan  4 21:42:46 trying reconnect to localhost:30000
Fri Jan  4 21:42:46 reconnect localhost:30000 ok
dowon01:SECONDARY> 



3) Replca Set 기본과 Master/Slave를 결합한 형태

   * 참조 20page




< 참조 > 

- High Availabiltity & Replica Sets with mongoDB

http://www.slideshare.net/shaolintiger/high-availabiltity-replica-sets-with-mongodb


- Sharding by mongodb/10gen on Nov 28, 2012

http://www.slideshare.net/mongodb/sharding-15392976


- Sharding morning session

http://www.slideshare.net/mongodb/sharding-morning-session


- Sharding - Seoul 2012

http://www.slideshare.net/mongodb/sharding-seoul-2012-15576057


- Replication and Replica Sets

http://www.slideshare.net/mongodb/replication-and-replica-sets-tokyo-2012


- MongoDB Basic Concepts

http://www.slideshare.net/mongodb/mongodb-basic-concepts-15674838


- A Morning with MongoDB - Helsinki

http://www.slideshare.net/mongodb/morning-with-mongo-db-helsinki-1


- MongoDB Roadmap

http://www.slideshare.net/mongodb/next-15674517

posted by 윤영식