블로그 이미지
Peter Note
Web & LLM FullStacker, Application Architecter, KnowHow Dispenser and Bike Rider

Publication

Category

Recent Post

2013. 1. 8. 21:54 Testing, TDD/Test First

1) Clean Code를 만들기 위한 Unit Testing에 대한 이해


2) Test Driven Development(TDD)를 위한 Unit Testing

* 2)번 슬라이드중 TDD를 가장 잘 설명한 그림 : 설계->Test(Fail) -> 구현 -> Test(Success)



3) Unit Testing을 위한 가장 효과적인 방법들


4) 테스트를 위한 도구들에 대한 생각


* 4) 슬라이드에서 나온 도구 그림

posted by Peter Note
2013. 1. 8. 21:26 CI

이제 Maven에서 Gradle로 옮겨가자. Maven의 XML의 복잡함과 의존관계에 머리 좀 아팠다면 이제 Gradle로 옮겨서 Human Readable하게 생활하자. 


* 참조서적 : Building and Testing with Gradle


1) http://www.gradle.org/ 에서 설치 파일을 다운로드 받는다 

  - gradle-1.3-all,zip 파일

  - 특정 디렉토리에 풀어 놓는다 


2) Window라면 환경변수의 Path에 <gradle설치디렉토리>/bin을 잡아준다 (필수)



3) 역시 환경변수로 GRADLE_HOME=<gradle설치디렉토리> 를 잡아준다 (옵션)


4) build.gradle 파일을 만들어서 수행해 보자 

// build.gradle 파일 

task helloworld << {

  println 'hello dowon'

}

  - 수행 결과 


이제 Gradle로 시작해 보자. 

posted by Peter Note
2013. 1. 8. 20:42 Git, GitHub/Git Lec02

Git의 열거형 명령을 하나의 Alias로 지정할 수 있다. 설정 방법을 알아보자 


1) Alias 설정하기 : git config --global alias.[Alias명] '[명령]'

  - Ustage상태로 변경 : git config --global alias.unstage 'reset HEAD --' 로 설정하면 하기 명령은 동일하다 

    $ git unstage fileA

    $ git reset HEAD fileA 

  - last 명령 : git config --global alias.last 'log -l HEAD'

$ git config --global alias.last 'log -l HEAD'


$ git last

commit 329db048ff7af2d417588e28da50a6c53fb1bd84

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

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


    add content in build.gradle


commit f856853c5b0ac53483f9d14fe1b3ec6ef0fdbca7

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

Date:   Thu Dec 27 11:01:23 2012 +0900


    Update build.gradle


commit 03ca40a6026b9144f15cc8988ad6539049d36486

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

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


    Create build.gradle


2) 많이 사용하는 git alias : 참조사이트 

[alias]

git config --global alias.st status

git config --global alias.co checkout

git config --global alias.ci commit

git config --global alias.br branch

git config --global alias.unstage 'reset HEAD --'

git config --global alias.cs "commit -s"

git config --global alias.last 'log -1 HEAD'

git config --global alias.visual '!gitk'


* 현 브랜치의 히스토리를 short SHA값, author 정보, 커밋 트리 그리고 히스토리에서 특정 커밋을 가르키는 refs(브랜치, 태그)보기

  $ git config --global alias.lg "log --name-status --color --abbrev-commit --date=relative --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'"


  $ git lg 결과를 색깔별로 보여줌 


* 브랜치를 중심으로 히스토리를 보고 싶을 경우

  $ git config --global alias.tree "log --graph --decorate --pretty=oneline --abbrev-commit --all"

  또는 $ git config --global alias.lol 'log --oneline --graph --decorate'

  $ git tree 또는 git lol 수행 결과


* Visual 윈도우에서 변경 내역 보기 

  $ git config --global alias.visual '!gitk'

  $ git visual 을 수행하면 하기 화면이 뜬다 


<참조>

  - dogfeet alias 설정

  - 개발자 하루 alais 설정

  - 자료 : 민트기술

   Git-Guide-r1.pdf

posted by Peter Note
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 Peter Note
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 Peter Note
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 Peter Note
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 Peter Note
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 Peter Note
2012. 12. 29. 14:12 MongoDB/Concept

몽고디비설치를 하고 사용해보자. 설치전 몽고의 기본 개념을 읽고 시작하자


MongoDB는 웹 애플리케이션과 인터넷 기반을 위해 설계된 데이터베이스 관리 시스템이다. 데이터 모델과 지속성 전략은 높은 읽기/쓰기 효율과 자동 장애조치(failover)를 통한 확장의 용이성을 염두에 두고 만들어졌다. 애플리케이션에서 필요한 데이터베이스 노드가 하나거나 혹은 그 이상이거나에 관계없이 MongoDB는 놀라울 정도로 좋은 성능을 보여준다. 관계 데이터베이스를 확장하는 데 어려움을 겪었던 적이 있다면 이것은 대단한 뉴스일 것이다.



1. 설치후 4개파일 별도 디렉토리에 copy 

  + mongodb 폴더 안에 4개 파일 copy

  + mongo.exe : 쉘 / mongod.exe : 서버 / mongofiles.exe : gridFS 빅데이터 핸들링 / mongos.exe : 라우터 서버

[dowon@localhost mongodb]$ ls

bsondump      mongodump    mongooplog    mongosniff  THIRD-PARTY-NOTICES

GNU-AGPL-3.0  mongoexport  mongoperf     mongostat

mongo         mongofiles   mongorestore  mongotop

mongod        mongoimport  mongos        README

[dowon@localhost mongodb]$ pwd

/home/dowon/MongoDB/mongodb <- binary files 위치

[dowon@localhost mongodb]$ cd ..

[dowon@localhost MongoDB]$ pwd

/home/dowon/MongoDB

[dowon@localhost MongoDB]$ ls

db01  db02  db03  mongodb  <- 디렉토리들

[dowon@localhost MongoDB]$ 




2. 별도 디렉토리 만들고 서버 시작

  + mDB01, mDB02, mDB03 디렉토리를 만듦 : Replica Set을 만들 것이다. 

  + 서버 시작하기 

[dowon@localhost mongodb]$ ./mongod --dbpath /home/dowon/MongoDB/db01 &

[1] 5840

[dowon@localhost mongodb]$ Fri Dec 28 19:39:42 

Fri Dec 28 19:39:42 warning: 32-bit servers don't have journaling enabled by default. Please use --journal if you want durability.

Fri Dec 28 19:39:42 

Fri Dec 28 19:39:42 [initandlisten] MongoDB starting : pid=5840 port=27017 dbpath=/home/dowon/MongoDB/db01 32-bit host=localhost.localdomain

Fri Dec 28 19:39:42 [initandlisten] 

Fri Dec 28 19:39:42 [initandlisten] ** NOTE: when using MongoDB 32 bit, you are limited to about 2 gigabytes of data

