[파이썬] scrapy 로 웹 사이트 크롤링

[출처] http://isbullsh.it/2012/04/Web-crawling-with-scrapy/

Crawl a website with scrapy

Written by Balthazar

Introduction

In this article, we are going to see how to scrape information from a website, in particular, from all pages with a common URL pattern. We will see how to do that with Scrapy, a very powerful, and yet simple, scraping and web-crawling framework.

For example, you might be interested in scraping information about each article of a blog, and store it information in a database. To achieve such a thing, we will see how to implement a simple spider using Scrapy, which will crawl the blog and store the extracted data into a MongoDB database.

We will consider that you have a working MongoDB server, and that you have installed the pymongo and scrapy python packages, both installable with pip.

If you have never toyed around with Scrapy, you should first read this short tutorial.

First step, identify the URL pattern(s)

In this example, we’ll see how to extract the following information from each isbullsh.it blogpost :

  • title
  • author
  • tag
  • release date
  • url

We’re lucky, all posts have the same URL pattern: http://isbullsh.it/YYYY/MM/title. These links can be found in the different pages of the site homepage.

What we need is a spider which will follow all links following this pattern, scrape the required information from the target webpage, validate the data integrity, and populate a MongoDB collection.

Building the spider

We create a Scrapy project, following the instructions from their tutorial. We obtain the following project structure:

isbullshit_scraping/
├── isbullshit
│   ├── __init__.py
│   ├── items.py
│   ├── pipelines.py
│   ├── settings.py
│   └── spiders
│       ├── __init__.py
│       ├── isbullshit_spiders.py
└── scrapy.cfg

We begin by defining, in items.py, the item structure which will contain the extracted information:

from scrapy.item import Item, Field

class IsBullshitItem(Item):
    title = Field()
    author = Field()
    tag = Field()
    date = Field()
    link = Field()

Now, let’s implement our spider, in isbullshit_spiders.py:

from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
from scrapy.selector import HtmlXPathSelector
from isbullshit.items import IsBullshitItem

class IsBullshitSpider(CrawlSpider):
    name = 'isbullshit'
    start_urls = ['http://isbullsh.it'] # urls from which the spider will start crawling
    rules = [Rule(SgmlLinkExtractor(allow=[r'page/\d+']), follow=True), 
    	# r'page/\d+' : regular expression for http://isbullsh.it/page/X URLs
    	Rule(SgmlLinkExtractor(allow=[r'\d{4}/\d{2}/\w+']), callback='parse_blogpost')]
    	# r'\d{4}/\d{2}/\w+' : regular expression for http://isbullsh.it/YYYY/MM/title URLs
    		
    def parse_blogpost(self, response):
        ...

Our spider inherits from CrawlSpider, which “provides a convenient mechanism for following links by defining a set of rules”. More info here.

We then define two simple rules:

  • Follow links pointing to http://isbullsh.it/page/X
  • Extract information from pages defined by a URL of pattern http://isbullsh.it/YYYY/MM/title, using the callback method parse_blogpost.

Extracting the data

To extract the title, author, etc, from the HTML code, we’ll use the scrapy.selector.HtmlXPathSelector object, which uses the libxml2 HTML parser. If you’re not familiar with this object, you should read the XPathSelector documentation.

We’ll now define the extraction logic in the parse_blogpost method (I’ll only define it for the title and tag(s), it’s pretty much always the same logic):

def parse_blogpost(self, response):
    hxs = HtmlXPathSelector(response)
    item = IsBullshitItem()
    # Extract title
    item['title'] = hxs.select('//header/h1/text()').extract() # XPath selector for title
    # Extract author
    item['tag'] = hxs.select("//header/div[@class='post-data']/p/a/text()").extract() # Xpath selector for tag(s)
    ...
    return item

Note: To be sure of the XPath selectors you define, I’d advise you to use Firebug, Firefox Inspect, or equivalent, to inspect the HTML code of a page, and then test the selector in a Scrapy shell. That only works if the data position is coherent throughout all the pages you crawl.

Store the results in MongoDB

Each time that the parse_blogspot method returns an item, we want it to be sent to a pipeline which will validate the data, and store everything in our Mongo collection.

First, we need to add a couple of things to settings.py:

ITEM_PIPELINES = ['isbullshit.pipelines.MongoDBPipeline',]

MONGODB_SERVER = "localhost"
MONGODB_PORT = 27017
MONGODB_DB = "isbullshit"
MONGODB_COLLECTION = "blogposts"

Now that we’ve defined our pipeline, our MongoDB database and collection, we’re just left with the pipeline implementation. We just want to be sure that we do not have any missing data (ex: a blogpost without a title, author, etc).

Here is our pipelines.py file :

import pymongo

from scrapy.exceptions import DropItem
from scrapy.conf import settings
from scrapy import log
class MongoDBPipeline(object):
    def __init__(self):
        connection = pymongo.Connection(settings['MONGODB_SERVER'], settings['MONGODB_PORT'])
        db = connection[settings['MONGODB_DB']]
        self.collection = db[settings['MONGODB_COLLECTION']]
        
    def process_item(self, item, spider):
    	valid = True
        for data in item:
          # here we only check if the data is not null
          # but we could do any crazy validation we want
       	  if not data:
            valid = False
            raise DropItem("Missing %s of blogpost from %s" %(data, item['url']))
        if valid:
          self.collection.insert(dict(item))
          log.msg("Item wrote to MongoDB database %s/%s" %
                  (settings['MONGODB_DB'], settings['MONGODB_COLLECTION']),
                  level=log.DEBUG, spider=spider) 
        return item

Release the spider!

Now, all we have to do is change directory to the root of our project and execute

$ scrapy crawl isbullshit

The spider will then follow all links pointing to a blogpost, retrieve the post title, author name, date, etc, validate the extracted data, and store all that in a MongoDB collection if validation went well.

Pretty neat, hm?

Conclusion

This case is pretty simplistic: all URLs have a similar pattern and all links are hard written in the HTML code: there is no JS involved. In the case were the links you want to reach are generated by JS, you’d probably want to check out Selenium. You could complexify the spider by adding new rules, or more complicated regular expressions, but I just wanted to demo how Scrapy worked, not getting into crazy regex explanations.

Also, be aware that sometimes, there’s a thin line bewteen playing with web-scraping and getting into trouble.

Finally, when toying with web-crawling, keep in mind that you might just flood the server with requests, which can sometimes get you IP-blocked :)

Please, don’t be a d*ick.

See code on Github

The entire code of this project is hosted on Github. Help yourselves!

델파이 프로그래밍 소스 사이트(유용한 델파이 사이트)

[출처] http://aptinfo.tistory.com/80

유용한 델파이 사이트

Posted at 2009/12/24 16:20// Posted in 개발자 인생/프로그래밍 팁



델마당 : http://www.delmadnag.com

http://delphiforfun.org/

많은 델파이 예제를 다루고 있으며, 상당히 어려운 부분에 대해서도 기술하고 있습니다.

문제는 영어로 된 사이트라는 것이지만,

프로그램과 소스가 있어서, 델파이 코드를 뒤져볼 수 있으면 짧은 영어에도 많은 것을 배울 수 있습니다.

http://www.cobans.net/

RPN 파서라던가

혼자 플레이하는 테트리스

그리고 프렉탈 등등의 여러가지 내용들이 있습니다.

러시아 대학생이 만든 사이트.

http://www.koders.com/

상당히 많은 소스를 제공하는 사이트입니다.

어지간한 소스는 다 있다고 해도 무방합니다.

공부하는데 도움이 되는 사이트

출처 : http://delphi.icm.edu.pl/

델파이 컴포넌트와 프로그램들을 모아놓은 사이트입니다.

많은 컴포넌트들이 있으며, 많은 분류 항목으로 나누어져 있습니다.

찾아보면 좋은 컴포넌트들이 많습니다.

쉐어웨어/프리웨어/데모 등등을 찾을 수 있습니다.

가끔 대박을 건지기도 한답니다.

http://mapage.noos.fr/qnno/pages/delphi_en.htm

몇몇의 컴포넌트와 유닛이 있습니다.

spidergraph hotlog는 아주 좋은 컴포넌트입니다.

hotlog는 에러log 대용으로 사용할 수 있으며, d5~d7까지 지원합니다.

D7을 지원하는 관계로 D2006으로 컨버팅은 아주 쉽습니다.

첨부파일은 hotlog 2.2입니다.

http://www.codebot.org/delphi/

델파이 셀 컨트롤과 오픈 소스 라이브러리가 있는 곳입니다.

약간의 셀에 대한 설명도 있습니다.

오픈 소스 라이브러리는 다른 RTL 유닛의 도움을 받지 않은 순수한 라이브러리입니다.

5, 7, 2006을 지원합니다.

6는 약간의 문제가 있는 듯 하더군요.

약간의 스샷과 예제에 대한 플래시 동영상도 있습니다.

http://www.wilsonc.demon.co.uk/delphi.htm

윌슨의 델파이 관련 사이트.

리소스 편집기라던지 몇몇 특별한 유틸이니 소스가 있습니다.

메신져 - 파일 전송 가능한 메신져. LAN 환경. 클로즈 소스. GPL

http://sourceforge.net/projects/achat

확대경 - 화면 부분 확대, 소스, GPL

http://sourceforge.net/projects/magnifier

colored library - 문법 강조 , LGPL/MPL1.1, 이글립스 플러그인

http://sourceforge.net/projects/colorer/

아레스 갤럭시 P2P - 슈퍼P2P, 소스, GPL

http://sourceforge.net/projects/aresgalaxy

delphicodetodoc - 델파이 코드를 문서로, 소스, GPL

http://sourceforge.net/projects/dephicodetodoc

dev-php IDE - php IDE 개발 환경, 소스, GPL

http://sourceforge.net/projects/devphp

crash point - worms 아류, 소스, GPL

http://sourceforge.net/projects/crashpoint

delphi code analyser - 델파이 코드 분석툴, 소스, MPL1.1

http://sourceforge.net/projects/dca

Scintilla Project 컴포넌트 - Scintilla 컴포넌트, 소스, LPGL/MPL1.1

http://sourceforge.net/projects/delphisci

프로메테우스 프로젝트 - 라크나로크 서버, 소스, GPL

http://sourceforge.net/projects/prometheusproj

Recognition And Vision Library - 패턴인식 라이브러리, 소스, LGPL

http://sourceforge.net/projects/ravl

소코반 - 게임, 소스, 라이센스 없음

http://sourceforge.net/projects/sokobanyasc

LCD Smartie - LCD 개발 프로그램, 소스, LGPL/GPL/MPL1.1

http://sourceforge.net/projects/lcdsmartie

Legend of Mir2 Diamond Emulator - 미르의 전설 2 서버/클라이언트 에뮬레이터, 소스, GPL

http://sourceforge.net/projects/diamondm2server

InstantObjects - DB 관련 컴포넌트 패키지, 소스, MPL1.1

http://sourceforge.net/projects/instantobjects

HomeNet PhoneNet - VOIP, 소스, GPL/Nethack General Public License

http://sourceforge.net/projects/hnpnren

shundown monster - 컴퓨터 종료 어플, 소스, GPL

http://sourceforge.net/projects/shutdown

iSafer firewall - 방화벽, 소스, GPL (한국)

http://sourceforge.net/projects/winsockfirewall

PTISC - 턴베이스 게임엔진(2D Isomatric) 소스, GPL

