2010/12/21

신간 "거침없이 배우는 펄"

책이 나온지 한 일주일 됐지만 뒤늦게나마 소개합니다.



http://www.yes24.com/24/goods/4433208

이 책은 Learning Perl 5판 의 번역서이며 @keedi, @kiseok7, @saillinux 님에 의해 번역되었습니다.

개인적으로 이책에 대한 비평을 https://github.com/aero/perl_docs/wiki/Learning-perl-5th-review 에 올리고 있으니 같이 보시면 도움이 되실겁니다.

2010/11/13

Modern Perl 책 무료로 공개



Perl커뮤니티에서 chromatic이란 닉네임으로 활동하고 있는 분이 얼마 전 Modern Perl이란 책을 내놓았다.

Modern Perl이라 함은 여러버젼을 거쳐서 발전해온 Perl 5의 기능과 장점을 살려 어떻게 현대적 스타일로 Perl 프로그램을 작성할 것인가를 다룬다.

PHP가 웹프로그래밍언어로 인기를 끌기 전 한때 유행했던 Perl CGI시절 Perl에 대한 기억을 가지고 있는 사람들은 이 책을 본다면 새로운 Perl의 모습을 볼 수 있을 것이다. ( 본인도 예전에 Perl CGI가 유행하던 시절 한가닥했던 국내에서 개발된 Perl CGI기반 게시판 소스들을 받아서 본 적이 있는데 현대적 Perl프로그래밍 스타일에 비하면 거의 스파게티 혹은 쓰레기 코드 수준이어서 실망했던 기억이 있는데 그 시절 Perl은 Perl 5가 아닌 Perl 4혹은 Perl 3스타일 이었다고 할 수 있다.)


참고:
Modern Perl 무료책
Modern Perl Blog 

그리고 추가하여 더이상 구시대의 Perl을 사용한다는 말을 듣지 않으려면 http://perl-begin.org//tutorials/bad-elements/  도 함께 보시길 추천한다.

2010/11/10

흥미로운 프로젝트 OpenTSDB

오늘날 IT시스템들은 사용자와 시스템이 생산해내는 각종 컨텐츠와 데이터들의 홍수를 맞고 있다.

그래서 Hadoop처럼 NoSQL이니 하면서 Map,Reduce기술을 사용하여 대용량의 데이터를 빠르게 처리하기 위한 시도들이 나오고 있으며 이제는 그러한 기술들로 대용량 데이터를 다룬다는 것은 특별하지 않고 일상적인 일이 되어가고 있다.

IT운영조직은 방대해져 가는 IT서비스와 함께 방대해져 가는 IT자원들을 빈틈없이 모니터링해야 하는 상황에 이르렀는데 상용/오픈소스를 가릴 것 없이 고전적인 IT모니터링 솔루션들은 수천~수만대가 넘어가는 IT인프라를 모니터링하고 그 이력과 성능치들을 저장하고 검색하기에는 역부족인 상황이 다가오고 있다.( 일부 솔루션들은 분산화된 Polling 환경을 지원하기 하나 결국에 병목은 뒷단의 고전적인 데이터스토리지인 RRD file이나 RDBMS에서 오게 됨)


이러한 규모의 문제를 만나려면 적어도 수천대 이상의 서버/장비들을 운용해보지 않는 이상 힘들겠지만.. 그런데 이런 상황에 희망을 주는 프로젝트가 생겼다.

이름 하여 OpenTSDB

해당 싸이트는 OpenTSDB의 목적을 다음과 같이 얘기하고 있다.

OpenTSDB is a distributed, scalable Time Series Database (TSDB) written on top of HBase. OpenTSDB was written to address a common need: store, index and serve metrics collected from computer systems (network gear, operating systems, applications) at a large scale, and make this data easily accessible and graphable.

앞으로 이것이 모니터링에 있어 규모의 문제에 부딪힌 이들에게 희망을 줄 수 있을듯하다.

2010/11/08