Fri Dec 28 19:39:42 [initandlisten] **       see http://blog.mongodb.org/post/137788967/32-bit-limitations

Fri Dec 28 19:39:42 [initandlisten] **       with --journal, the limit is lower

Fri Dec 28 19:39:42 [initandlisten] 

Fri Dec 28 19:39:42 [initandlisten] db version v2.2.2, pdfile version 4.5

Fri Dec 28 19:39:42 [initandlisten] git version: d1b43b61a5308c4ad0679d34b262c5af9d664267

Fri Dec 28 19:39:42 [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 Dec 28 19:39:42 [initandlisten] options: { dbpath: "/home/dowon/MongoDB/db01" }

Fri Dec 28 19:39:42 [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 Dec 28 19:39:42 [websvr] admin web console waiting for connections on port 28017

Fri Dec 28 19:39:42 [initandlisten] waiting for connections on port 27017



3. 쉘사용하기 : JavaScript 코딩을 통하여 작업을 한다. 

   (명령뒤에 s 붙으면 목록이다, MongoDB는 자바스크립트 엔진인 extended Spidermonkey shell을 탑재함)

[dowon@localhost mongodb]$ ./mongo

MongoDB shell version: 2.2.2

connecting to: test

Fri Dec 28 19:45:29 [initandlisten] connection accepted from 127.0.0.1:44889 #2 (1 connection now open)

> 2+3

5

> 'hello dowon'

hello dowon

> var dowon = function() {

... return 'hi youngsik. what are you doing now?'

... }

> dowon()

hi youngsik. what are you doing now?


  - {} : 자바스크립 객체이다. anonymous function이고 일반 find() 시퀀스에 "어나너머스 자바스크립트 객체" = 클로저(Closure) 하나를 집어 넣은 것이다. 

> use peopleDB  // 데이터베이스 만들기

switched to db peopleDB

> db // db 명이 peopleDB를 referencing 한다

peopleDB

> show dbs

local (empty)

test (empty)

> db.people.save({age:37, name:'dowon', sex:'male'})  // collection (table) 만들기. JavaScript객체-JSON

Fri Dec 28 19:53:25 [FileAllocator] allocating new datafile /home/dowon/MongoDB/db01/peopleDB.ns, filling with zeroes...

Fri Dec 28 19:53:25 [FileAllocator] creating directory /home/dowon/MongoDB/db01/_tmp

Fri Dec 28 19:53:25 [FileAllocator] done allocating datafile /home/dowon/MongoDB/db01/peopleDB.ns, size: 16MB,  took 0.012 secs

Fri Dec 28 19:53:25 [FileAllocator] allocating new datafile /home/dowon/MongoDB/db01/peopleDB.0, filling with zeroes...

Fri Dec 28 19:53:25 [FileAllocator] done allocating datafile /home/dowon/MongoDB/db01/peopleDB.0, size: 16MB,  took 0.002 secs

Fri Dec 28 19:53:25 [FileAllocator] allocating new datafile /home/dowon/MongoDB/db01/peopleDB.1, filling with zeroes...

Fri Dec 28 19:53:25 [FileAllocator] done allocating datafile /home/dowon/MongoDB/db01/peopleDB.1, size: 32MB,  took 0.001 secs

Fri Dec 28 19:53:25 [conn2] build index peopleDB.people { _id: 1 }

Fri Dec 28 19:53:25 [conn2] build index done.  scanned 0 total records. 0 secs

Fri Dec 28 19:53:25 [conn2] insert peopleDB.people keyUpdates:0 locks(micros) w:201336 200ms

> show dbs  // collection을 만들때 즉, save 할때 데이터베이스가 생성된다 

local (empty)

peopleDB 0.0625GB

test (empty)

> show collections // collections (테이블)보기

people

system.indexes

> db.people.find()

{ "_id" : ObjectId("50de69359db888890e4126da"), "age" : 37, "name" : "dowon", "sex" : "male" }

> var person=[age:22]

Fri Dec 28 19:55:55 SyntaxError: missing ] after element list (shell):1

> var person={age:22};

> db.people.save(person) // 변수로 차기도 가능

> db.people.find()

{ "_id" : ObjectId("50de69359db888890e4126da"), "age" : 37, "name" : "dowon", "sex" : "male" }

{ "_id" : ObjectId("50de6a0e9db888890e4126db"), "age" : 22 }

> db.people.find({age:22})

{ "_id" : ObjectId("50de6a0e9db888890e4126db"), "age" : 22 }


  - index 넣고 확인하기 

1 : ascending

0 : descending 


> db.people.ensureIndex({age:1});

Fri Dec 28 20:17:20 [conn2] build index peopleDB.people { age: 1.0 }

Fri Dec 28 20:17:20 [conn2] build index done.  scanned 2 total records. 0.002 secs

> db.people.ensureIndex({name:0});

Fri Dec 28 20:17:26 [conn2] build index peopleDB.people { name: 0.0 }

Fri Dec 28 20:17:26 [conn2] build index done.  scanned 2 total records. 0.002 secs

> db.people.getIndexes();

[

{

"v" : 1,

"key" : {

"_id" : 1

},

"ns" : "peopleDB.people",

"name" : "_id_"

},

{

"v" : 1,

"key" : {

"age" : 1

},

"ns" : "peopleDB.people",

"name" : "age_1"

},

{

"v" : 1,

"key" : {

"name" : 0

},

"ns" : "peopleDB.people",

"name" : "name_0"

}

]


  - help 명령 보기 : 펑션이 이미 정의되어 있다

> db.people.help()

DBCollection help

db.people.find().help() - show DBCursor help

db.people.count()

db.people.copyTo(newColl) - duplicates collection by copying all documents to newColl; no indexes are copied.

db.people.convertToCapped(maxBytes) - calls {convertToCapped:'people', size:maxBytes}} command

db.people.dataSize()

db.people.distinct( key ) - e.g. db.people.distinct( 'x' )

db.people.drop() drop the collection

db.people.dropIndex(index) - e.g. db.people.dropIndex( "indexName" ) or db.people.dropIndex( { "indexKey" : 1 } )

db.people.dropIndexes()

db.people.ensureIndex(keypattern[,options]) - options is an object with these possible fields: name, unique, dropDups

db.people.reIndex()

db.people.find([query],[fields]) - query is an optional query filter. fields is optional set of fields to return.

                                             e.g. db.people.find( {x:77} , {name:1, x:1} )

db.people.find(...).count()

db.people.find(...).limit(n)

db.people.find(...).skip(n)

db.people.find(...).sort(...)

db.people.findOne([query])

db.people.findAndModify( { update : ... , remove : bool [, query: {}, sort: {}, 'new': false] } )

db.people.getDB() get DB object associated with collection

db.people.getIndexes()

db.people.group( { key : ..., initial: ..., reduce : ...[, cond: ...] } )

