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

Publication

Category

Recent Post

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 윤영식
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 윤영식
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 윤영식
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 윤영식
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 윤영식