http://sourceforge.net/projects/ptisc

Klipboard - 클립보드툴, 소스, LGPL

http://sourceforge.net/projects/klipboard

델파이 Indy(9,10)데모, 소스, MPL1.1

http://sourceforge.net/projects/internetdemos

Packetyzer - 패킷 분석기, 소스, GPL

http://sourceforge.net/projects/packetyzer

Programmer's Notepad - 편집기, GPL

http://sourceforge.net/projects/pnotepad

Charset Detector - 문자 코드 검출기, 소스, LGPL

http://sourceforge.net/projects/chsdet

GenIconXP - 다중 아이콘 파일 생성기, 소스, GPL

http://sourceforge.net/projects/geniconxp

파이썬 코드 50라인으로 웹 크롤러 만들기

[출처] http://theanti9.wordpress.com/2009/02/14/python-web-crawler-in-less-than-50-lines/

Python Web Crawler in Less Than 50 Lines

I got kind of bored today, and wrote a pretty simple web crawler with python and it turned out to be less than 50 lines. It doesn’t store output, I’ll leave that up to anyone who wants to use the code, because, well, theres just too many ways to choose from. Right now you pass it a starting link as a parameter and it will crawl forever untill it runs out of links. But that is not a likely condition. So here ya go. Have fun. Feel free to ask questions

import sys
import re
import urllib2
import urlparse
tocrawl = set([sys.argv[1]])
crawled = set([])
keywordregex = re.compile('<meta\sname=["\']keywords["\']\scontent=["\'](.*?)["\']\s/>')
linkregex = re.compile('<a\s*href=[\'|"](.*?)[\'"].*?>')

while 1:
	try:
		crawling = tocrawl.pop()
		print crawling
	except KeyError:
		raise StopIteration
	url = urlparse.urlparse(crawling)
	try:
		response = urllib2.urlopen(crawling)
	except:
		continue
	msg = response.read()
	startPos = msg.find('<title>')
	if startPos != -1:
		endPos = msg.find('</title>', startPos+7)
		if endPos != -1:
			title = msg[startPos+7:endPos]
			print title
	keywordlist = keywordregex.findall(msg)
	if len(keywordlist) > 0:
		keywordlist = keywordlist[0]
		keywordlist = keywordlist.split(", ")
		print keywordlist
	links = linkregex.findall(msg)
	crawled.add(crawling)
	for link in (links.pop(0) for _ in xrange(len(links))):
		if link.startswith('/'):
			link = 'http://' + url[1] + link
		elif link.startswith('#'):
			link = 'http://' + url[1] + url[2] + link
		elif not link.startswith('http'):
			link = 'http://' + url[1] + '/' + link
		if link not in crawled:
			tocrawl.add(link)

** EDIT **

This was a very early draft of this program. As it turns out, I revisited this project a few months later and it evolved much more.
If you would like to check out the more evolved form, feel free to have a look here at my github

[프로그래밍 Tip] 아래는 프로그램 소스코드를 공개하는 사이트를 모아둔 것입니다.
[출처] http://promisej7.tistory.com/294


1. Visual C++, C# and Visual Basic 및 윈도우즈 .Net에 관련된 소스코드들이 공유되는 대표적인 사이트
http://www.codeguru.com/

2. 인터넷 상의 돌아다니는 코드들을 모아놓은 사이트
http://www.planet-source-code.com/

3. Codeguru와 더불어 많은 소스코드와 튜토리얼을 제공하고 있는 사이트
http://www.codeproject.com/

4. 전세계를 석권하고 있는 구글에서 제공하는 오픈소스 사이트
http://code.google.com/
http://code.google.com/projects.html

5. C++, Visual Basic, ASP, sourcecode, programming, javascript, code, delphi, ... 일반적인 조그만 코드들이 많이 모여있음.
http://www.programmersheaven.com/

6. OSI에 대한 정보가 나와 있는 사이트
http://www.opensource.org/

7. 프로젝트 단위의 소스코드를 오픈해주는 세계에서 가장 유명한 사이트
http://sourceforge.net/index.php

8. 자바스크립트가 많이 오픈되어 있는 사이트
http://javascript.internet.com/

9. Gamelan.com is a leading site for Java articles, tutorials, news, discussions, and other resources. ...
http://www.developer.com/open/

10. 세계적인 오픈소스에 대한 라이센스 정책을 세우는 GNU 사이트
http://www.gnu.org/copyleft/gpl.html

11. 세계적인 모바일 업체인 노키아에서 공유하고 있는 소스코드 사이트
http://opensource.nokia.com/projects/S60browser/

12. 애플컴퓨터를 위한 오픈소스 사이트
http://developer.apple.com/opensource/index.html

13. 영국의 개발자들의 소스코드 공유 커뮤니티 사이트
http://www.developerfusion.co.uk/

14. 한국의 대표적인 VS 개발자 공유 사이트
http://www.devpia.com/

15. 개발자 포럼 및 소스공유사이트, BREW에 대한 정보 제공을 잘해주고 있는 사이트
http://www.developer.com/ws/brew/

Hadoop HDFS BASIC Usage Over View : 하둡 사용 개요

 

 

출처 : 국가생물자원정보관리센터 (KOBIC ) - 조수안 연구원

Hadoop Installation Guide

Rockscluster 기반하에서 설명된 메뉴얼임을 알림.>

(# - > root, $ -> hadoop )

* 설치를 시작하기전에 JDK1.5 이상 System에 설치되어 있어야 함.

Step1) 계정 생성

# useradd hadoop(hadoop 계정을 생성해 준다)

# passwd hadoop(hadoop 계정의 password를 설정한다)

# rocks-user-sync(frontend와 노드간의 sync를 맞춰준다.

이작업을 하면 frontend에서 노드로 비번없이 접근이 가능함)

Step2) Hadoop System 폴더 생성

# mkdir /data/hadoop/hdfs(Hadoop관련 디렉토리를 생성한다.

(hdfs이후로는 절대 폴더를 생성하지 않아야함)

# chown -R hadoop.hadoop /data(폴더에 hadoop권한을 준다)

Step3) Hadoop Download

$ wget http://ftp.apache-kr.org/lucene/hadoop/hadoop-$version.tar.gz

(hadoop 홈폴더 안에 Download)

$ tar zxvf hadoop-$version.tar.gz(압축을 품)

$ cd hadoop-$version(압축 푼 폴더로 이동)

$ ant package(설치 command)

Step4) 설정파일 편집

$ vi ./conf/hadoop-env.sh

: 아래와 같이 JAVA_HOME 경로, slaves 설정 파일 경로를 편집합니다.

HADOOP_HOME 은 실제로 hadoop이 설치된 경로를 설정합니다.

export JAVA_HOME=/usr/java/jdk_$version

export HADOOP_HOME=/home/hadoop/HADOOP

export HADOOP_SLAVES=${HADOOP_HOME}/conf/slaves

export HADOOP_LOG_DIR=${HADOOP_HOME}/logs

$ vi conf/hadoop-site.xml(붉은 부분이 실제 자신의 환경에 맞게 편집할 부분임)

fs.default.name

clustome.kobic.re.kr:9000

The name of the default file system. Either the literal string

"local" or a host:port for NDFS.

mapred.job.tracker

clustome.kobic.re.kr:9001

The host and port that the MapReduce job tracker runs at. If

"local", then jobs are run in-process as a single map and

reduce task.

mapred.map.tasks

4

define mapred.map tasks to be number of slave hosts

mapred.reduce.tasks

1

define mapred.reduce tasks to be number of slave hosts

dfs.name.dir

/data/hadoop/hdfs/name

dfs.data.dir

/data/hadoop/hdfs/data

mapred.system.dir

/data/hadoop/hdfs/mapreduce/system

mapred.local.dir

/data/hadoop/hdfs/mapreduce/local

dfs.replication

2

$ vi conf/slaves(실제 slave노드들의 호스트 네임을 적어놓는다)

c0-1

c0-2

c0-3

.

.

.

Step5) 방화벽 설정

# vi /etc/sysconfig/iptables (Master Node)

-A INPUT -m state --state NEW -p tcp --dport 9000 -j ACCEPT

-A INPUT -m state --state NEW -p tcp --dport 9001 -j ACCEPT

-A INPUT -m state --state NEW -p tcp --dport 50010 -j ACCEPT

-A INPUT -m state --state NEW -p tcp --dport 50030 -j ACCEPT

-A INPUT -m state --state NEW -p tcp --dport 50040 -j ACCEPT

-A INPUT -m state --state NEW -p tcp --dport 50050 -j ACCEPT

-A INPUT -m state --state NEW -p tcp --dport 50060 -j ACCEPT

-A INPUT -m state --state NEW -p tcp --dport 50070 -j ACCEPT

# /etc/init.d/iptables restart

# vi /etc/sysconfig/iptables(Slave Node)

-A INPUT -m state --state NEW -p tcp --dport 50010 -j ACCEPT

-A INPUT -m state --state NEW -p tcp --dport 50040 -j ACCEPT

-A INPUT -m state --state NEW -p tcp --dport 50050 -j ACCEPT

-A INPUT -m state --state NEW -p tcp --dport 50060 -j ACCEPT

# /etc/init.d/iptables restart

Step6) ssh key 생성

* Rocks 시스템의 경우 rocks-user-sync만 해주면 됨.

* 일반 리눅스 시스템일 경우엔 기존 ssh key 설정 방법과 같음.

Step7) NameNode Format

$ ./bin/hadoop namenode -format(해당 command를 실행 후 y를 누르면 포맷이 완료됨.)

Step8) 데몬 실행

$ ./bin/start-all.sh(마스터와 슬레이브의 모든 데몬을 한꺼번에 실행)

Step9) 실행 확인

* 웹브라우져에서 다음의 주소로 확인한다.

ex) http://clustome.kobic.re.kr:50030 (Hadoop Map/Reduce Administration)

ex) http://clustome.kobic.re.kr:50070 (Data Node Information)

Hadoop Operation Guide

○ Hadoop Startup

* Hadoop cluster를 시작하기 위해서는 HDFS와 Map-Reduce cluster를 구동시켜야 한다.

$ bin/hadoop namenode -format(새로운 분산파일시스템 포맷)

$ bin/start-dfs.sh(HDFS 구동(NameNode))

* bin/start-dfs.sh script 파일은 ${HADOOP_CONF_DIR}/slaves 파일에 리스팅 되어있는 모든

노드의 DataNode 데몬을 구동시킨다.

$ bin/start-mapred.sh(Map-Reduce 구동(JobTracker))

* bin/start-mapred.sh script 파일은 ${HADOOP_CONF_DIR}/slaves 파일에 리스팅 되어있는 모든

노드의 TaskTracker 데몬을 구동시킨다.

Hadoop Shutdown