db.people.insert(obj)

db.people.mapReduce( mapFunction , reduceFunction , <optional params> )

db.people.remove(query)

db.people.renameCollection( newName , <dropTarget> ) renames the collection.

db.people.runCommand( name , <options> ) runs a db command with the given name where the first param is the collection name

db.people.save(obj)

db.people.stats()

db.people.storageSize() - includes free space allocated to this collection

db.people.totalIndexSize() - size in bytes of all the indexes

db.people.totalSize() - storage allocated for all data and indexes

db.people.update(query, object[, upsert_bool, multi_bool]) - instead of two flags, you can pass an object with fields: upsert, multi

db.people.validate( <full> ) - SLOW

db.people.getShardVersion() - only for use with sharding

db.people.getShardDistribution() - prints statistics about data distribution in the cluster

db.people.getSplitKeysForChunks( <maxChunkSize> ) - calculates split points over all chunks and returns splitter function


* MongoDB Tutorial 시작하기

posted by Peter Note
2012. 12. 29. 12:23 MongoDB/Concept

> MongoDB 아키텍쳐

- Replica Set : Fail-Over용 백업 Primary가 죽으면 Secondary가 primary가 됨 = Shard 1개를 의미한다. - auto fail-over 가 된다.

  primary와 secondary 각각 데이터 파일을 가지고 있다. secondary는 사용할 수 없다. primary만 서비싱

- MongoDB는 HTTP 즉 World Wid Web(WWW) 상의 모든 데이터를 연결시키는 것과 같다. 상상을 해보자 MongoDB는 웹상의 데이터가 합쳐지고  관리되어 지도록 만들었다는데 의미가 있다. 


- primary와 secondary 자체도 머신이 분리 될 수 있다. 당연히 shard 들도 머신 분리 될 수 있다. 

  Replica Set = Shard 이다 




- shard에 전체 데이터를 나누어 갖는다. mongos(몽고스)가 routing 한다. 즉, client는 mongos로 접속한다.

  * mongoos (몽구스)는 Node.js와 연결하는 driver이다. 

- replica, shard는 disk 서비스이다. memcached 같은 것은 memory 서비스이다. 



- 3개월에 한번씩 major version upgrade 

- 데이터베이스 = 중복되지 않는 데이터들의 집합체

- CAP 개념 : NoSQL의 CAP



> MongoDB 특징

  - Agile and Scalable : 신속하고 확장 가능한 개발을 위한 저장소

    + Agility : 실시간으로 변경된다. Schemeless 이다. 

    + Scalable : 무한 확장 가능하다.  

  - 무조건 64bit로 사용하여 무한 메모리를 사용할 수 있다. 메모리 관리는 OS가 하도록 한다. 32bit는 4G만 사용할 수 있다.

  - High Availability 

  - Auto Sharding 

  - Rich Query : human readerble & 인간의 뇌구조 key=value 즉, 문제=해결

  - Full Indexing 

  - Fast In-Place Update : CRUD 

  - Map/Reduce : version 2.2 의 핵심. MongoDB 자체가 M/R하던가 Hadoop으로 M/R를 주던가 한다. 결국은 Hadoop으로 간다.

    * 참조 : JayData

  - GridFS : BSon = binary json 형태로 저장.


* 10gen 기본개념 소개자료


posted by Peter Note
2012. 12. 29. 11:36 Backbone.js

View단위 MVC Framework으로 알려진 몇가지에 대해서 알아보자. MOVE solution으로 M=Model, O=Operation, VE=View 이다. 특히 View는 Logical DOM을 핸들링하게(Stream을 타고 즉, 동적으로 Storage지까지 가는 것이다. Stream=Function 이다.) 되고 MVC의 Controller 역할을 하게 된다. Operation은 단순 서비스/이벤트 역할이다. 대표적인 프레임워크가 BackBone이다. 

HTML -> Dynamic -> WebApp 그 정점에 SPA(Single Page Application)이 존재하고, 결국 최종 종착점은 고객에게 서비스하기 위한 View 기술이다. 여기에 필요한 전체 구조는 BackBone + Node.js + MongoDB 라고 보면되고, 이들은 Stream(Dynamic)하게 그러면서 Functional로 연력되어 Schemaless하게 움직이게 된다.



1) 전체 레밸의 MVC Framework

  - 브라우저 : BackBone.js

  - 서버 : Node.js위에서 구동되는 Express.js

  - 스토리지 : MongoDB위의 Mongoos 

* Node.js로 구성할 수 있는 Web App의 구성도



> BackBone.js 


> Ember.js


> Angular.js


3가지의 장단점에 대해서 검토해 보자 (다음번에 구체적으로 정리) O;TL

posted by Peter Note
2012. 12. 27. 17:31 Languages/Java

Java 클래스의 bytecode instrument 프레임워크인 ASM Guide 문서를 읽고 간단히 정리해 보자 


* 참조 파일


> Object Based Model

  - ASM 라이브러리는 컴파일된 클래스의 generating 과 transforming API를 제공한다.

  - DOM(예)의 경우 : event 기반 모델로 클래스를 이벤트 시퀀스로 표현한다. (Event Based Model)

  - ASM의 경우 : object 기반 모델로 클래스를 오브젝트 트리로 표현한다. (Object Based Model)

 

> 구성

  - asm.jar : class parster 와 writer  (core API)

  - asm-util.jar : 개발, 디버깅시에 사용 (core 의존)

  - asm-commons.jar : 미리 정의한 class 변환기 (core 의존)

  - asm-tree.jar : object 표현을 event 표현으로 변환

  - asm-analysis.jar : 미리 정의한 분석기와 분석 프레임워크 (tree 의존)


> Core API

  - class methods, annotations, generics에 대한 generate 과 transform을 Core API 활용하여 어떻게 하는지 알아본다

  - 컴파일된 클래스 구조(Structure) : 간단히 3가지로 나뉨

    + modifier 영역 : public, private

    + field 영역 : modifier, type이나 annotation of a field, name 선언

    + method, constructor 영역 : modifier, name, return, parameter type, annotation of a method

  - 컴파일 클래스와 소스의 차이

    + 소스는 여러 클래스를 포함한다 : inner class

    + 컴파일 클래스는 하나 클래스로 표현하고 comment 제거하고 package, import도 포함하지 않는다. 

    + 컴파일 클래스는 "constant pool"가 있다. constant pool은 배열(Array)이다. 한번만 생성이 도고 index로 참조되어 진다. 

      >>> 컴파일 클래스의 전체 구조

    


    + 컴파일 클래스는 타입표현 명명이 틀리다. internal name 은 클래스의 전체 이름을 사용한다. 

       java/lang/String같이 slash(/)로 구분한다.

    + Internal name은 type에도 적용된다. (type descriptor)

      >>> type descriptor 맵핑

     


    + method descriptor는 type descriptor의 목록이다.

      >>> 메소드 예

    


  - ClassVisitor 추상 클래스가 컴파일된 클래스의 생성/변환을 담당한다. AnnotationVisitor, FieldVisitor, MethodVisitor 리턴

   

  - FieldVisitor 추상 클래스 

   


  - Core API는 ClassVisitor API에 기반하여 클래스 generate 와 transform 할 수 있게 3가지 core 컴포넌트를 제공한다

    + ClassReader : byte array 주어진 컴파일된 클래스를 파싱한다. ClassVisitor를 accept 메소드 파라미터로 주면 

                            visitXxx 메소드를 호출한다 (event producer)

    + ClassWriter : ClassVisitor의 subclass이고 컴파일된 클래스를 바이너리로 만든다. toByteArray메소드롤 얻을 수 있는 

                            byte array로 결과물을 생산한다 (event consumer) 

    + ClassVisitor : 다른 ClassVisitor를 받으면 메소드 호출을 위임한다 (event filter)