screen session에 이름붙여 사용하기

UNIX에서 작업하다 보면 어떤 작업을 그대로 놔두고 로그아웃 했다가 나중에 다시 들어와서 보려면 가상 터미널 프로그램인 screen을 종종 사용하게 된다.

터미널에서 screen 명령을 내리면 새로운 세션이 생성되어서 들어가고 이것을 백그라운드?상태로 떼어내려면 ctrl+a를 누른후 d키를 누르면 원래 터미널로 돌아온다. 그리고 다시 떼어낸 특정 screen session에 들어가려면 screen -ls 명령을 내린후 세션넘버를 찾아서 screen -r 명령을 통해서 다시 진입한다.

aero@host:~$ screen -ls
There are screens on:
        7295.pts-0.sweetpea     (2010년 11월 08일 13시 56분 14초)       (Detached)
        7271.pts-0.sweetpea     (2010년 11월 08일 13시 55분 35초)       (Detached)
2 Sockets in /var/run/screen/S-aero.

aero@host:~$ screen -r 7271

하지만 이렇게 하면 어느 세션에 어떤 작업을 하는지 나중에 헷갈릴 수 가 있는데 세션번호 대신에 특정 의미있는 단어들을 세션이름으로 지정할 수 있으면 편리할 것이다.그렇게 하려면 다음 처럼 screen -S 세션이름 명령으로 세션이름을 지정해서 새로운 세션을 지정하면 된다.


aero@host:~$ screen -S DB
[detached from 7328.DB]
aero@host:~$ screen -S WEB
[detached from 7347.WEB]
aero@host:~$ screen -ls
There are screens on:
        7347.WEB        (2010년 11월 08일 14시 00분 33초)       (Detached)
        7328.DB (2010년 11월 08일 14시 00분 23초)       (Detached)
2 Sockets in /var/run/screen/S-aero.
aero@host:~$ screen -r DB

이제 -r 옵션에 세션이름을 지정해서 해당세션을 복구할 수 있다.

그러면 이미 떠있는 세션이름을 바꿀려면 어떻게 해야 할까?
방법은 두가지가 있다.

첫번째 방법은 해당 screen session에 들어간 다음 수동으로 ctrl+a 를 누른후 :sessionname 새로운세션이름 을 써서 바꾸는 방법이며 두번째 방법은 아래처럼 screen -ls에서 세션번호나 세션이름을 알아낸 다음처럼 -S 옵션으로 해당 세션번호나 이름을 지정하고 해당 세션에 명령을 날리는 -X 옵션으로 sessionname 새로운세션이름 수동으로 하던 명령을 날리는 것이다.

aero@host:~$ screen -ls
There is a screen on:
        7374.pts-0.sweetpea     (2010년 11월 08일 14시 03분 47초)       (Attached)
1 Socket in /var/run/screen/S-aero.

aero@host:~$ screen -S 7374 -X sessionname aero
aero@host:~$ screen -ls
There is a screen on:
        7374.aero       (2010년 11월 08일 14시 03분 47초)       (Detached)
1 Socket in /var/run/screen/S-aero.

2010/11/03

Parallelize a job with Parallel::Forker

In Opsview, Master and Slave monitoring servers collect perfdata from servers and parse and write to rrd files.

but I encountered rrd file writing timeout(12 seconds) as the number of rrd files increased.
So I started investigating where the performance bottleneck could be occurring ( We have multi-core CPU and there are no cpu or I/O bottlenecks ) and parallelized the time-consuming job in insert.pl like this with Parallel::Forker module.

Performance increases almost linearly with increasing N until you meet the limit of I/O bandwidth.


Original

JOB FLOW
perfdata in array -> iteration ( parse, write )
 [ @perfdata ]       [ processdata(@perfdata) ]

CODE
processdata(@perfdata);
debug( 5, 'INSERT nagiosgraph exited' );




Parallelized