$ bin/stop-dfs.sh(HDFS 중지(NameNode)

* bin/stop-dfs.sh script 파일은 ${HADOOP_CONF_DIR}/slaves 파일에 리스팅 되어있는 모든

노드의 DataNode 데몬을 중지시킨다.

$ bin/stop-mapred.sh(Map-Reduce 중지(JobTracker))

* bin/stop-mapred.sh script 파일은 ${HADOOP_CONF_DIR}/slaves 파일에 리스팅 되어있는 모든

노드의 TaskTracker 데몬을 중지시킨다.

★ 위의 모든 작업을 해주는 스크립트가 ./bin/start-all.sh 와 ./bin/stop-all.sh 이다.

Hadoop FSShell Usage

* Usage: java FsShell

[-fs ]

[-conf ]

[-D <[property=value>]

[-ls ]

[-lsr ]

[-du ]

[-dus ]

[-mv ]

[-cp ]

[-rm ]

[-rmr ]

[-expunge]

[-put ]

[-copyFromLocal ]

[-moveFromLocal ]

[-get [-crc] ]

[-getmerge [addnl]]

[-cat ]

[-copyToLocal [-crc] ]

[-moveTo!Local [-crc] ]

[-mkdir ]

[-setrep [-R] ]

○ Hadoop FSShell Example

* jar 파일 실행

[hadoop@clustome HADOOP]$ bin/hadoop jar hadoop-bioliterext.jar medline_2000 medline_2000_result

- hadoop-bioliterext.jar 파일은 파라미터로 input_dir 과 output_dir 을 받는다.

여기서는 medline_2000 이 input_dir, medline_2000_result 가 output_dir 이다.

* 리눅스 ls 명령 실행

[hadoop@clustome HADOOP]$ bin/hadoop dfs -ls

* 리눅스 로컬 데이터를 분산파일시스템으로 복사

[hadoop@clustome HADOOP]$ bin/hadoop dfs -copyFromLocal sample dfs_sample

- sample 이라는 디렉토리를 HDFS(Hadoop Distributed File System)의 dfs_sample 이라는

디렉토리로 복사하는 명령

* 분산파일시스템의 데이터를 로컬 디스크로 복사

[hadoop@clustome HADOOP]$ bin/hadoop dfs -copyToLocal dfs_sample sample

- dfs_sample 이라는 HDFS(Hadoop Distributed File System)의 디렉토리를 로컬 디스크의

sample로 복사하라는 명령

===================================

===================================

======= Fuse installing =============

====================================

리눅스 시스템으로 마운팅해서 일반 리눅스에서 사용하기

hdfs 를 리눅스 파일시스템으로 마운트 시키기 위해 준비해야 할 것은 다음과 같다

Fuse-Hadoop Installation Guide

<Hadoop 0.16.2 Version / Fuse-2.7.3 / Fuse-j-hadoopfs / Fuse-j-2.4를 기준으로 작성된 매뉴얼이며 Rockscluster 기반하에서 설명된 메뉴얼임을 알림.>

(# - > root, $ -> hadoop )

* 설치를 시작하기전에 JDK1.5 이상 System에 설치되어 있어야 함.

* 모든 설치가 끝난 후 마운트 전엔 반드시 Hadoop Demon이 올라와 있어야 함.

Step1) 설치파일 다운

$ mkdir /$Hadoop_Home/fuse

$ cd fuse

$ wget http://jaist.dl.sourceforge.net/sourceforge/fuse/fuse-2.7.3.tar.gz

-> Fuse-2.7.3

$ wget http://jaist.dl.sourceforge.net/sourceforge/fuse-j/fuse-j-2.4-prerelease1.tar.gz

-> Fuse-j-2.4

$ wget http://issues.apache.org/jira/secure/attachment/12371549/fuse-j-hadoopfs-03.tar.gz

->Fuse-j-hadoopfs

Step2) Fuse-2.7.3 설치

$ tar xvfz fuse-2.7.3(압축을 푼다.)

$ cd fuse-2.7.3(해당 패키지 폴더로 이동)

# ./configure(환경설정 및 make 파일 체크)

# make(반드시 root로 해야함. 이유는 /usr/local/lib 와 /usr/local/include에 관련 파일을 쓰기 때문)

# make install

# modprobe fuse

Step3) Fuse-j-2.4 설치

$ tar xvfz fuse-j-2.4(압축을 품)

$ cd fuse-j-2.4(해당 패키지 폴더로 이동)

$ vi build.conf(설정파일 편집)

- JDK_HOME=자신의 머신에 맞게 설정

- FUSE-HOME=자신의 머신에 맞게 설정

$ ant(빌드함)

$ make

Step4) Fuse-j-hadoopfs

$ tar xvfz fuse-j-hadoopfs(압축을 품)

$ cd fuse-j-hadoopfs(해당 패키지 폴더로 이동)

$ vi build.properties(설정파일 편집)

- JDK_HOME=/usr/java/jdk1.5.0_07(자바경로 설정)

- HADOOP_HOME=/home/hadoop/HADOOP(hadoop 경로설정)

- FUSE_HOME=/home/hadoop/fuse/(fuse 홈 설정)

- FUSE_J_HOME=/home/hadoop/fuse/fuse-j-2.4-prerelease1(fuse-j 홈 설정)

- FUSE_J_DOWNLOAD_URL=http://www.jaql.org/fuse-j/fuse-j.tar.gz

(fuse-j 다운로드 설정: 이 구문 설정을 해놓으면 fuse-j 가 없을 경우 자동으로 다운 받게 해줌.)

$ cp fuse-2.7.3/lib/.lib/libfuse.so.2 fuse-j-2.4/jni(해당 lib 복사)

$ ant compile -Dbuild-fuse-j-hadoopfs=1(컴파일 함)

# chown hadoop.hadoop /dev/fuse(hadoop관련 마운트 디바이스 파일을 hadoop 계정으로 줌)

$ ./hadoofs_fuse_mount.sh [마운트포인트]

(마운트 포인트는 / 및에 아무곳이라도 상관없다. 단, hadoop권한이 있어야 함.)

= 정말 수백번의 삽질 끝에 알아낸 설치 정보이다. 삽질결과 다음과 같은 정보를 뽑아낼 수 있었음.=

설치 후 리눅스 기본 명령어 테스트 결과 (cp, mkdir, scp ,rsync, rm, ls, vi... 등등) 잘 됨.

단, df 명령어를 하였을 경우 hadoop 파일시스템으로 마운트 된 정보는 나오질 않음

하지만 데이터가 실제로 들어가는지에 대한 확인 및 관리는 다음의 url로 확인이 가능함.