posted by Peter Note
2012. 12. 27. 11:18 Git, GitHub/Git Lec02

GitHub에 만들어 놓은 저장소 관리를 알아보자. 


1) 리모트 저장소 확인하기 

// 프로젝트 복제 

$ git clone https://github.com/ysyun/pro_git.git

Cloning into 'pro_git'...

remote: Counting objects: 3, done.

remote: Total 3 (delta 0), reused 0 (delta 0)

Unpacking objects: 100% (3/3), done.


$ cd pro_git


$ git remote

origin


// 같은 프로젝트에 대해서 여러 기여자가 있을 수 있다. 

$ git remote -v  

origin  https://github.com/ysyun/pro_git.git (fetch)

origin  https://github.com/ysyun/pro_git.git (push)


2) 리모트 저장소 추가하기 : git remote add [단축이름] [url] 

$ git remote -v

dowon   $ (fetch)

dowon   $ (push)

origin  https://github.com/ysyun/pro_git.git (fetch)

origin  https://github.com/ysyun/pro_git.git (push)


// 기존 잘 못 설정된 내역 삭제

$ git remote rm dowon


$ git remote -v

origin  https://github.com/ysyun/pro_git.git (fetch)

origin  https://github.com/ysyun/pro_git.git (push)


// 새로운 remote alias 추가 

$ git remote add dowon  https://github.com/ysyun/pro_git.git


// 확인

$ git remote -v

dowon   https://github.com/ysyun/pro_git.git (fetch)

dowon   https://github.com/ysyun/pro_git.git (push)

origin  https://github.com/ysyun/pro_git.git (fetch)

origin  https://github.com/ysyun/pro_git.git (push)


// 리모트 저장소 이름 변경 

$ git remote rename dowon young


// 확인

$ git remote -v

origin  https://github.com/ysyun/pro_git.git (fetch)

origin  https://github.com/ysyun/pro_git.git (push)

young   https://github.com/ysyun/pro_git.git (fetch)

young   https://github.com/ysyun/pro_git.git (push)


3) 리모트 저장소를 Pull, Fetch 하기 : git fetch [remote-name] 

   - fetch : clone 이후 변경된 데이터를 모두 로컬로 가져온다. 그러나 자동 Merge는 하지 않는다. 수동 Merge해야 함

   - pull : 리모트 저장소 브랜치에서 데이터를 가져와서 현재 작업하는 로컬 브랜치와 Merge 한다. 

// fetch로 새로 추가한 build.gradle 파일 가져오기 fetch 수행

$ git fetch origin

From https://github.com/ysyun/pro_git

   49c657f..03ca40a  master     -> origin/master


// 못가져옴 

$ ls

README.md


// pull로 새로 추가한 build.gradle 파일 가져오기 fetch 수행

$ git pull origin

Updating 49c657f..03ca40a

Fast-forward

 build.gradle | 3 +++

 1 file changed, 3 insertions(+)

 create mode 100644 build.gradle


// 가져옴 

$ ls -alrt

total 5

drwxr-xr-x   13 yuwonsys Administ     4096 Dec 27 10:45 ..

-rw-r--r--    1 yuwonsys Administ       38 Dec 27 10:45 README.md

-rw-r--r--    1 yuwonsys Administ       37 Dec 27 10:58 build.gradle

drwxr-xr-x   14 yuwonsys Administ     4096 Dec 27 10:58 .git

drwxr-xr-x    5 yuwonsys Administ        0 Dec 27 10:58 .


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

// 내용확인

$ cat build.gradle

task gzip << {

  println "gzip"

}


// remote에서 build.gradle 내역 수정함 -> fetch로 가져오기 시도 

$ git fetch origin

remote: Counting objects: 5, done.

remote: Compressing objects: 100% (2/2), done.

remote: Total 3 (delta 0), reused 0 (delta 0)

Unpacking objects: 100% (3/3), done.

From https://github.com/ysyun/pro_git

   03ca40a..f856853  master     -> origin/master


// 변경 내역 파일 fetch 못함 

$ cat build.gradle

task gzip << {

  println "gzip"

}

// remote에서 build.gradle 내역 수정함 -> pull로 가져오기 시도 

$ git pull origin

Updating 03ca40a..f856853

Fast-forward

 build.gradle | 1 +

 1 file changed, 1 insertion(+)


// 변경 내역 파일 pull하여 가져왔음 

$ cat build.gradle

task gzip << {

  println "gzip"

  println "ok"

}


4) 리모트 저장소에 Push 하기 : git push [리모트 저장소 이름] [브랜치 이름]

// 맨 하단 내역을 로컬에서 추가한다 

$ cat build.gradle

task gzip << {

  println "gzip"

  println "ok"

  println "are you sure?"

}


// 상태를 확인해 보면 modified 상태이므로 Staging Area -> Git Directory로 이동해야 한다 

$ git status

# On branch master

# Changes not staged for commit:

#   (use "git add <file>..." to update what will be committed)

#   (use "git checkout -- <file>..." to discard changes in working directory)

#

#       modified:   build.gradle

#

no changes added to commit (use "git add" and/or "git commit -a")


// -a 옵션으로 Git Directory로 바로 commit 한다

$ git commit -a -m "add content in build.gradle"

[master 329db04] add content in build.gradle

 1 file changed, 1 insertion(+)


// commit 완료 확인

$ git status

# On branch master

# Your branch is ahead of 'origin/master' by 1 commit.

#

nothing to commit, working directory clean


// 변경 내역을 리모트의 master 브랜치로 push 한다 (github 사용시 ID/PWD 입력함)

$ git push origin master

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

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

Counting objects: 5, done.

Delta compression using up to 2 threads.

Compressing objects: 100% (3/3), done.

Writing objects: 100% (3/3), 345 bytes, done.

Total 3 (delta 0), reused 0 (delta 0)

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

   f856853..329db04  master -> master