JOB FLOW
perfdata in array -> split array into N -+-> array 0  -> iteration ( parse, write ) 
                                         +-> array 1  -> iteration ( parse, write ) 
                                         +->    .     -> iteration ( parse, write ) 
                                         +-> array N-1-> iteration ( parse, write ) 

CODE
use Parallel::Forker;

my $fork = Parallel::Forker->new;
$SIG{CHLD} = sub { Parallel::Forker::sig_child($fork); };
$SIG{TERM} = sub { $fork->kill_tree_all('TERM') if $fork && $fork->in_parent; die "Quitting...\n"; };

my $n = 4;
my @n_perfdata;

my $size = int(@perfdata/$n);
foreach ( 0 .. $n-1 ){
    $n_perfdata[$_] = [ splice @perfdata, 0, $size ];
}
push @{$n_perfdata[$n-1]}, @perfdata;

foreach ( 0..$#n_perfdata ) {
    $fork->schedule ( name => $_, run_on_start => \&child_sub )->run;
}

$fork->wait_all();

debug( 5, 'INSERT nagiosgraph exited' );

sub child_sub {
    processdata( @{ $n_perfdata[ $_[0]{name} ] } );
}

2010/10/07

I18N patch for Opsview 3.9.0

I love Opsview for my IT infrastructure monitoring system.
But It still has some problems to support non-ascii characters or languages. :(
So I'v made patch for the newest Opsview 3.9.0.

My patches are

http://gist.github.com/614513
http://gist.github.com/614511

I hope Opsview will apply these patches to thier product.

2010/09/23

Perl 스크립트에 필요한 모듈 같이 넣기 App::FatPacker

Perl 스크립트를 만들다 보면 기본 Perl 배포본에는 기본으로 들어가는 코어모듈 이외에 추가로 모듈을 설치하여 사용하게 되는데, 만약 자신에 배포해야 하는 스크립트에 어떤 모듈을 사용해야 하지만 이것을 사용자가 사용할 때 모듈에 대한 의존성을 신경 쓰지 않으며 추가로 모듈을 설치해야하는 수고를 덜어주고 싶을 때가 있다.

이럴 때 유용하게 써먹을 수 있는 모듈이 바로 App::FatPacker 모듈이다.

그럼 예를 들어서 한 번 App::FatPacker를 사용해보자.
CPAN에는 Linux머신의 다양한 성능정보 및 시스템정보를 접근할 수 있는 Sys::Statistics::Linux 라는 훌륭한 모듈이 있다. ( vmstat,iostat 명령등의 결과 ,/proc 디렉토리를 수동으로 노가다 파싱해서 수치를 뽑아내서 썼던 사람이 보면 이렇게 잘 차려진 밥상을 보며 허무감의 눈물을 흘릴만한~ )

예를 들어 Sys::Statistics::Linux::SysInfo 를 사용하여 Linux머신의 각종 정보를 뽑아내는 Perl 스크립트를 다음과 같이 만들었다고 했을 때

<sysinfo.pl>
#!/usr/bin/env perl
use strict;
use warnings;
use Sys::Statistics::Linux::SysInfo;

my $lxs = Sys::Statistics::Linux::SysInfo->new;
my $info = $lxs->get;
print "$_ : $info->{$_}\n" for keys %$info;

<실행결과 예>
swaptotal : 11881464 kB
arch : x86_64
version : #43-Ubuntu SMP Thu Sep 16 16:05:42 UTC 2010
release : 2.6.32-24-server
hostname : somehost
countcpus : 8
domain : (none)
idletime : 63d 23h 59m 42s
kernel : Linux
memtotal : 4055708 kB
uptime : 7d 23h 30m 3s

이것을 사용하려면 Sys::Statistics::Linux 모듈을 따로 설치해야 한다. 만약에 수백,수천대의 서버에 복사해서 각 시스템의 정보를 뽑아오는 작업을 한다고 하면 그 많은 서버에 이 간단한 스크립트 하나를 위해 Sys::Statistics::Linux 를 일일이 설치하기는 부담스럽고 귀찮을 것이다.

바로 이럴 때 App::FatPacker가 빛을 발한다. 그러면 위에서 예를 든 sysinfo.pl 스크립트에 Sys::Statistics::Linux 모듈을 포함시키는 작업을 진행해보자.

App::FatPacker 모듈을 설치한 다음

$ fatpack trace sysinfo.pl
라고 명령을 내리면 필요한 추가 모듈을 분석하여 fatpacker.trace 란 파일을 생성한다.

$ fatpack packlists-for `cat fatpacker.trace` > packlists
의 명령으로 fatpacker.trace 파일에서 포함할 파일의 리스트를 packlists 파일로 뽑는다.

$ fatpack tree `cat packlists`
packlists 에 있는 모듈 파일들을 패키징 할 준비를 한다.

$ (fatpack file; cat sysinfo.pl) > sysinfo.packed.pl
sysinfo.pl에 모듈을 같이 패키징해서 sysinfo.packed.pl 이란 스크립트를 생성한다.
(여기서 홈디렉토리에 ~/lib 디렉토리가 없다고 에러가 나는 경우가 있는데 이때는 lib 디렉토리를 그냥 만들어 주면 된다.)

이제 sysinfo.packed.pl 스크립트는 자체적으로 의존성 있는 모듈을 파일의 첫 부분에 적절히 패키징하여 포함하므로 따로 필요한 모듈이 설치되어 있지 않아도 잘 실행되게 된다.

주의점:
App::FatPacker는 순수한 Perl모듈에 대해서만 동작한다. C라이브러리등과 연동되어서 돌아가는 XS모듈은 동작하지 않는다. 그리고 만능이 아니므로 비교적 크기가 작고 적은 수의 모듈에 대해서만 사용하는 것이 좋다. 아주 많은 모듈을 포함하고 Perl이 독립적으로 패키징되어서 돌아가도록 하고 싶으면 PAR::Packer 모듈을 참고하길 바란다.

2010/09/16

설치된 Perl CPAN 모듈 목록 뽑아서 다시 설치하기

Perl 버젼이 새로나오면 perlbrew를 이용해서 새로운 버젼의 Perl을 설치할 경우 문제가 되는 것은 기존에 설치한 모듈들을 어떻게 다시 다 설치할 것 인가이다.

모듈을 별도의 디렉토리를 지정해서 설치해서 사용하면 모듈의 Path를 그대로 지정해주면 사용할 수 있겠지만 여기서 문제는 C라이브러리 및 코드와 연동되어 컴파일되어 설치되는 일명 XS모듈들이다. 이런 모듈들은 Perl 버젼에 따라 호환이 되지 않은 경우가 있기 때문에 깔끔하게 다시 설치해주는 것이 좋은데 그러려면 일단 현재 설치된 모듈들의 목록을 뽑아야 한다.

현재 설치된 모듈들의 목록을 얻으려면 ExtUtils::Installed 모듈을 이용하여 다음과 같이 명령을 내린다.

perl -MExtUtils::Installed -le 'print for ExtUtils::Installed->new->modules'

그러면 다음처럼 설치된 모듈들의 목록이 쭉 출력되게 되는데
Algorithm::Diff
Algorithm::Permute
Any::Moose
AnyEvent
AnyEvent::HTTP
App::CPAN::Fresh
App::Cmd
.
.
.


다음과 같이 리다이렉션으로 목록을 텍스트 파일로 저장해 놓고

perl -MExtUtils::Installed -le 'print for ExtUtils::Installed->new->modules' > modules.txt

perlbrew로 새 버젼의 Perl을 설치한 다음

cat modules.txt | xargs cpan -i

명령이나 cpanm 을 사용한다면

cat modules.txt | cpanm -v

명령을 내리면 목록의 모듈들을 모두 다시 설치한다.

2010/08/26

블로그 변경

귀차니즘으로 인해 기존의 설치형 블로그( http://aero.sarang.net/blog )를 버리고 옮김