(http://clustome2.kobic.re.kr:50070)

remote 네트워크 파일 copy 수행 결과 평균 속도 30M ~ 35M를 유지하고 있으며 현재까진 안정적이다.

fuse-hadoop-0.1.0_fuse-j.2.4_hadoop.0.5.0 패키지를 이용하여 마운트를 하는 방법도 있지만

필자가 테스트 해본 결과 위의 방식이 가장 안정적이며 속도 또한 잘 나온다.

오픈 소스 클라우드 분석

IaaS(Infrastructure as a Service)를 위한 빌딩 블록

M. Tim Jones, Consultant Engineer, Emulex Corp.

요약: 이제 더 이상 신생 기술이 아닌 클라우드 컴퓨팅은 애플리케이션을 사용하고 개발하는 방법을 근본적으로 바꿔 놓은 유용하고 중요한 기술입니다. 예상대로 Linux®와 오픈 소스가 클라우드의 기반(공용 및 개인용 인프라를 위한)을 제공합니다. 이 기사에서는 클라우드, 클라우드의 아키텍처 및 이러한 동적이고 확장 가능한 컴퓨팅 및 저장소 플랫폼을 개발하는 데 사용된 오픈 소스 기술에 대해 자세히 설명합니다.

이 기사에 태그: 개요, 클라우드

원문 게재일: 2010 년 3 월 09 일 번역 게재일: 2010 년 4 월 13 일
난이도: 중급 영어로: 보기
페이지뷰: 8376 회
의견: 0 (보기 | 의견 추가 - 로그인)

평균 평가 등급 4 개 총 5표 평균 평가 등급 (5 투표수)
아티클 순위

분산 시스템 즉, 인터넷에서는 클라우드를 추상적 개념으로 사용하는 것이 매우 일반화되어 있다. 하지만 지난 몇 년 동안 이 추상적 개념은 로컬 또는 원격으로 손쉽게 서비스로 제공할 수 있는 높은 수준의 가상화된 확장 가능한 인프라로 확장되었다. 이 기사에서는 클라우드 아키텍처에 대한 자세한 정의와 장점에 대해서는 다루지 않는다. 대신 참고자료 섹션을 참조하기 바란다.

클라우드 컴퓨팅 분석

이 기사에서는 먼저 클라우드 아키텍처의 핵심 추상적 개념인 IaaS(Infrastructure as a Service)부터 시작하여 빌딩 블록을 거쳐서 높은 수준의 통합 솔루션까지 살펴본다.

자주 사용하는 약어

  • API: Application programming interface
  • I/O: Input/output
  • SLA: Service-level agreement
  • UI: User interface

요구사항은 아닐지라도 가상화는 동적으로 확장 가능한 아키텍처를 빌드하는 데 도움이 되는 고유한 장점을 제공한다. 확장성 외에도 가상화는 로드 밸런싱을 위해 실제 서버 간에 VM(virtual machine)을 마이그레이션하는 기능도 제공한다. 그림 1에서는 VMM(virtual machine monitor)이라고도 하는 하이퍼바이저라는 소프트웨어 계층에서 가상화 구성 요소를 제공하는 것을 볼 수 있다. 이 계층에서는 하나의 물리적 시스템에서 여러 운영 체제(및 해당 애플리케이션)를 동시에 실행할 수 있는 기능을 제공한다. 하이퍼바이저 위에는 가상 머신이라는 오브젝트가 있으며, 이 오브젝트에는 운영 체제, 애플리케이션 및 구성이 포함되어 있다. 선택적으로 장치 에뮬레이션을 하이퍼바이저에서 또는 VM으로서 제공할 수 있다. 마지막으로, 가상화의 새로운 동적 특성과 가상화의 새로운 기능을 관리하기 위한 새로운 관리 스키마가 필요하다. 이 관리는 서버에서의 로컬 관리를 통해 계층에서 가장 적합하며, 뿐만 아니라 상위 레벨 인프라 관리를 가상 환경에 대한 전체적인 조정 기능을 통해 상위 레벨 인프라 관리에도 적합하다.


그림 1. 클라우드에 있는 노드의 핵심 요소
핵심 클라우드 요소의 계층 보기를 보여 주는 아키텍처 도표

공유 스토리지를 사용하는 실제 네트워크에 그림 1과 같은 노드를 여러 개 배치하고, 전체 인프라에 대한 관리를 조정하고, 캐싱 및 필터링을 통해 수신 연결(개인용 또는 공용 설정에 상관 없이)에 대한 프론트엔드 로드 밸런싱을 제공하면 클라우드라는 가상 환경이 완성된다. 그림 2에서는 이 새로운 구조를 보여 준다. 이 구조에서 유휴 시스템은 추가 계산 성능이 필요할 때까지 유휴 상태로 유지될 수 있으며(전력 효율 향상) VM을 통해 각 노드의 개별 로드에 따라 노드간 밸런스가 조정되며, 심지어는 동적으로도 조정된다.


그림 2. 클라우드 컴퓨팅 인프라
실제 네트워크/스토리지부터 시작하여 사용자/인터넷까지의 클라우드의 다양한 상호 작용 계층을 보여 주는 다이어그램

클라우드의 기본 아키텍처를 정의했으므로 이제 동적 클라우드 인프라를 구축할 때 오픈 소스가 적용되는 부분을 살펴보자.


핵심 오픈 소스 기술

Linux 환경에서는 클라우드 소프트웨어 패키지의 가상화, 관리 및 대규모 통합을 위한 가상화된 인프라에 중점을 둔 개발의 물결이 나타나고 있다. 먼저 개별 노드 레벨에서의 오픈 소스를 살펴본 다음 인프라 레벨에서 어떤 변화가 나타나고 있는지 살펴보자.

하이퍼바이저

노드 레벨에서의 클라우드의 기본은 하이퍼바이저이다. 가상화는 요구사항이 아니다. 그렇다고 하더라도 가상화가 확장 가능하고 전력 효율이 높은 아키텍처에 필요한 기능을 제공한다는 데는 논쟁의 여지가 없다. 수많은 오픈 소스 가상화 솔루션이 있기는 하지만 Linux 운영 체제를 하이퍼바이저로 변환하는 두 가지 주요 솔루션으로는 Linux KVM(Kernel VirtualMachine)과 Lguest가 있다. KVM은 프로덕션 환경에 전개된 공식 하이퍼바이저 솔루션이며, Lguest는 Linux VM만을 실행하는 Linux 중심적 솔루션이지만 커널에 통합되어 있으며 더 많이 사용되고 있다.

Linux를 하이퍼바이저로 변환하는 솔루션 외에 게스트 VM 중심적 방법을 사용하는 다른 솔루션도 있다. UML(User-Mode Linux)은 게스트 Linux 커널을 수정하여 하이퍼바이저 확장 없이 다른 Linux 운영 체제에서 실행되도록 수정하는 또 다른 접근법이다. 대부분의 사용자가 수정되지 않은 커널을 실행하기를 원하기 때문에 전체 가상화 솔루션(예를 들어, KVM)이 주로 사용된다.

이 UML 접근법도 많이 사용되고 있기는 하지만 가상화된 하드웨어(예를 들어, 콘솔, 가상 디스크 및 네트워크)가 필요하다.

장치 에뮬레이션

하이퍼바이저는 여러 운영 체제에서 CPU를 공유할 수 있는 방법을 제공한다(CPU 가상화). 하지만 전체 가상화를 제공하기 위해서는 VM에 대해 전체 환경이 가상화되어야 한다. 시스템 또는 플랫폼 에뮬레이션은 여러 가지 방법으로 수행될 수 있지만 수많은 하이퍼바이저를 지원하는 인기 있는 오픈 소스 패키지로는 QEMU가 있다. QEMU는 완전한 에뮬레이터이자 하이퍼바이저이다. 하지만 KVM에서는 장치 에뮬레이션을 위해 사용자 공간에 있는 별도의 프로세스로서 QEMU를 사용한다(그림 1 참조). QEMU의 한 가지 흥미로운 특징은 QEMU가 디스크 에뮬레이션을 제공하기(QCOW 형식을 통해) 때문에 스냅샷 및 라이브 VM 마이그레이션 등의 다른 고급 기능도 제공한다는 것이다.

KVM에서는 커널 2.6.25 이후부터 I/O 가상화 성능을 최적화하는 방법으로 virtio를 사용하고 있다. Virtio는 게스트의 후크를 사용하여 의사 가상화된 드라이버를 하이퍼바이저에 도입하여 실제 장치에 가까운 수준의 성능을 제공하는 방식으로 최적화를 수행한다. 이 방법은 이 목적을 위해 운영 체제를 수정할 수 있는 경우에만 사용할 수 있지만 Linux 하이퍼바이저에서 실행되는 Linux 게스트 시나리오에서 사례를 찾아볼 수 있다.

오늘날에는 virtio와 QEMU가 함께 작동하므로 사용자 공간에 있는 Linux 게스트와 QEMU 에뮬레이터 간에 에뮬레이트된 장치 트랜잭션을 최적화할 수 있다.

가상 네트워킹

VM이 실제 서버에 통합됨에 따라 플랫폼에 대한 네트워킹 요구가 높아지고 있다. 하지만 VM의 모든 네트워킹을 플랫폼의 실제 계층에서 처리하는 대신 로컬 통신 자체를 가상화할 수 있다. VM 간의 네트워크 통신을 최적화하기 위해 가상 스위치가 도입되었다. vSwitch는 실제 스위치처럼 동작하지만 플랫폼 내에 가상화되어 있다(그림 3 참조). 이 그림에서는 VM에 연결된 가상화된 인터페이스(VIF)가 가상 스위치를 통해 실제 인터페이스(PIF)와 통신한다.


그림 3. Open vSwitch와 가상 및 실제 인터페이스
실제 도메인, 실제 인터페이스, 가상 인터페이스 및 VM이 아래부터 차례대로 쌓여 있는 계층을 보여 주는 다이어그램

오픈 소스는 매우 흥미로운 솔루션인 Open vSwitch를 사용하여 이 문제를 효과적으로 해결하고 있다. vSwitch는 가상 환경을 위한 가상 스위치를 제공할 뿐만 아니라 실제 플랫폼을 통합하고 VLAN(virtual local area network), 우선순위 기반 QoS(Quality of Service), 트렁크 및 하드웨어 가속 지원(예를 들어, 단일 루트 IOV(I/O virtualization) 네트워크 어댑터) 등의 엔터프라이즈 레벨 기능도 제공할 수 있다. Open vSwitch는 현재 2.6.15 커널에서 사용할 수 있으며 다양한 Linux 기반 가상화 솔루션(Xen, KVM, VirtualBox) 및 관리 표준(RSPAN(Remote Switched Port Analyzer), NetFlow 등)을 지원한다.

VM 도구 및 기술

VM은 운영 체제, 루트 파일 시스템 및 구성의 집합체이므로 도구 개발을 위한 공간으로 충분히 사용할 수 있다. 하지만 VM 및 도구의 모든 가능성을 실현하려면 VM 및 도구를 조립할 수 있는 이식 가능한 방법이 필요하다. 최신 방법인 OVF(Open Virtualization Format)는 유연하고, 효율적이며, 이식 가능한 VM 구조이다. OVF는 VM의 구성을 정의하는 XML 랩퍼로 가상 디스크 이미지를 랩핑하며, 이 구성에는 네트워킹 구성과 프로세서 및 메모리 요구사항을 비롯하여 이미지 및 플랫폼 요구사항을 추가로 정의하기 위한 확장 가능한 다양한 메타데이터가 포함된다. OVF의 주요 기능은 하이퍼바이저에 관계 없이 VM을 분배할 수 있는 이식성이다.

VMI(VM image)를 관리하고 다른 형식으로 변환하는 기능을 제공하는 수많은 유틸리티가 있다. VMware의 ovftool은 VMI 변환을(예를 들어, VMDK(VMware Virtual Disk Development Kit) 형식을 OVF로 변환) 위해 사용할 수 있는 유용한 도구이다. 이 도구를 비롯한 여러 도구는 VMI가 있을 때만 유용하다. 하지만 실제 서버를 VMI로 변환하려는 경우에는 어떤 도구를 사용해야 할까? 이 목적에 적합한 Clonezilla라는 유용한 도구를 사용할 수 있다. 이 도구는 원래 재해 복구를 위한 디스크 복제 도구로 개발되었지만 실제 서버 인스턴스를 VM으로 변환하여 가상화된 인프라에 쉽게 전개할 때도 사용할 수 있다. OVF 형식이 채택되면서 변환 및 관리를 위한 여러 다른 도구(예를 들어, libvirt 기반의 유틸리티)가 개발되었거나 개발 중에 있다.

로컬 관리

이 기사에서는 두 가지 관점에서 관리를 살펴본다. 이 섹션에서는 플랫폼 관리를 설명하며, 다음 섹션에서는 상위 레벨의 인프라 관리에 대해 설명한다.

Red Hat에서는 libvirt 라이브러리를 플랫폼 가상화(하이퍼바이저 및 VM)를 관리하기 위한 API로 도입했다. Libvirt가 흥미로운 이유는 수많은 하이퍼바이저 솔루션(KVM 및 Xen 등)을 지원하고 수많은 언어(예를 들어, C, Python 및 Ruby)에 대한 API 바인딩을 제공하기 때문이다. Libvirt는 플랫폼 하이퍼바이저와의 직접적인 인터페이스를 통해 API를 더 큰 인프라 관리 솔루션으로 확장하는 "최종 관리 단계"를 제공한다. Libvirt를 사용하면 VM을 쉽게 시작하고 중지할 수 있을 뿐만 아니라 API를 사용하여 플랫폼 간에 VM을 마이그레이트하는 등의 고급 작업도 수행할 수 있다. 또한 libvirt 기반의 쉘인 virsh도 사용할 수 있다.


인프라 오픈 소스 기술

지금까지 가상화된 노드 레벨의 오픈 소스 솔루션 중 일부를 살펴보았으며 이제부터는 이 인프라를 지원하는 다른 몇 가지 오픈 소스 애플리케이션을 살펴보자. 이 기사에서는 세 가지 범주를 살펴본다. 처음 두 범주는 앞에서 설명한 솔루션을 보완하는 인프라 레벨 기술이다. 세 번째 범주는 손쉽게 전개할 수 있도록 모든 기능을 모아 놓은 통합 솔루션으로 구성되어 있다.

I/O 기술

확장 가능하고 밸런스가 잘 잡힌 웹 아키텍처를 개발하기 위해서는 백엔드 기능을 구현한 서버 간의 웹 트래픽에 대한 밸런스를 조정하는 기능의 역할이 중요하다. 수많은 로드 밸런싱 솔루션이 있지만 최근에 Yahoo!에서 Traffic Server라는 솔루션의 소스를 공개했다. Traffic Server는 세션 관리, 인증, 필터링, 로드 밸런싱 및 라우팅을 비롯하여 클라우드 인프라에 필요한 수많은 기능을 하나의 패키지로 묶어 놓았다는 점이 흥미롭다. Yahoo!에서는 처음에 이 제품을 Inktomi로부터 인수한 이후 제품을 확장하여 오픈 소스로 공개했다.

인프라 관리

대규모 인프라 관리(많은 하이퍼바이저 및 추가 VM 관리)는 수많은 방법으로 수행할 수 있으며, 그 중에서 동일한 플랫폼(libvirt)을 기반으로 개발된 일반적인 두 가지 솔루션이 있다. oVirt 패키지는 소수의 VM에서부터 시작하여 수백 개의 호스트에서 실행되는 수천 개의 VM으로 확장할 수 있는 오픈 VM 관리 도구이다. Red Hat에서 개발한 oVirt 패키지는 일반적인 관리 기능과 함께 자동화된 클러스터링 및 로드 밸런싱 기능도 지원하는 웹 기반 관리 콘솔이다. oVirt 도구는 Python 언어로 작성되었다. 마찬가지로 Red Hat에서 libvirt를 기반으로 개발한 VirtManager는 웹 기반인 oVirt와는 달리 GTK+ UI를 사용하는 애플리케이션이다. VirtManager는 훨씬 더 많은 그래픽 기능을 제공하며(실시간 성능 및 자원 활용을 위해) 원격 VM에 대한 전체 그래픽 콘솔로 사용할 수 있는 VNC 클라이언트 뷰어를 포함하고 있다.

그리고 Puppet은 데이터 센터 인프라(클라우드)를 위해 설계된 또 하나의 오픈 소스 패키지이다. 가상화된 인프라만을 위해 설계된 것은 아니지만 이 제품을 사용하면 피어 운영 체제의 세부 사항을 추상화하여 대형 인프라 관리를 단순화할 수 있다. 이 작업은 Puppet 언어를 사용하여 수행된다. Puppet은 많은 수의 서버에 대한 관리 작업을 자동화하는 데 이상적이며 오늘날 널리 사용되고 있다.


통합 IaaS 솔루션

다음과 같은 오픈 소스 패키지에서는 모든 필수 기능(가상화, 관리, 인터페이스 및 보안 포함)을 단일 패키지로 통합하는 포괄적인 방법을 사용한다. 이러한 패키지를 서버 및 스토리지 네트워크에 추가하면 유연한 클라우드 컴퓨팅 및 스토리지 인프라(IaaS)를 구축할 수 있다. 이러한 플랫폼에 대한 자세한 정보는 참고자료를 참조하기 바란다.

Eucalyptus

Eucalyptus(Elastic Utility Computing Architecture for Linking Your Programs to Useful Systems)는 클라우드 컴퓨팅 인프라를 구축하는 데 사용되는 가장 인기 있는 오픈 소스 패키지 중 하나이다. 이 패키지의 독특한 점은 인터페이스가 Amazon의 클라우드 컴퓨팅 인터페이스인 Amazon EC2(Amazon Elastic Compute Cloud)와 호환된다는 점이다. 또한 Eucalyptus에는 Amazon의 클라우드 스토리지 인터페이스인 Amazon S3(Amazon Simple Storage Service)와 호환되는 Walrus가 포함되어 있다.

Eucalyptus는 하이퍼바이저를 위해 KVM/Linux 및 Xen을 지원하며 클러스터 관리를 위한 Rocks 클러스터 배포판을 포함하고 있다.

OpenNebula

OpenNebula는 Universidad Complutense de Madrid에서 개발한 또 하나의 흥미로운 오픈 소스 애플리케이션이다(Apache 라이센스를 따름). OpenNebula는 개인용 클라우드 구조를 지원할 뿐만 아니라 하이브리드 클라우드라는 아이디어도 지원한다. 하이브리드 클라우드는 개인용 클라우드 인프라와 공용 클라우드 인프라(예를 들어, Amazon)를 결합하여 확장 수준을 한층 더 높일 수 있다.

OpenNebula는 Xen, KVM/Linux 및 VMware를 지원하며 libvirt와 같은 요소를 사용하여 관리 및 검사 작업을 수행한다.

Nimbus

Nimbus는 과학적 컴퓨팅에 중점을 둔 또 하나의 IaaS 솔루션이다. Nimbus를 사용하면 Amazon EC2에서 제공하는 것과 같은 원격 자원을 임대한 후 로컬에서 이들 자원을 관리할 수 있다(구성, VM 전개, 모니터링 등). Nimbus는 Globus.org의 일부인 Workspace Service 프로젝트의 변형이며, Amazon EC2를 이용하여 Xen과 KVM/Linux를 지원한다.

Xen Cloud Platform

Citrix에서는 Xen을 IaaS 플랫폼에 통합했으며, 이때 Open vSwitch 등의 다른 오픈 소스 기능을 통합하는 동안 Xen을 하이퍼바이저로 사용했다. Xen 솔루션의 흥미로운 장점은 Kensho 프로젝트의 표준 기반 관리(OVF, DTMF(Distributed Management Task Force), CIM(Common Information Model) 및 VMAN(Virtualization Management Initiative) 포함)에 중점을 두고 있다는 점이다. Xen 관리 스택은 SLA 보증과 함께 비용 정산(charge-back)을 위한 세부 기준도 지원한다.

OpenQRM

마지막으로 소개하지만 중요한 솔루션인 OpenQRM은 데이터 센터 관리 플랫폼을 분류된다. OpenQRM은 가상화된 전체 데이터 센터를 관리하는 단일 콘솔로 써드파티 도구를 통합할 수 있는 플러그인 가능한 아키텍처로 구성되어 있다. OpenQRM은 고가용성을 위한 지원(중복성 활용)이 통합하고 KVM/Linux, Xen, VMware 및 Linux VServer를 포함한 다양한 하이퍼바이저를 지원한다.


추가 주제

클라우드 및 가상화 도메인에서 오픈 소스가 주도적인 역할을 담당하고 있는 분야에 대해 할 말은 많지만 이 기사에서는 오늘날 사용할 수 있고 인기가 높은 가시적인 일부 솔루션만을 간략히 소개했다. 자신의 고유한 요구사항에 따라 개별 구성 요소부터 클라우드를 구축하려거나 처음부터 작동하는 종합적인 솔루션을 원하든지 상관 없이 오픈 소스를 통해 모든 것을 구할 수 있다. 여기에서 설명한 솔루션을 포함한 여러 솔루션에 대한 자세한 정보를 보려면 참고자료를 참조하기 바란다.


참고자료

교육

제품 및 기술 얻기

토론

필자소개

M. Tim Jones는 임베디드 펌웨어 아키텍트이자 Artificial Intelligence: A Systems Approach, GNU/Linux Application Programming(현재 2판), AI Application Programming(현재 2판) 및 BSD Sockets Programming from a Multilanguage Perspective의 저자이다. 정지 위성을 위한 커널 개발에서 시작해 임베디드 시스템 아키텍처와 네트워크 프로토콜 개발에 이르기까지 다양한 분야에 대한 공학 지식을 가지고 있다. 콜로라도주 롱몬트 소재의 Emulex Corp.에서 컨설턴트 엔지니어로 활약하고 있다.

Visual studio 2010 에서 소스파일을 UTF-8 로 자동변환

 

[출처] http://nving.tistory.com/66

hack/etc

Visual C++ 10은 기본적으로 ASCII 인코딩으로 파일을 만든다. (VC#은 기본적으로 유니코드 파일로 생성된다는거 같다)

근데 이게 git와 함께 쓰이면 gitweb 등에서 한글이 깨져보이는 현상이 발생하는데 이는 gitweb이 UTF-8 인코딩을 기본 인코딩으로 보여주기때문이다.

이를 위해 소스파일들의 인코딩을 변경해줘야되는데 메뉴의 File -> Advanced Save Options에서 Encoding을 UTF-8로 변경해야하는 번거로움을 감수해야한다.

그만좀 보고싶다.


프로그래머의 힘은 자동화다. 언제까지 이 노가다를 할텐가?
자동화 방법은 다음과 같다.

매크로 에디터에 들어가 EnviromentEvents에서 코드 맨 윗부분의 Module들을 Imports 하는 부분에

Option Strict Off

Option Explicit Off

Imports System

Imports EnvDTE

Imports EnvDTE80

Imports EnvDTE90

Imports EnvDTE90a

Imports EnvDTE100
Imports System.Diagnostics '여기까지 기존 모듈

Imports System.IO

위와 같이 System.IO 모듈을 포함시키고 Automatically generated code, do not modify 다음에 다음 코드를 붙여넣고 저장한다.


Sub MakeUTF8File(ByVal path As String)

Dim input As New FileStream(path, FileMode.Open)

 

'Check BOM

Dim isUTF8 As Boolean = (input.ReadByte = &HEF And input.ReadByte = &HBB And input.ReadByte = &HBF)

input.Close()

 

If (Not isUTF8) Then

Dim s As String

s = File.ReadAllText(path, System.Text.Encoding.Default)

File.WriteAllText(path, s, System.Text.Encoding.UTF8)

End If

End Sub

 

Public Sub DocumentEvents_DocumentSaved(ByVal Document As EnvDTE.Document) Handles DocumentEvents.DocumentSaved

Dim path As String = Document.FullName

MakeUTF8File(path)

End Sub


'이 핸들러는 왠만하면 빼는게 좋다. 라이브러리 파일들을 디버깅 차원에서 열때 자동으로 바꿔버리면 조금 곤란할듯

Public Sub DocumentEvents_DocumentOpening(ByVal path As String, ByVal flag As Boolean) Handles DocumentEvents.DocumentOpening

MakeUTF8File(path)

End Sub

이제 다음과 같은 상황에서 파일이 UTF-8 인코딩으로 자동변환이 된다.

1. 파일을 열때
2. 파일을 생성 (생성할때 자동으로 열리니까)
3. 파일을 저장할때

이제 UTF-8 BOM과 함께하는(?) 코딩을 하면 된다.

추가내용1:
@waan26
님이 알려주신 새파일 생성시 UTF-8을 적용하는 좀 더 좋은 방법이 있다. (C++ Class 생성에는 안먹힌다)
위 방법을 사용시 새 파일을 생성하면 파일 변환이 변환됬다는 메세지 박스가 무조건 뜨게 되는데 (파일 로딩 후에 변환을 시도하는거 같다)
새 파일 생성시 무조건 UTF-8 파일을 생성하는 좀 더 깔끔한 해법으로 다음과 같은 방법이 있다.

1. Visual Studio 설치된 위치(보통 C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcprojectitems)에 간다.
2. hfile.h, newc++file.cpp 과 같은 템플릿 파일의 인코딩을 UTF-8로 변경한다
3. 그 뒤로는 항상 UTF-8 파일이 생성된다.


추가내용2: 클래스 템플릿을 따로 만드는 방법도 있다. 이건 좀 있다가 해보고 적어야지 [...]

P.S. 그건 그렇고 코드를 이쁘게 보여줘야되는데.. ( --)

HTML5로 자신만의 3D 엔진을 만들자

[출처] http://sixrevisions.com/web-development/how-to-create-an-html5-3d-engine/

How to Create an HTML5 3D Engine

You're probably aware by now that HTML5 is game-changing. In particular, with the HTML5 canvas, there's been an outpouring of HTML5 3D JavaScript engines such as three.js released to enhance the rudimentary 2D HTML5 API. After all, 3D graphics is a lot cooler than 2D graphics, right?

It's probably fair to say that if you were to create a full-blown 3D engine–complete with three dimensional matrix transformations, point objects, plane objects, shading, ray tracing, and other spatial computations–it would be quite difficult.

But what if we wanted to create an optimized, barebones 3D JavaScript engine that supports translations and rotations? How hard would it be?

What if I tell you that we can create our own simple 3D JavaScript engine with just 40 lines of code?

This guide will provide a simple and straightforward JavaScript engine that enables HTML5 3D renderings that can be used in web animation, games, and so forth.

Understanding 3D Projections

Before creating our own 3D engine, we should first understand how the illusion of 3D space is created on a 2D screen. These illusions are called 3D projections. 3D projections map points onto a two-dimensional plane. In our case, the three-dimensional points define an object we wish to render, and the two-dimensional plane is the computer screen.

As you can see in the following image, we can create a three-dimensional projection of a cube on a two-dimensional plane by drawing three irregular quadrilaterals – the top, left, and front quadrilaterals.

Plane Projections with Ellipses

Unfortunately, calculating three-dimensional projections can be quite complex to code. How can we simplify it?

Imagine looking down at a rotating rectangular plane. Its four corners would lie on the outline of a perfect circle, whose radius is equal to half the distance from opposite corners of the rectangle.

Now imagine if we were to tilt the plane in 3D space. What happens? This imaginary circle suddenly becomes an ellipse, whose height is less than its width.

This means that we could create a simple 3D projection by creating planes whose corners reside along the edges of an ellipse.

If we are defining the rotation of the plane with an angle, theta, the 3D projection calculations suddenly become quite simple!

Any point on our three-dimensional plane can be defined with the following two equations which describe a point along the edges of an ellipse:

x = A * cos(theta)

y = B * sin(theta)

where A is half of the ellipse width, and B is half of the ellipse height.

A Simple 3D Engine

If our engine simply creates planes in 3D space, we can build multiple cross-sectional planes that frame a 3D object that we wish to render.

Sample 3D Object Rendering

Cross-Sectional Planes Diagram

View demo

This particular 3D shape was created by generating three cross-sectional planes – the top, center, and bottom plane. These imaginary planes provide us with all of the points we need to render the 3D object using the HTML5 Canvas API.

By creating a straightforward function that can generate, translate, and rotate these cross-sectional planes, we have effectively created a simple 3D engine.

Here is the code for our HTML5 3D engine:

// This simple 3D engine was provided by www.Html5CanvasTutorials.com

// for the purpose of creating 3D HTML5 renderings

function Plane(centerX,centerY, planeLength, planeWidth, planeTilt, planeTheta) {

this.centerX = centerX;

this.centerY = centerY;

this.planeLength = planeLength;

this.planeTheta = planeTheta;

 

var lastPerspectiveX = null;

var lastPerspectiveX2 = null;

var planeNextCornerAngle = 2*Math.asin(planeWidth/planeLength);

 

this.rotate = function(newTheta) {

    planeTheta = newTheta - planeNextCornerAngle/2;

}

 

this.translate = function(newCenterX, newCenterY) {

    centerX = newCenterX;

    centerY = newCenterY;

}

 

this.generate = function() {

    var ovalLength = planeLength;

    var ovalWidth = ovalLength * planeTilt;

 

    var perspectiveX = (ovalLength / 2) * Math.cos(planeTheta);

    var perspectiveY = (ovalWidth / 2) * Math.sin(planeTheta);

    var perspectiveX2 = (ovalLength / 2) * Math.cos(planeTheta + planeNextCornerAngle);

    var perspectiveY2 = (ovalWidth / 2) * Math.sin(planeTheta + planeNextCornerAngle);

 

    this.topLeftX = (perspectiveX *1) + centerX;

    this.topLeftY = (perspectiveY * -1) + centerY;

    this.bottomRightX = (perspectiveX*-1) + centerX;

    this.bottomRightY = (perspectiveY*1) + centerY

    this.topRightX = (perspectiveX2 *1) + centerX;

    this.topRightY = (perspectiveY2 *-1) + centerY;

    this.bottomLeftX = (perspectiveX2 *-1) + centerX;

    this.bottomLeftY = (perspectiveY2 *1) + centerY;

}

}

This simple 3D engine is completely free to use and modify so long as you keep the commented credits in your code. Enjoy!

SQL to Mongo Mapping Chart

MySQL executable

Oracle executable

Mongo executable

mysqld

oracle

{{mongod}}

mysql

sqlplus

mongo

MySQL term

Mongo term/concept

database

database

table

collection

index

index

row

BSON document

column

BSON field

join

embedding and linking

primary key

_id field

group by

aggregation

MongoDB queries are expressed as JSON (BSON) objects.  The following chart shows examples as both SQL and in Mongo Query Language syntax. 

The query expression in MongoDB (and other things, such as index key patterns) is represented as JSON (BSON). However, the actual verb (e.g. "find") is done in one's regular programming language; thus the exact forms of these verbs vary by language.  The examples below are Javascript and can be executed from the mongo shell.

SQL Statement

Mongo Statement

CREATE TABLE USERS (a

Number, b Number)

implicit; can also be done explicitly with

db.createCollection("mycoll")

  

ALTER TABLE users ADD ...

implicit

  

  

INSERT INTO USERS VALUES(3,5)

db.users.insert({a:3,b:5})

  

  

SELECT a,b FROM users

db.users.find({}, {a:1,b:1})

SELECT * FROM users

db.users.find()

SELECT * FROM users WHERE age=33

db.users.find({age:33})

SELECT a,b FROM users WHERE age=33

db.users.find({age:33}, {a:1,b:1})

SELECT * FROM users WHERE age=33 ORDER BY name

db.users.find({age:33}).sort({name:1})

SELECT * FROM users WHERE age>33

db.users.find({age:{$gt:33}})

SELECT * FROM users WHERE age!=33

db.users.find({age:{$ne:33}})

SELECT * FROM users WHERE name LIKE

"%Joe%"

db.users.find({name:/Joe/})

SELECT * FROM users WHERE name LIKE

"Joe%"

db.users.find({name:/^Joe/})

SELECT * FROM users WHERE age>

33 AND age<=40

db.users.find({'age':{$gt:33,$lte:40}})

SELECT * FROM users ORDER BY name DESC

db.users.find().sort({name:-1})

SELECT * FROM users WHERE a=1 and b='q'

db.users.find({a:1,b:'q'})

SELECT * FROM users LIMIT 10 SKIP 20

db.users.find().limit(10).skip(20)

SELECT * FROM users WHERE a=1 or b=2

db.users.find( { $or : [ { a : 1 } , { b : 2 } ] } )

SELECT * FROM users LIMIT 1

db.users.findOne()

SELECT order_id FROM orders o, order_line_items li WHERE li.order_id=o.order_id AND li.sku=12345

db.orders.find({"items.sku":12345},{_id:1})

SELECT customer.name FROM customers,orders WHERE orders.id=

"q179" AND orders.custid=customer.id

var o = db.orders.findOne({_id:"q179"});

var name = db.customers.findOne({_id:o.custid})

  

  

SELECT DISTINCT last_name FROM users

db.users.distinct('last_name')

SELECT COUNT(*y)

FROM users

db.users.count()

SELECT COUNT(*y)

FROM users where AGE > 30

db.users.find({age: {'$gt': 30}}).count()

SELECT COUNT(AGE) from users

db.users.find({age: {'$exists': true}}).count()

  

  

CREATE INDEX myindexname ON users(name)

db.users.ensureIndex({name:1})

CREATE INDEX myindexname ON users(name,ts DESC)

db.users.ensureIndex({name:1,ts:-1})

  

  

EXPLAIN SELECT * FROM users WHERE z=3

db.users.find({z:3}).explain()

  

  

UPDATE users SET a=1 WHERE b='q'

db.users.update({b:'q'}, {$set:{a:1}}, false, true)

UPDATE users SET a=a+2 WHERE b='q'

db.users.update({b:'q'}, {$inc:{a:2}}, false, true)

  

  

DELETE FROM users WHERE z=

"abc"

db.users.remove({z:'abc'});

More examples, specifically aggregation examples, here

See Also

지식라이브러리 : 전문가 칼럼
전문가칼럼 보기

 

제목 튜닝방법론(문제 SQL 분석)
분류 Etc 조회수 93
작성일자 2012.07.18 출처 월간마이크로소프트웨어
첨부파일 작성자 dbguide

튜닝방법론(문제 SQL 분석)



데이터베이스를 운영하다 보면 성능 저하를 발생시키는 SQL이 발생하게 된다. 이와 같은 현상에서 가장 처음에 수행해야 하는 부분은 문제 SQL의 수집일 것이다. 이와 같이 문제 SQL을 수집 한 후에는 해당 SQL을 어떻게 분석하고 최적화하느냐에 따라 해 당 시스템은 성능이 향상될 수 있다. 이번 시간에는 문제 SQL을 수집한 후에 해당 문제 SQL을 어떻게 분석해서 수행하는지에 대 해 확인해 보자.

권순용의 DB 이야기



문제 SQL 분류


문제 SQL을 수집했다면 해당 SQL을 분석하는 것이 필요하 다. 문제 SQL을 분석하는 것은 여러 가지 요소를 확인하게 될 것이다. 그 중에 첫 번째는 다음과 같은 항목이다.

- Online SQL : Online SQL은 업무 중에 실시간으로 수행되는 SQL을 의미한다. 그렇기 때문에 Buffer Gets는 많지 않을 가능성이 높고 수행 횟수는 매우 클 가능성이 높다.

- Batch SQL : Batch SQL은 업무 중에 실시간이 아닌 어떤 주기적으로 수행하는 SQL을 의미하며 일반적으로 대용량 데이터를 처리하게 되므 로 Buffer Gets는 높으며 수행횟수는 높지 않을 것이다.

Online SQL인지 아니면 Batch SQL인지를 수집한 SQL에서 어떻게 판단해야 할 것인가? SQL 분석에 있어서 가장 중요한 부 분은 이 둘을 구분하는 것이며, 이는 가장 먼저 해야 할 일일 것 이다. 두 가지 종류의 SQL을 분류하는 수단의 하나는 수행횟수 다. 시간당 수행횟수가 많은 SQL은 Online SQL이 될 가능성이 높을 것이다. 물론 Batch SQL의 경우도 그런 경우가 발생할 수 도 있지만 수행횟수가 많은 SQL은 시스템 전반적인 성능에 문 제를 발생시킬 수 있게 된다.

이와 같이 SQL에 대해 분류됐다면 우선적으로는 Online SQL을 분석하는 것이 필요하다. 추후로 중요한 것은 자주 수행 되는 중요 Batch SQL이 될 것이다. 물론 시간이 많다면 모든 SQL을 분석하는 것도 바람직하다. 하지만 항상 시간이 부족하 기 때문에 우선순위를 정하는 것이 매우 중요하다.

문제 SQL 분석


문제 SQL을 분류했다면 이제는 본격적으로 분석을 수행해야 할 것이다. 그렇다면 어떤 것을 가지고 SQL을 분석할 것인가? 이에 대해 다음과 같은 항목을 분석해야 할 것이다.

- 인덱스 사용 유무
- 사용하는 조인 방식
- 테이블 액세스 방식
- SQL 작성 방식
- 데이터의 흐름

이와 같은 부분을 정확히 분석해야만 해당 SQL에 대한 정확 한 분석이 이뤄지고 성능을 향상시킬 수 있게 된다. <리스트 1>의 예제를 확인해 보자.



<리스트 1>은 목록 쿼리의 형식을 가지고 있는 SQL로, 해당 SQL은 <리스트 2>와 같이 실행 계획이 생성된다.





해당 SQL을 분석해보면 어떤 부분이 문제인지 확인할 수 있 겠는가? 앞서 언급한 항목을 하나하나 확인해 보자.

- 인덱스 사용 유무 : 현재 RANK_TOTAL 테이블을 액세스함에 있어서 인덱스를 이용하고 있으며 인덱스는 QUERY+ST_DATE로 구성돼 있 는 인덱스를 이용하고 있다.
- 사용하는 조인 방식 : 현재 조인은 발생하지 않고 있다.
- 테이블 액세스 방식 : 인덱스 액세스 후 테이블을 액세스하는 전형적인 방식이다.
- SQL 작성 방식 : SQL 작성은 현재 단계에서는 중복 테이블 액세스 등 이 없다.
- 데이터의 흐름 : 계속 감소하는 형식의 데이터 흐름이다.

그렇다면 해당 SQL은 분석 항목 확인에서 그렇게 큰 문제가 발생하지 않는 것처럼 보인다. 하지만 가장 큰 문제는 테이블 액 세스 방식에 있다. 물론 데이터 액세스에는 이상이 없지만 해당 SQL은 Online SQL이며 자주 수행되는 SQL이기 때문에 어떻 게 해서라도 더 최적화해야 하기 때문이다. 해당 SQL의 성능 데 이터는 <리스트 3>과 같다.





해당 SQL은 문제가 없다면 1초 미만으로 결과가 추출될 것이 다. 하지만 해당 SQL은 문제가 존재해 31초 정도의 수행시간이 소요됐다. 우선적으로 이는 앞서 언급한 인덱스 액세스 후 테이 블을 액세스하는 테이블 액세스 방식에 문제가 존재한다.

해당 SQL에 대한 분석은 이와 같으며 해당 SQL에 대한 최적 화는 다음 시간에 살펴본다.






출처 : 월간마이크로소프트웨어6월호

제공 : DB포탈사이트 DBguide.net

phpmyadmin과 비슷하게 mongoDB를 php 서버로 관리하기 위한 phpMoAdmin

[출처] http://www.phpmoadmin.com/

리눅스, 아파치 웹서버, mysql 데이타베이스, php 스크립트를 운용하는 LAMP 서버에서는 phpmyadmin 이라는

대부분 사용하고 있는 database 툴이 있습니다.

여기에 최근 각광받는 nosql 데이타베이스인 mongoDB를 사용할 때는 관리가 참 남감한데요.

phpMoAdmin리는 툴이 있습니다. 최근 웹 기술을 사용하여 역동적인 인터페이스를 가지고 있습니다.

phpMoAdmin - MongoDB GUI

MongoDB administration tool for PHP

Built on a stripped-down version of the Vork high-performance framework

  • Nothing to configure - place the moadmin.php file anywhere on your site and it just works!
  • Fast AJAX-driven XHTML 1.1 interface operates consistently in every browser!
  • Self-contained in a single 95kb file!
  • Works on any version of PHP5 with the MongoDB NoSQL database & Mongo PHP driver.
  • Enter into the single smart-search box:
    • Plain text
    • (type-casted) value
    • Text with * wildcards
    • Regular Expressions (regex)
    • JSON (with Mongo-operators enabled!)
  • Includes multiple design themes to choose from
  • Super flexible - option to query MongoDB using JSON or PHP-array syntax
  • Import/export data in JSON format
    • Export full collections
    • Export the results of any query
    • Import can:
      • Insert only new records
      • Save / upsert (adds & overwrites)
      • Update only pre-existing records
      • Batch-Insert until a duplicate is found
  • Textareas can be resized by dragging/stretching the lower-right corner.
  • E_STRICT PHP code is formatted to the Zend Framework coding standards + fully-documented in the phpDocumentor DocBlock standard.
  • Instructional error messages - phpMoAdmin can be used as a PHP-Mongo connection debugging tool
  • Option to enable password-protection for one or more users; to activate protection, just add the username-password(s) to the array at the top of the file.
  • Free & open-source! Released under the GPLv3 FOSS license!

DOWNLOAD phpMoAdmin

 

(tiny 25kb download, unzips to 115kb)

Screenshots

Object display

Full-mode

Object display

Compact-mode

Object editor

Drag-corner to resize textarea

Mongo Statistics

Stats, error log, versions & system info

   

Features

  • Database
    • List with data sizes
    • Create/drop
    • Repair/compact
  • Collection
    • Show list of collections with number of objects within each
    • Create/rename/drop collection
    • List indexes
    • Create/drop indexes
      • multiple keys
      • ascending/descending
      • unique index
  • Data objects
    • Single smart-search box accepts:
      • exact-text
      • (type-casted) value
      • text with * wildcards
      • Regular Expressions (regex)
      • JSON (with Mongo-operators enabled)
    • Option to query MongoDB using JSON or a PHP array
    • Show objects with 3-different viewing options (full, compact & uniform)
    • Sort by any key within your data object (even nested sub-keys!) with ascending/descending option
      • Option to sort by $natural for rapid browsing of large datasets
    • Define the number of results to display per page (or unlimited)
    • Create/delete objects
    • Edit object data
  • Mongo GridFS
    • GridFS objects automatically link GridFS chunks to GridFS files
  • MongoDB stats
    • Uptime, memory, etc.
    • Log of previous errors
    • Mongo-PHP settings
    • Version & bit-depth of MongoDB, Mongo PHP driver, phpMoAdmin, etc.
  • Optional password-protection for one or more users

     

     

phpMoAdmin - MongoDB GUI

MongoDB administration tool for PHP

Built on a stripped-down version of the Vork high-performance framework

  • Nothing to configure - place the moadmin.php file anywhere on your site and it just works!
  • Fast AJAX-driven XHTML 1.1 interface operates consistently in every browser!
  • Self-contained in a single 95kb file!
  • Works on any version of PHP5 with the MongoDB NoSQL database & Mongo PHP driver.
  • Enter into the single smart-search box:
    • Plain text
    • (type-casted) value
    • Text with * wildcards
    • Regular Expressions (regex)
    • JSON (with Mongo-operators enabled!)
  • Includes multiple design themes to choose from
  • Super flexible - option to query MongoDB using JSON or PHP-array syntax
  • Import/export data in JSON format
    • Export full collections
    • Export the results of any query
    • Import can:
      • Insert only new records
      • Save / upsert (adds & overwrites)
      • Update only pre-existing records
      • Batch-Insert until a duplicate is found
  • Textareas can be resized by dragging/stretching the lower-right corner.
  • E_STRICT PHP code is formatted to the Zend Framework coding standards + fully-documented in the phpDocumentor DocBlock standard.
  • Instructional error messages - phpMoAdmin can be used as a PHP-Mongo connection debugging tool
  • Option to enable password-protection for one or more users; to activate protection, just add the username-password(s) to the array at the top of the file.
  • Free & open-source! Released under the GPLv3 FOSS license!

DOWNLOAD phpMoAdmin

 

(tiny 25kb download, unzips to 115kb)

Screenshots

Object display

Full-mode

Object display

Compact-mode

Object editor

Drag-corner to resize textarea

Mongo Statistics

Stats, error log, versions & system info

   

Features

  • Database
    • List with data sizes
    • Create/drop
    • Repair/compact
  • Collection
    • Show list of collections with number of objects within each
    • Create/rename/drop collection
    • List indexes
    • Create/drop indexes
      • multiple keys
      • ascending/descending
      • unique index
  • Data objects
    • Single smart-search box accepts:
      • exact-text
      • (type-casted) value
      • text with * wildcards
      • Regular Expressions (regex)
      • JSON (with Mongo-operators enabled)
    • Option to query MongoDB using JSON or a PHP array
    • Show objects with 3-different viewing options (full, compact & uniform)
    • Sort by any key within your data object (even nested sub-keys!) with ascending/descending option
      • Option to sort by $natural for rapid browsing of large datasets
    • Define the number of results to display per page (or unlimited)
    • Create/delete objects
    • Edit object data
  • Mongo GridFS
    • GridFS objects automatically link GridFS chunks to GridFS files
  • MongoDB stats
    • Uptime, memory, etc.
    • Log of previous errors
    • Mongo-PHP settings
    • Version & bit-depth of MongoDB, Mongo PHP driver, phpMoAdmin, etc.
  • Optional password-protection for one or more users

1339765580_자동화된 개발 환경 파이썬 장고 p40120.pdf

파이썬 개발자들에게 장고란 이름은 낯설지 않을
것이다. 장고를 도입한 웨싱턴 포스트에서 이미 성능이 검증됐고
구글 앱 엔진에서 장고를 지원하며 화제가 됐다. 최근 장고는 파
이썬을 기반으로 한 웹 프레임워크인 터보기어나 Zope(Z
Objectpublishing Environment)를 제치고 파이썬의 대표적인
웹 프레임워크로 급부상하기 시작했다.
파이썬의 특징인 단순함과 명료성을 물려받았고 수많은 파이
썬 모듈을 바로 이용할 수 있는 것은 장고가 순수하게 파이썬만
으로 개발됐기 때문이다. 설치가 쉽고 간단한 코드만으로 웹 애
플리케이션을 개발하고 서비스할 수 있을 만큼 완성도가 높은 실
용적인 프레임워크가 장고다. 또한 RESTful 등의 웹 애플리케이
션 필수 기능을 간단한 코드만으로 처리할 수 있고 데이터베이스
모델의 생성, 연동 그리고 관리 페이지까지 자동으로 생성된다.
이런 단순함과 명료성은 장고에 담긴 두 가지 철학에 기인했
다. 첫 번째 철학인‘중복 방지 원칙’은 개발 프로젝트에서 생성
된 비슷한 기능의 수많은 클래스와 데이터를 지양한다는 의미로
차후 언급할 OMR(Object-Relational Mapper)이 이를 담당한
다. 두 번째 철학은‘자동화’다. 실제로도 장고는 많은 부분이 자
동화돼 개발자의 부담을 덜어준다.
Object-Relational Mapper
장고는 파이썬 코드로 필요한 데이터의 모델을 표현하는 것
만으로 데이터베이스를 이용할 수 있다. Data-model syntax로
데이터 모델을 정의하면 원하는 데이터에 접근할 수 있으며
SQL문을 통한 직접적인 접근도 가능하다.
사람의 이름을 저장하기 위한 Person이란 클래스는 데이터 모
델과 관련된 가장 기본적인 클래스인 models.Model 클래스를
상속받는다. 클래스를 선언하고 모델링할 때 해당 클래스에서 어
떤 데이터를 사용할지 프로퍼티를 선언하며 프로퍼티는 테이블
의 필드에 해당한다. 이렇게 생성한 모델로 데이터베이스를 직접
적으로 접근 및 파이썬 API를 통한 접근 모두 가능하다.
Automatic admin interface
장고는 데이터를 관리할 수 있는 관리자 인터페이스를 무료로
제공한다. 모델을 생성하면 관리 페이지에 데이터를 직접 추가,
수정, 삭제할 수 있다.
128 m a s o
최동진 milkelf.choi@gmail.com|소프트웨어 개발과 인연을 맺은 지 10년이 훌
쩍 넘었다. 그 동안 C/C++ 만으로 개발했지만 업무 효율성을 위해 접하게 된
파이썬의 매력에 푹 빠져 있다. 최근 웹에 관심을 가지고 여러 웹 기술들을 연구
하고 있다. 저서로는 <빠르게 활용하는 파이썬 3.2 프로그래밍>이 있다.
촉박한 일정과 무리한 요구사항으로 곤경에 빠져 본 일은 개발자에게 특별한 경험은 아닐 것이다. 이런 개발상의 어려움을 줄여주는
다양한 웹 프레임워크 중‘ 장고(Django)’는 개발 당시, 기타리스트인‘ 장고 라인하르트’에 빠진 나머지 이런 독특한 이름이 지어졌다.
이름만큼이나웹사이트의문구도독특하다.‘ 마감을완벽히지킬수있는프레임워크’란인상적인문구만으로마감시일로인해
극심한 스트레스에 시달렸을 장고 개발자의 시름이 느껴진다. 그렇다면 어떻게 웹 프레임워크인 장고만으로 마감일을 지킬 수 있을까?
이런 의문에 대한 답을 이 글에서 찾을 수 있을 것이다. 여기서는 순수하게 파이썬(Python)만으로 개발된 장고의 특징과 활용법
그리고 향후 전망까지 살펴본다.
자동화된 개발 환경
파이썬 장고
cove r s t o r y 3
from django.db import models
class Person(models.Model):
full_name = models.CharField(max_length=30)
email_address = models.CharField(max_length=30)
<리스트 1> Data-model syntax 사용
Elegant URL design
URL을 처리하는 URLConf는 이 모듈에 정의된 URL 패턴과
장고의 함수를 이어주는 역할을 한다. 장고에서 프로젝트 생성
시 기본 생성되는 urls.py 파일에 URLConf를 설정할 수 있으며
URL 패턴은 정규식만 알면 쉽게 정의할 수 있다.
from django.conf.urls.defaults import *
urlpatterns = patterns(‘’,
(r’ ^articles/(\d{4})/(\d{2})/(\d+)/$’ ,
‘news.views.article_detail’),
)
위 코드에서‘/articles/2005/05/39323/’는 URL 호출 시
news.views.article_detail(request,‘ 2005’,‘ 05’,‘ 39323’)처럼
함수를 호출하며, RESTful 형식의 요청을 처리할 때 유용하다.
Template system
장고는 강력하고 확장이 가능한 템플릿 언어를 제공한다. 여기
에는 콘텐츠, 파이썬 코드가 분리돼 있어 디자이너에게 친화적인
템플릿이라고 볼 수 있다. 타 웹 프레임워크에서는 템플릿을 위
한 언어를 새로 학습해야 하지만 장고는 파이썬 언어만 알면 쉽
게 템플릿을 활용할 수 있다.
PHP나 JSP에서는 템플릿에 코드 삽입이 가능하지만 장고는
조건문과 반복문 정도만 허용하며, 이는 콘텐츠와 디자인을 완전
히 분리하고자 한 의도가 반영된 결과다.
Cache System
서버의 도움 없이 장고는 메모리, 데이터베이스, 파일시스템
중 지정된 위치에 자동으로 페이지를 캐시할 수 있다.
Internationalization
국가별 언어 지원을 위해 여러 개의 웹 애플리케이션이나 템플
릿을 개발하는 것은 중복금지의 원칙을 위반하는 것이다. 장고는
하나의 웹 애플리케이션만으로 국제화와 현지화 모두 가능하다.
Model, View, Template
장고에서는 MCV를 MVT(Model, View, Template)라고 부
르며 이는 데이터를 의미하는 Model, 사용자에게 보여지는 시각
적 부분인 Template, 실질적으로 프로그램 로직이 동작하는 함
수의 실행과 결과를 전달하는 View를 의미한다.
장고 사용하기
웹 서버가 내장된 장고는 별도의 웹 서버를 설치하지 않아도
돼 설치도 비교적 간단하다. 아파치 웹 서버도 mod_wsgi로 장고
와 연동할 수 있고 장고의 코드를 구글 앱 엔진에 올릴 수 있다.
장고를 설치하기 위해서는 먼저 파이썬 2.6 또는 파이썬 2.7이
설치돼 있어야 한다. www.djangoproject.com/download에서
최신 버전을 다운로드하고 임의의 디렉터리에 압축을 푼 후 다음
의 명령어를 콘솔에서 실행하면 장고 설치가 완료된다.
C:\down\Django-1.4>python.exe setup.py install
이제 본격적으로 프로젝트와 앱을 개발해보자. 장고에서는 웹
애플리케이션을 앱이라 부르며, 프로젝트는 데이터베이스, 템플
릿, URL 등의 설정과 웹 사이트에 필요한 앱의 집합이다.
먼저 mysite란 이름의 프로젝트를 생성하자.
C:\>c:\Python27\python.exe django-admin.py startproject mysite
mysite란 디렉터리가 생성되고 그 안에는 <표 1>과 같은 파일
이 생성된다.
m a s o 129
<그림 1> 장고 관리 페이지
{% block content %}
{% for entry in blog_entries %}
<h2>{{ entry.title }}</h2>
<p>{{ entry.body }}</p>
{% endfor %}
{% endblock %}
<리스트 2> 간단한 장고 템플릿
<표 1> 프로젝트 안에 자동으로 생성된 파일
__init__.py 초기화와 관련된 파일로 첫 생성의 경우 빈파일이다.
manage.py 프로젝트를 관리에 필요한 기능이 포함된 모듈
settings.py
프로젝트의 설정 값과 규칙을 지정한 파일, 데이터베이스 설정도
이곳에서 한다.
urls.py URL을 어떻게 다룰지에 대한 규칙이 정의돼 있다.
다음 명령어로 mysite 프로젝트에 contact란 앱을 추가하자.
C:\mysite>c:\Python27\python.exe manage.py startapp contact
mysite 디렉터리 안에 contact 디렉터리가 생성되고 contact
앱에 필요한 기본 파일이 자동으로 생성된다. 프로젝트 디렉터리
의 setting.py 파일의 INSTALLED_APPS 항목에 contact를 추
가하면 프로젝트에 앱이 추가된다(<리스트 3> 참조).
데이터베이스 설정하기
장고의 강력한 기능인 OMR을 이용하기 위해선 setting.py 파
일의 DATABASE 항목을 사용할 DBMS에 맞춰 수정해야 한
다. 파이썬에서는 sqlite3 DBMS를 기본 제공하므로 별도의
DBMS를 설치하지 않아도 된다.
<리스트 4>와 같이 setting.py 파일을 수정한 후 콘솔에 다음
명령어를 실행한다.
C:\mysite>c:\Python27\python.exe manage.py syncdb
만약 첫 실행인 경우 관리에 필요한 테이블이 생성되고 슈퍼유
저 등록 메시지가 나타난다.
데이터 모델 만들기
contact 앱에 필요한 이름과 이메일 주소를 저장하는 간단한
모델을 만들자. contact 디렉터리 안의 model.py에 Person 클래
스를 추가한다. syncdb 명령어를 다시 실행하면 테이블 1개가
생성됐다는 메시지가 나타나며, 다음 명령어로 생성된 테이블의
스키마를 확인할 수 있다.
C:\mysite>c:\Python27\python.exe manage.py sql contact
BEGIN;
CREATE TABLE“ contact_person”(
“id”integer NOT NULL PRIMARY KEY,
“full_name”varchar(30) NOT NULL,
“email_address”varchar(30) NOT NULL
);
COMMIT;
관리 페이지 설정
이제 장고가 무료로 제공하는 데이터베이스 관리 페이지를 이
용해보자. setting.py 파일의 INSTALLED_APPS 항목에서
‘django.contrib.admin’의 주석을 지워 관리 페이지를 활성화시
킬 수 있다. urls.py에서도 관리 페이지를 사용하기 위해 주석을
지우고 pattern에 다음과 같이 입력하면 관리 페이지에 접근할
수 있는 URL이‘서버주소 + /admin/’로 설정된다.
장고 내장 서버 사용
장고에 내장된 웹 서버를 실행하는 방법은 다음과 같다.
C:\mysite>c:\Python27\python.exe manage.py runserver
Validating models...
0 errors found
Django version 1.4, using settings‘ mysite.settings’
Development server is running at http://127.0.0.1:8000/
130 m a s o
c o v e r s t o r y 3 파이썬 장고
INSTALLED_APPS = (
...생략
'django.contrib.staticfiles',
# Uncomment the next line to enable the admin:
#'django.contrib.admin',
'contact',
)
<리스트 3> app 추가
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
# sqlite3 엔진을 사용할 것을 선언한다.
'NAME': 'contactdb',
# DB 이름, 혹은 sqlite3인 경우 DB 파일 패스
'USER': '', # Not used with sqlite3.
'PASSWORD': '', # Not used with sqlite3.
'HOST': '',
# Set to empty string for localhost. Not used with sqlite3.
'PORT': '',
# Set to empty string for default. Not used with sqlite3.
}
}
<리스트 4> DATABASE 설정
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
# Uncomment the next line to enable the admin:
url(r'^admin/', include(admin.site.urls)),
)
<리스트 5> 관리 페이지 세팅
Quit the server with CTRL-BREAK.
브라우저에서 http://127.0.0.1:8000/admin을 입력하면 관리
자 페이지가 나타난다. 로그인 하면 Person이 없을 것이다. 관리
페이지에서 Person을 포함시키기 위해서는 contact 디렉터리 안
의 admin.py 파일을 생성하고 다음과 같이 입력한다.
서버를 재시작하면 관리 페이지에 Person이 포함된 것을 확인
할 수 있다.
Contact 앱 구현
Person 안에 있는 모든 이름 항목이 출력되는 앱 애플리케이
션을 개발해보자. contact 앱 생성 시 함께 생성된 views.py에 다
음과 같이 입력한다.
contact 앱이 실행될 수 있게 urls.py를 <리스트 8>과 같이 수
정하자.
<리스트 8>은‘서버 주소 + /contacts/’형식의 요청 시
contact 앱 안의 views.py에서 contacts 함수를 찾아 실행시킨다.
contact 앱 애플리케이션을 위한 모든 작업이 완료됐다. 브라
우저에 http://127.0.0.1:8000/contacts를 입력하면 데이터베이
스의 Person 항목의 모든 정보가 <그림 2>처럼 출력된다.
보다 쉽게 장고를 이해할 수 있도록 간단한 앱 애플리케이션을
개발해봤다. 소규모의 간단한 웹서비스 개발에 장고를 이용할 수
있지만 대용량 웹서비스, 앱 애플리케이션 개발에도 유용하다.
장고의 미래
최근 릴리즈된 장고 1.4는 1.3이 릴리즈된 지 1년 만에 업데이
트가 이뤄졌다. 빨라진 업데이트 주기는 장고의 사용자 층이 두
터워지고 이에 따라 사용자 요구도 증가된 데 따른 결과다.
장고 1.4에서는 전 세계로 장고가 확산되며 타임존을 지원하
기 시작했으며, 브라우저 내에서도 앱 애플리케이션을 테스팅할
수 있는 모듈이 새로 추가됐다. 그러나 새로운 제약 사항도 존재
해, 장고 1.4부터 파이썬 2.4 이하 버전의 동작을 보장하지 않는
다. 또한 파이썬 3가 릴리즈된 지 3년이 지났지만 아직 지원되지
않고 있다. 아직 파이썬 2.6이 파이썬 개발의 주축인 점이 주요
요인으로 최근 파이썬 3를 지원하기 위한 개발이 진행 중이다.
향후 파이썬 3.3 의 릴리즈에 맞춰 장고 1.5가 등장하면 파이썬 3
가 지원될 것으로 기대된다.
한편, 장고의 발전을 위한 노력도 지속되고 있다. 대표적으로
구글 앱 엔진의 최신 릴리즈에서 Cloud SQL을 장고에서 사용할
수 있게 돼 OMR을 통해 Cloud SQL과 연동하고 빅 테이블을
이용할 수 있다. 또한 장고에서 개발된 앱을 구글 앱 엔진에서 배
포할 수 있다. 스크립트 언어의 약점인 속도 문제 개선을 위해 기
존 파이썬보다 속도가 빠른 pypy로 장고를 실행시켜 속도를 향
상시키려는 시도가 계속되고 있다.
한 가지 분명한 것은 장고는 파이썬의 대표 웹 프레임워크로서
의 위상을 계속 유지할 것이라는 점이며, 지금 이 순간에도 그 발
전은 계속되고 있다.
m a s o 131
from contact.models import Person
from django.contrib import admin
admin.site.register(Person)
<리스트 6> 관리 페이지에 데이터 모델 등록
from contact.models import Person # 생성한 데이터 모델 임포트
from django.http import HttpResponse
# Create your views here.
def contacts(request):
contact_list = Person.objects.all() # Person의 모든 데이터를
가져온다.
output = '<br>'.join( [p.full_name for p in
contact_list] )
return HttpResponse(output) # HttpResponse를 이용해 출력
<리스트 7> 간단한 장고 웹서비스
…생략…
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^contacts/$', 'contact.views.contacts'),
)
<리스트 8> contact을 위한 Urls.py 설정
<그림 2>
contact 앱 실행 결과

+ Recent posts