5) 리모트 저장소 살펴보기 : git remote show [리모트 저장소 이름]

$ git remote show origin

* remote origin

  Fetch URL: https://github.com/ysyun/pro_git.git

  Push  URL: https://github.com/ysyun/pro_git.git

  HEAD branch: master

  Remote branch: // pull 하여 오는 리모트 브랜치 목록 보여줌

    master tracked

  Local branch configured for 'git pull': // Merge 브랜치를 알려줌

    master merges with remote master

  Local ref configured for 'git push':  // master 브랜치가 master 브랜치로 push 함 

    master pushes to master (up to date)


posted by Peter Note
2012. 12. 26. 17:53 CI/Jenkins, Travis

JavaScript로 짠 코드를 Gradle로 빌드해서 Jenkins로 자동화 하는 방법에 대해서 알아보자. 슬라이드에 JavaScript 에 대한 압축, 축소에 대해 Gradle Plugin 사용예가 존재한다. http://git.io/gradlejs 로 등록되어 있다.


> JavaScript + Jenkins에 대한 한글 자료


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

[Travis] GitHub과 Travis CI 연동하기  (0) 2013.08.14
[Jenkins] 설치후 Security 설정하기  (0) 2013.01.07
posted by Peter Note
2012. 12. 25. 23:55 Languages/Java

그루비도 Closure를 지원한다. 그렇다면 Closure에 대하여 알아보자. (좀 더 정리할 필요가 있겠음)


> 클로저의 가치

  - 함수 객체(function objects) 또는 익명 함수(anonymous function)로서 작용한다.

  - 유형 시스템(type system)이 데이터뿐만 아니라 코드도 나타낼 수 있어야 한다는 점에 유형 시스템에 대한 결과도 갖는다 (음 무슨 말인지 이해안감ㅜㅠ)

  - 함수들을 퍼스트-클래스 객체들로서 지원한다. 

  - 함수들은 변수에 저장될 수 있고, 매개변수로서 다른 함수에 저장된다.

  - 동적으로 생성되고, 함수들에서 리턴된다. 

  - 클러저는 Scheme, Common Lisp, Smalltalk, Groovy, JavaScript, Ruby, Python에서 찾아 볼 수 있다.


<참조>

  - 클로저 논의 IBM 번역

  - JavaScript에서의 클로저

posted by Peter Note
2012. 12. 25. 23:33 Languages/Java

IntelliJ IDE 에서 그루비를 실행하고 테스트해보자. 우선 Eclipse에서 어떻게 수행되는지 동영상을 보고 따라해 보도록 한다. 


> 이클립스에서 그루비 실행하기 

  - 그루비 한글번역 튜토리얼

  - IntelliJ IDE에서 JUnit 4 테스트를 생성하고 구동시키는 방법 



> IntelliJ IDE에서 그루비 생성하고 클래스 테스트하기 


위의 eclipse 기준 동영상을 IntelliJ IDE에 맞추어 테스트 해본다 

1) 새로운 프로젝트 생성

  - New Project 생성

  - step-01 : Java Module 선택


  - step-02 : src 디렉토리 선택

  - step-03 : Groovy 선택 (사전에 Groovy는 설치되어 있어야 한다)


2) 그루비 테스트 하기  

// collection & closure

def coll = ["groovy", "java", "ruby"]  // javascript처럼 컬렉션을 만들 수 있다

assert  coll instanceof Collection // assert 결과가 true이면 다음 문장으로 계속 수행함 

assert coll instanceof ArrayList

println coll.class

println coll


coll << "perl"  // 추가하기 


println coll


coll[4] = 'python'  // 배열처럼 직접 삽입

println coll


println coll - ['java'] // 값 빼기 


// closure 1

coll.each{  value ->    // 파라미터 명을 value로 설정함 

    println '> ' + value

}

// closure 2

def excite = { word ->

    return "${word}!!"

}

assert 'Dowon!!' == excite('Dowon')

println excite('Dowon')


// key=value의 map 객체를 만듦 

def hash = [name:'yun', 'age':27]

assert hash.getClass() == java.util.LinkedHashMap

println hash


hash.height = 177   // key=value 추가하기 

println hash


hash.put('height', 190)  // put 이용

println hash


3) Song 클래스 만들기

// set, get 메소드가 자동으로 만들어 진다. 

// getGenre() 메소드를 재정의한다

class Song {

    def name

    def artist

    def genre


    String toString() {

        "${name}, ${artist}, ${getGenre()}"

    }


    def getGenre() {

        genre.toUpperCase()

    }

}


4) SongExample로 Song 클래스 수행 : ctrl + shift + F10 으로 수행한다 

class SongExample {

    static void main(args) {

       // 생성자는 그루비가 자동으로 생성해 준다 

        Song sng = new Song(name: "tear's heaven", artist: "singer", genre: "rock")

        sng.name = "hi"

        sng.setArtist("dowon")   // set, get 메소드가 이미 있으므로 호출 가능하다 

        println sng


        Song sng2 = new Song()

        // name 지정을 하지 않았으므로 null이다. ?를 하면 null safety 체크한다  

        // 즉 name 이 null 이면 toUpperCase() 를 수행하지 않는다 

        println sng2.name?.toUpperCase()  

    }

}


5)  테스트 코드를 작성한다 : java의 junit 코드로 짜된다 어차피 그루비도 수행시 컴파일 되면 java와 같이 bytecode로 변경된다

  - ctrl + shift + t 클릭하면 "Create New Test..." 메뉴를 선택한다
   


  - JUnit4를 선택하고 OK 클릭한다
   


  - Test 코드를 작성한다 : Groovy 스타일 Test 케이스를 만들 수도 있고, Java 스타일 Test 케이스도 가능하다 (Bi-direction)

import junit.framework.Assert;
import junit.framework.TestCase;
import org.junit.Test;

public class SongTest  {
    @Test
    public void testToString() {
        Song song = new Song();
        song.setName("Smells like teen spirits");
        song.setArtist("youngsik");
        song.setGenre("hard rock");

        Assert.assertEquals("Smells like teen spirits, youngsik, HARD ROCK", song.toString());
    }
}


'Languages > Java' 카테고리의 다른 글

[ASM4] Core API - 01  (0) 2012.12.27
[Groovy] Closure 지원하는 그루비  (0) 2012.12.25
[Groovy] Domain Specific Language 배우기  (0) 2012.12.25
[JVM] Java란 무엇인가?  (0) 2012.11.21
[BeanShell] 설치하고 사용하기  (0) 2012.10.26
posted by Peter Note
2012. 12. 25. 02:04 Languages/Java

Groovy를 통해 많은 생태계가 만들어지고 있다. 그중 Gradle이라는 Build Automation 툴을 사용하려 한다. Groovy의 생태계와 DSL에 대해 알아보자 


> Groovy가 만들고 있는 생태계

  • Grails와 같은 Framework 에 사용
  • Easyb(BDD)와 같은 Testing 에 사용
  • Gradle 과 같은 Build Automation Tool 에 사용
  • 기타등등

> Groovy 기본 개념과 DSL 그리고 생태계

  • Groovy는 Dynamic 언어 (2003년 시작)
  • SpringSource, JBoss 등 많은 오픈소스진영에서 사용중
  • Fully Object-Oriented, Closures, Properties, Optional typing, wrapper APIs, authoring DSLs, lively ecosystem


> Groovy DSL 배우기 


posted by Peter Note
2012. 12. 24. 11:39 Git, GitHub/Git Lec02

Git 저장소를 만들고 Working Directory, Staging Area, Git Directory를 오가는 명령을 알아보자.


> Git 저장소 만들기 

  • 프로젝트 디렉토리를 만든다
  • 프로젝트 디렉토리로 이동한다
  • git init 명령을 수행하면 .git 디렉토리가 생긴다 (git 뼈대)
  • 버전관리를 시작할려면 git add -> git commit 을 하여 파일을 저장소에 추가해야 시작된다.

$ mkdir pro_git


$ cd pro_git


$ git init

Initialized empty Git repository in d:/git-repositories/pro_git/.git/


$ ls -alrt

total 4

drwxr-xr-x   13 yuwonsys Administ     4096 Dec 24 11:01 ..

drwxr-xr-x    9 yuwonsys Administ     4096 Dec 24 11:01 .git

drwxr-xr-x    3 yuwonsys Administ        0 Dec 24 11:01 .


$ touch README.md


$ git add README.md

$ git commit -a -m "add readme.md file"

[master (root-commit) 3b7d2a8] add readme.md file

 0 files changed

 create mode 100644 README.md



> Git 복제 

  • git clone <url>


> 파일 수정하고 저장소에 저장하기 

  • Tracked(관리대상)와 Untracked(비관리대상) 으로 나뉜다. 즉 한번이라도 commit 되면 관리대상이 된다.
  • Tracked는 Unmodified(수정하지 않음)와 Modified(수정함) 그리고 Staged(커밋전) 상태 중 하나이다.
  • Clone을 하게 되면 모든 파일은 Tracked이면서 Unmodified 상태이다. 또한 자동으로 자동 Checkout도 한다.

untracked <-> unmodified <-> modified <-> staged <-> commited


  • git status : 파일 상태의 확인 tracked와 modified 상태파일이 없거나, Untracked 파일이 있는지 보여준다
// tracked이면서 modified 상태 파일이 없음 표시
$ git status
# On branch master
nothing to commit, working directory clean

// Untracked 파일 추가 
$ touch aa.txt

// Untracked 파일 목록을 보여줌 
$ git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       aa.txt
nothing added to commit but untracked files present (use "git add" to track)

// tracked 파일인 README.md 파일에 내용을 입력함
$ vi README.md

// Tracked 파일과 Untracked 파일 목록을 보여줌 
$ git status
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   README.md
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       aa.txt
no changes added to commit (use "git add" and/or "git commit -a")
  • git add <파일명 또는 디렉토리경로명> : Tracked 상태로 만들면서 Staged 상태가 된다 
// aa.txt 파일을 add 하여 tracked+staged 상태로 변경함 
$ git add aa.txt

$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   aa.txt
#
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   README.md
#
  • Modified 상태의 파일을 Stage 하기 

// 수정하여서  Changes not staged for commit: 으로 표현된 README.md파일을 Staged 상태로 변경하기 

$ git add README.md


$ git status

# On branch master

# Changes to be committed:

#   (use "git reset HEAD <file>..." to unstage)

#

#       modified:   README.md

#       new file:   aa.txt

#

  • Stage 된 파일을 다시 Modified 하였을 경우 

// 이미 Staged 상태인것을 다시 수정한다

$ vi README.md


// 상태를 확인해 보면 README.md 파일이 Staged 에도 존재하고 modified 상태에도 존재한다.

// 만일 commit을 하게 되면 Staged 상태의 READM.md파일이 커밋된다. 

// 다시 git add README.md를 해준다

$ git status

# On branch master

# Changes to be committed:

#   (use "git reset HEAD <file>..." to unstage)

#

#       modified:   README.md

#       new file:   aa.txt

#

# Changes not staged for commit:

#   (use "git add <file>..." to update what will be committed)

#   (use "git checkout -- <file>..." to discard changes in working directory)

#

#       modified:   README.md

#


// modified 상태의 파일을 staged 상태로 변경한다 

$ git add README.md


// 다시 상태 확인 

$ git status

# On branch master

# Changes to be committed:

#   (use "git reset HEAD <file>..." to unstage)

#

#       modified:   README.md

#       new file:   aa.txt

#

  • .gitignore : Untracked 파일을 git 목록에서 제거하기 (로그파일, 빌드환경파일, 프로젝트파일등 무시하고자 하는 것을 명시한다)
    • 아무것도 없는 줄이나 # 시작하는 줄 무시
    • 표준 Glob 패턴 사용 (Glob패턴은 정규표현식을 단순하게 만든 것으로 보통 쉘에서 사용)
      • * : 문자가 하나도 없거나 하나 이상을 의미 
      • [abc] : 중괄호 안에 있는 문자중 하나를 의미
      • ? : 문자 하나를 의미
      • [0-9] : 하이픈을 사용하면 그 캐릭터 사이의 문자 하나를 의미
    • 디렉토리는 슬래쉬(/)를 끝에 사용
    • 느낌표(!)로 시작하는 패턴은 해당 패턴의 파일 무시

# comment

*.a  # 확장자 .a 인 파일 무시

!lib.a # lib.a 파일은 무시하지 않음

/TODO # 루트 디렉토리에 있는 TODO 파일 무시

build/  # build/ 디렉토리 모든 파일 무시

doc/*.txt # doc/*.txt는 무시 그러나 doc/another/*.txt 파일은 무시하지 않음

  • git diff : Staged와 Unstaged 상태의 변경 내용을 보기 (git status 는 단순 상태 정보만을 보여주지만 git diff는 변경 내용을 볼 수 있다)
// aa.txt 파일안에 test라고 내용을 입력한다 
$ vi aa.txt

// working directory의 modified상태와 staging area의 staged 상태의 내역 차이를 비교하고 내용을 보여준다
// 즉 staged 상태가 아닌 파일을 비교해 볼 수 있다. (즉, Ustaged 상태인 것들만 보여준다)
$ git diff
diff --git a/aa.txt b/aa.txt
index e69de29..9daeafb 100644
--- a/aa.txt
+++ b/aa.txt
@@ -0,0 +1 @@
+test

// git diff --cached : staged 와 git directory간의 변경내역을 보고 싶을 경우 
// Staging Area 와 저장소에 커밋한 것을 비교해 볼 수 있다. (즉, Staged 상태인 것들만 보여준다)
$ git diff --cached
diff --git a/README.md b/README.md
index e69de29..47086e9 100644
--- a/README.md
+++ b/README.md
@@ -0,0 +1,2 @@
+hi pro git
+by dowon
diff --git a/aa.txt b/aa.txt
new file mode 100644
index 0000000..e69de29
  • git commit <fileName option> -m <message> : Staging Area 파일을 정일한다. 즉, Staged 파일만 해당 된다. git add 하지 않은 파일은 Modified 상태로 남음.

// master 브랜치에 커밋했고, 체크섬은 9160d86 이라는 의미

$ git commit aa.txt -m "add test file"

[master 9160d86] add test file

 1 file changed, 1 insertion(+)

 create mode 100644 aa.txt

  • git commit -a -m <메세지> : Staging Area 생략하고 commit 하기. 

// 내용 수정

$ vi README.md


// 현재 상태 : modified 상태가 있지만 Staging Area를 거치지 앟고 바로 Git Direcotry (로컬 저장소)로 보내고 싶을 경우 

$ git status

# On branch master

# Changes to be committed:

#   (use "git reset HEAD <file>..." to unstage)

#

#       modified:   README.md

#

# Changes not staged for commit:

#   (use "git add <file>..." to update what will be committed)

#   (use "git checkout -- <file>..." to discard changes in working directory)

#

#       modified:   README.md

#


// -a 옵션 사용 단, 파일은 최소 1회 이상 commit 이 된 것이어야 한다 

// master 브랜치에 6efd594 체크섬으로 commit 되었음

$ git commit -a -m "modified README.md"

[master 6efd594] modified README.md

 1 file changed, 2 insertions(+)


// commit 이 되었음 

$ git status

# On branch master

nothing to commit, working directory clean

  • git rm <파일> : 삭제된 파일은 Staging 상태가 된다. 다시 commit을 하면 삭제가 된다. (삭제확인을 위한 장치). 만일 Staging Area에서 포함되지 않게 제거하는 것은 git rm --cached를 사용한다.
// 파일을 삭제한다 
$ git rm aa.txt
rm 'aa.txt'

// 삭제된 파일이 Staging Area에 Deleted 상태로 있음을 알려준다 
$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       deleted:    aa.txt
#

// commit 하여 Staging Area에 있는 Deleted 상태의 파일을 제거한다 
$ git commit -m "delete aa.txt"
[master b5da470] delete aa.txt
 1 file changed, 1 deletion(-)
 delete mode 100644 aa.txt

// aa.txt 파일이 제거되었다. 
$ git status
# On branch master
nothing to commit, working directory clean
  • git mv <from파일> <to파일> : 파일 이름 변경하기를 하면 Staging Area에 Renamed 상태로 된다.
// 이름을 변경(옮긴다)
$ git mv README.md README

// Staging Area에 Renamed 상태
$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       renamed:    README.md -> README
#
  • git log : 커밋 히스토리 보기. 가장 최근 커밋이 가장 먼저 나온다. -p 옵션은 커밋의 diff 결과를 보여준다. -2 는 두개의 결과만 보여준다. -p 옵션은 diff이기 때문에 동료의 변경 내용을 빠르게 확인 할 수 있다. --stat 각 커밋의 통계 정보를 보여줌. --pretty는 사용자 정의가능 (oneline, short, full, fuller, format 옵션 예, --pretty=oneline). --graph는 브랜치 그래프를 보여줌
// -p 변경 내역을 포함하고 -2  최근 2개만 보여줌 
$ git log -p -2
commit b5da4702608e2980a38d51416af79a35b7fcd904
Author: Yun DoWon <ysyun@yuwin.co.kr>
Date:   Mon Dec 24 14:01:50 2012 +0900

    delete aa.txt

diff --git a/aa.txt b/aa.txt
deleted file mode 100644
index 9daeafb..0000000
--- a/aa.txt
+++ /dev/null
@@ -1 +0,0 @@
-test

commit 6efd594f461e0e71d655efab90cf2341f8d9e290
Author: Yun DoWon <ysyun@yuwin.co.kr>
Date:   Mon Dec 24 13:54:48 2012 +0900

    modified README.md

diff --git a/README.md b/README.md
index e69de29..00ed50f 100644
--- a/README.md
+++ b/README.md
@@ -0,0 +1,2 @@
+hi pro git
+by dowon yun

// 통계 정보를 보여줌 
$ git log --stat
commit b5da4702608e2980a38d51416af79a35b7fcd904
Author: Yun DoWon <ysyun@yuwin.co.kr>
Date:   Mon Dec 24 14:01:50 2012 +0900

    delete aa.txt

 aa.txt | 1 -
 1 file changed, 1 deletion(-)

commit 6efd594f461e0e71d655efab90cf2341f8d9e290
Author: Yun DoWon <ysyun@yuwin.co.kr>
Date:   Mon Dec 24 13:54:48 2012 +0900

    modified README.md

 README.md | 2 ++
 1 file changed, 2 insertions(+)

commit 9160d863411cd3ef7c7977bff6d405ad41608b58
Author: Yun DoWon <ysyun@yuwin.co.kr>
Date:   Mon Dec 24 13:48:06 2012 +0900

    add test file

 aa.txt | 1 +
 1 file changed, 1 insertion(+)

commit 3b7d2a8903cd5b02344ce89b3ff4386ff3f3a038
Author: Yun DoWon <ysyun@yuwin.co.kr>
Date:   Mon Dec 24 11:04:33 2012 +0900

    add readme.md file

 0 files changed

// 한줄로 보여주기 : 내용을 많을 경우 유용함 
$ git log --pretty=oneline
b5da4702608e2980a38d51416af79a35b7fcd904 delete aa.txt
6efd594f461e0e71d655efab90cf2341f8d9e290 modified README.md
9160d863411cd3ef7c7977bff6d405ad41608b58 add test file
3b7d2a8903cd5b02344ce89b3ff4386ff3f3a038 add readme.md file

// format 형식을 준다 
$ git log --pretty=format:"%h -%an, %ar : %s"
b5da470 -Yun DoWon, 15 minutes ago : delete aa.txt
6efd594 -Yun DoWon, 22 minutes ago : modified README.md
9160d86 -Yun DoWon, 29 minutes ago : add test file
3b7d2a8 -Yun DoWon, 3 hours ago : add readme.md file

// 브랜치 히스토리까지 본다 
$ git log --pretty=format:"%h %s" --graph
* b5da470 delete aa.txt
* 6efd594 modified README.md
* 9160d86 add test file
* 3b7d2a8 add readme.md file
* format 옵션 내역

Option Description of Output

%H Commit hash

%h Abbreviated commit hash

%T Tree hash

%t Abbreviated tree hash

%P Parent hashes

%p Abbreviated parent hashes

%an Author name

%ae Author e-mail

%ad Author date (format respects the –date= option)

%ar Author date, relative

%cn Committer name

%ce Committer email

%cd Committer date

%cr Committer date, relative

$s  Subject


* git log 옵션들

--since --after : 명시한 날짜 이후의 커밋만 검색. 예)git log --since=2.weeks : 2주 동안 만들어진 커심들만 조회

--until, --before : 명시한 날짜 이전의 커밋만 검색 

--author : 저자를 지정할 수 있다. 

--committer : 입력한 커밋터의 커밋만 조회 

--grep : 커밋 메세지에서 키워드를 검색

-- <path1> <path2> : 해당 경로 밑의 커밋 히스토리를 조회 


// commit hash와 subject만을 보여주고 저작자 Yun DoWon 이라는 사람의 23이전 커밋 내역 검색

$ git log --pretty="%h - %s" --author="Yun DoWon" --since="2012-12-23"

b5da470 - delete aa.txt

6efd594 - modified README.md

9160d86 - add test file

3b7d2a8 - add readme.md file


'Git, GitHub > Git Lec02' 카테고리의 다른 글

[Pro Git] Git Alias 사용하기  (0) 2013.01.08
[Pro Git] Tag 사용하기  (0) 2013.01.08
[Pro Git] 리모트 저장소 관리하기  (0) 2012.12.27
[Pro Git] Git 설치와 최초 설정하기  (0) 2012.12.24
[Pro Git] DVCS역사  (0) 2012.12.24
posted by Peter Note
2012. 12. 24. 10:49 Git, GitHub/Git Lec02

Git 설치에 대해 간단히 알아보고, 설정하는 방법에 대하여 알아보자 


> Git 설치

  • Git은 curl, zlib, openssl, expat, libiconv를 필요로 한다 
// Fedora yum 이용
$ yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel
$ yum install git-core

// 데비안 apt-get 이용
$ apt-get install libcurl4-gnutls-dev libexpat1-dev gettext libz-dev libssl-dev
$ apt-get install git-core
// 윈도우 설치
http://code.google.com/p/msysgit  다운로드하여 설치한다

$ tar -zxf git-1.8.1.tar.gz

$ cd git-1.7.2.2
$ make prefix=/usr/local all
$ sudo make prefix=/usr/local install
  • Git이 이미 설치되었다면 최신버전 소스를 다음과 같이 받을 수 있다. 

git clone https://github.com/git/git.git



> Git 환경파일

  • /etc/gitconfig : 시스템의 모든 사용자와 모든 저장소에 적용되는 설정. git config --system 옵션으로 RW 가능.
  • ~/.gitconfig : 특정 사용자에게만 적용(윈도우는 USER 밑에 존재) git config --global 옵션으로 RW 가능.
  • .git/config : Git Directory(Local Repsoitory)의 현재 작업중인 프로젝트에만 적용. 우선순위 가장 높음.

// user 밑의 .gitconfig 파일 내역 

[user]

name = Yun DoWon

email = ysyun@yuwin.co.kr

[http]

postbuffer = 524288000

[push]

default = upstream

[core]

autocrlf = true

[color]

ui = auto


// 현재 프로젝트의 .git/config 파일 내역 

[core]

repositoryformatversion = 0

filemode = false

bare = false

logallrefupdates = true

symlinks = false

ignorecase = true

hideDotFiles = dotGitOnly

[remote "origin"]

url = https://github.com/ysyun/jmqtt_client.git

fetch = +refs/heads/*:refs/remotes/origin/*

[branch "master"]

remote = origin

merge = refs/heads/master


// 전체 설정 내역 보기 : git config {key} 명령으로 특정 Key에 대한 값 확인 (Help 명령: git help config)

$ git config --list

core.symlinks=false

core.autocrlf=true

color.diff=auto

color.status=auto

color.branch=auto

color.interactive=true

pack.packsizelimit=2g

help.format=html

http.sslcainfo=/bin/curl-ca-bundle.crt

sendemail.smtpserver=/bin/msmtp.exe

diff.astextplain.textconv=astextplain

rebase.autosquash=true

user.name=Yun DoWon

user.email=ysyun@yuwin.co.kr

http.postbuffer=524288000

push.default=upstream

core.autocrlf=true

color.ui=auto

core.repositoryformatversion=0

core.filemode=false

core.bare=false

core.logallrefupdates=true

core.symlinks=false

core.ignorecase=true

core.hidedotfiles=dotGitOnly

remote.origin.url=https://github.com/ysyun/jmqtt_client.git

remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*

branch.master.remote=origin

branch.master.merge=refs/heads/master


posted by Peter Note
2012. 12. 24. 10:00 Git, GitHub/Git Lec02

Pro Git에 대한 번역본을 보면서 공부한 내용을 정리한다. 


> 버전 관리 형태 

  • VCS : 초창기 로컬 버전 컨트롤 시스템으로 시작
  • CVCS : 중앙 버전 컨트롤 시스템 (단점 : 중앙 저장소 장애시 모든 개발자 접속 불가. 예: SVN, CVS)
  • DVCS : 분산 버전 컨트롤 시스템 (장점 : CVCS 단점 극복, 중앙 저장소를 그대로 로컬에 복제하여 사용함. 예:  Git)


> Git 역사

  • 리눅스 초창기 개발에서 쓰던 BitKeeper DVCS가 상용화 요구하면서 개발됨
  • 빠른 속도, 단순한 구조, 동시 다발적 브랜치(비선형적 개발), 완벽한 분산, 대형 프로젝트에도 적함(속도, 크기면에서도) 요건 충족토록 개발시작
  • 2005년 탄생

> Git 특성

  • Git 데이터는 파일 시스템의 SnapShot 으로 크기가 작다. 파일 변경이 없으면 버져닝시 이전 파일의 링크만 저장한다.
  • 거의 모든 명령은 로컬에서 수행된다. (CVCS는 네트워크 속도에 영향을 받는다) 오프라인 상태에서도 작업이 가능하다.
  • 데이터 무결성을 위해 모든 데이터 저장전 체크섬(Checksum 또는 Hash)을 구하여 관리한다. SHA01 Hash를 사용하여 체크섬을 만든다. (길이 40자 16진수 문자열)
  • 로컬에 3 단계로 나뉜다 : Working Directory (Modified) - Staging Area (Staged) - Git Directory(Local Repository, Commited)
    • Working Directory : 특정 버전을 Checkout 한 것이다. Git Directory에 압축된 데이터베이스 파일을 가져와 만든다
    • Staging Area : Git Directory에 있고, 단순 파일이고 곧 Commit 할 파일에 대한 정보이다. 종종 인덱스라고 불림.
    • Git Directory : 프로젝트의 메타데이터와 객체 데이터베이스를 저장하는 곳이다. Git의 핵심이다. 


posted by Peter Note