Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>

Contents

소개

Round Robin Database 의 줄임말이다. RRD는 데이터를 저장하고, 저장한 데이터를 시간흐름에 따라 보여주는 일을 한다. (예. 네트워크 트래픽, CPU 온도, 서버의 load 평균등) 시간을 기준으로 데이터를 저장하는 많은 시스템이 시간이 늘어날 수록 데이터베이스의 크기가 커지는 경향이 있지만, RRD는 자체적으로 아카이브를 관리하게 되므로 매우 작은 데이터베이스를 유지할 수 있다.

어떻게 보면 MRTG(:12)와 비슷하다고 할 수 있다. 실제 RRD 홈페이지의 소개글을 보면 RRD는 MRTG에서 아이디어를 얻어서 개발되었다는 문구를 찾아볼 수 있다.

그러나 당연하지만 MRTG를 참고해서 좀더 늦게 개발된 관계로 MRTG로는 힘들거나 불가능 했던 여러가지 기능이 확장되고 추가되었다.

네트워크 트래픽을 모니터링하는 예를 들어보자. 관리하고자 하는 요소가 In/Out bps와 In/Out pps라고 할때 MRTG로 이들을 관리하기 위해서는 bps와 pps를 위한 별도의 그래프가 만들어야 한다. 그러나 RRD로 할경우 하나의 그래프에 bps와 pps를 모두 관리할 수 있다. bps와 pps의 추이를 함께 비교함으로써 유입되거나 유출되는 패킷의 상태(예를 들자면 SYN 공격..)를 확인할 수 있다는 관점에서 생각해보면 그래프가 분리되는 MRTG로는 직관적으로 모니터링 하기가 힘들 수 밖에 없음을 알 수 있다. CPU 사용율을 모니터링 할때도 마찬가지다. RRD를 이용하면 User사용율, System사용율, Idle, Nice, I/O Wait 등의 정보를 하나의 그래프를 통해서 표현할 수 있다.

위의 장점들을 이용하면 임계치 선을 그어서, 임계치를 넘으면 다른 색으로 표시되게 하는등의 일도 할 수 있다. 보기에 좋다는 점도 무시할 수 없는 장점중 하나이다.

전체적으로 MRTG에 비해서 매우 유연하고, 확장성 있는 도구임을 알 수 있다

RRD 사용하기

설치

RRD 1.2 버젼을 기준으로 설명하도록 한다.

cgilib 설치

RRD의 설치를 위해서는 cgilib(버젼 0.5이상)이 설치되어 있어야 한다. http://www.infodrom.org/projects/cgilib 에서 cgilib의 최신버젼을 받을 수 있다. 압축을 풀면 configure 스크립트도 없이 그냥 make만 때리면 되는걸 알 수 있다. 컴파일하고 나면 libcgi.a가 만들어지는데, 적당한 경로에 옮기도록 한다. cgi.h 역시 나중에 rrd를 컴파일 할때 사용하게 되니 /usr/local/include 등에 옮겨 놓도록 한다.

RRD 설치

http://people.ee.ethz.ch/~oetiker/webtools/rrdtool 에서 최신의 rrd소스를 다운로드 받는다. 설치는 간단한데, 약간의 문제가 있다. 그것은 rrd가 libcgi의 공유라이브러리를 참조하게 되어 있다는 점이다. 이런 이유로 configure 스크립트를 돌릴 때 libcgi의 공유라이브러리를 찾을 수 없다는 메시지가 뜨면서 실패하게 된다. configure에서 libcgi를 테스트하는 부분을 주석처리 하도록 한다.

이렇게 해서 configure를 성공적으로 수행을 했는데, make할 때 다시한번 libcgi.so를 찾을 수 없다면서 컴파일이 실패하는 것을 볼 수 있을 것이다. 귀찮지만 직접 Makefile을 수정해서 정적라이브러리를 링크하도록 수정을 해주어야 한다.

RRD Tutorial

RRD에 대한 설명과 사용 방법에 대한 내용을 다룬다.

RRD에 대해서

Round Robin Database tool의 줄임말이다. Database tool이라는데에서 알 수 있듯이, RRD는 데이터들을 데이터베이스화 하고, 여기에서 값을 읽어와서 처리하는 일을 한다. 어떤 연속된 그래프를 그리는 일을 해야한다고 가정해보자. 그래프는 점의 연속으로 그래프를 그릴려면 점에 대한 좌표 데이터가 연속적으로 관리 될 수 있어야 할것이다. 그래서 데이터베이스로 부터 첫번째 좌표 데이터를 가져왔다면, 포인터를 옮겨서 두번째 좌표 데이터를 가져오는 일련의 작업을 반복함으로써 그래프를 그릴 수 있있게 될것이다.

RRD에서 다루는 데이터들

연속된 데이터를 다루기 위해서 사용할 수 있다. 보통은 시간순으로 연속된 데이터를 다루는데 가장 효과적인 툴이다. 즉 시간순으로 좌표값을 저장하고 필요할 경우 이것을 꺼내서 가공하는데 사용할 수 있다.

시간순으로 데이터가 저장될 수 있다면 어느 분야에나 사용이 가능할 것이다. 컴퓨터 분야라면 CPU의 성능추이라든지, 네트워크 트래픽의 변화등을 다루는데에 사용할 수 있다. 여기에서는 SNMP를 통해서 얻을 수 있는 네트워크 정보을 예제로 해서 RRD를 다루는 방법에 대해서 알아보도록 하겠다.

RRD로 할 수 있는 것들

RRD는 MRTG(:12)에서 아이디어를 얻어서 개발된 도구다. 그런 이유로 MRTG가 할 수 있는 일들을 효과적으로 수행할 수 있다. SNMP(:12)를 이용해서 데이터를 수집하고 수집된 데이터를 그래프화 해서 PNG나 JPG형태의 그래프로 출력하는 등의 일이 그것이다. RRD는 이러한 일들을 MRTG에서보다 더욱 효과적이고 다양하게 할 수 있다.

첫번째 예제 : 속도 변화 추이

그럼 예제를 만들어 보도록 하겠다.

여기에서는 한시간 동안 각 5분 단위로 자가용의 움직인 거리를 측정하고 이를 데이터로 남기도록 할 것이다. 남겨진 데이터는 쉽게 확인 가능하도록 그래프를 포함한 이미지로 출력시킬 것이다. rkerkrgelerlelrg

데이터 베이스 생성

RRD는 데이터베이스 툴이다. 이는 데이터를 저장할 데이터 베이스를 생성하고, 스키마를 지정해줘야 함을 의미한다. 데이터베이스 생성과 스키마 지정은 rrdtool 이라는 프로그램을 이용하면 된다.
  rrdtool create test.rrd             \
           --start 1129190400         \
           --step 300                 \
           DS:speed:COUNTER:600:U:U   \
           RRA:AVERAGE:0.5:1:24       \
           RRA:AVERAGE:0.5:6:10
  • create 옵션을 이용해서 새로운 데이터베이스를 생성할 수 있다. 데이터 베이스의 이름은 test.rrd로 정했다.
  • start를 이용해서 데이터가 쌓이는 시간을 명시해준다. 단위는 Unix Time으로 여기에서는 2005-10-13 17:00:00 분을 시작 시간으로 했다.
  • step는 데이터의 저장주기다.
  • DS는 Data Source의 줄임말로 데이터베이스에 쌓이게 될 데이터의 타입(필드타입)을 결정하기 위해서 사용된다. DS는 다음과 같은 형식으로 구성된다.
    DS:variable_name:DST:heartbeat:min:max
    1. variable_name : 데이터를 가리키는 이름으로 필드명이라고 생각하면 된다.
    2. DST : Data Source Type로 데이터의 형식(필드타입)이다. 다음과 같은 형식을 사용할 수 있다.
      • COUNT : 누적되는 증가값이다. SNMP(12)를 통해서 수집되는 대부분의 네트워크 트래픽 관련 데이터들이 이에 해당된다.
      • GAUGE : 현재 측정된 값을 저장한다. 디스크 사용율, 메모리 사용율, 온도등의 데이터가 이에 해당된다.
      • ABSOLUTE : 데이터의 변화율을 저장한다. 절대값이란 뜻에알 수 있듯이 바로 이전의 데이터를 항상 0으로 보고 측정된 변화율을 저장한다.
      • DERIVE : COUNT와 비슷하지만 음수까지 기록이 가능하다.
      • heartbeat
step에 지정된 간격만큼 데이터가 저장되어야 겠지만, 여러가지 이유로 정확한 step을 유지하면서 데이터가 저장되는 것은 사실상 불가능 하다. 대부분 시간 지연이 발생할 것이다. heartbead를 이용해서 어느정도의 시간지연을 무시할 것인지를 결졍할 수 있다. 보통은 step * 2만큼 지정된다. 위의 경우 600이 지정되었는데, 이는 300초만큼의 지연을 기다린다는 의미다. 예를 들어 12:10:00 에 데이터가 들어오기로 되어 있다면 12:14:59 까지의 데이터는 12:10:00의 데이터로 간주하고 입력한다는 뜻이 되겠다.
  • min,max: 데이터의 최대 최소 범위다. 알 수 없을 경우 U(Unknown)을 사용한다.

RRA

RRA는 Round Robin Archive 의 줄임말로, 데이터를 어떤방식으로 Archive화 할것인지를 결정하기 위해서 사용한다. RRA는 다음과 같은 포맷으로 작성된다.
RRA:CF:xff:step:rows
CF는 consolidation function 으로 데이터를 취합할 때, 어떤 연산을 적용할지를 결정한다. CF로 AVERAGE, MINIMUM, MAXIMUM, LAST중 선택할 수 있다. 만약 AVERAGE로 했다면, 데이터를 취합해서 그 평균값을 아카이브로 만들것 이다.

xff는 신경쓰지 말자. 0.5로 하면 된다.

steprows는 아카이브를 만드는 간격과 범위를 결정한다. 1:24는 24개의 데이터 값을 가지고 하나의 아카이브를 만들라는 뜻이다. 저장시간이 300초단위라면, 이 RRA 정보는 2시간의 데이터를 유지하는 아카이브를 생성하게 될 것이다. RRA:AVERAGE:0.5:1:600 로 정의 했다면, 5분단위 데이터가 600개로 이루어진 하나의 아카이브를 생산한다. 이는 약 2일정도의 데이터가 된다. RRA는 여러개를 만들 수 있는데, 이렇게 하면, 일단위 시간단위 연단위로 보여주기 위한 다양한 아카이브를 만들 수 있게 된다.

데이터 입력

이제 데이터를 입력 해보도록 하겠다. 준비된 데이터는 다음과 같다.
17:05  12345 KM
17:10  12357 KM
17:15  12363 KM
17:20  12363 KM
17:25  12363 KM
17:30  12373 KM
17:35  12383 KM
17:40  12393 KM
17:45  12399 KM
17:50  12405 KM
17:55  12411 KM
18:00  12415 KM
18:05  12420 KM
18:10  12422 KM
18:15  12423 KM

데이터 입력은 간단하다. rrdtool은 여러개의 레코드를 한번에 업데이트 시킬 수 있도록 지원한다.
rrdtool update test.rrd 1129190700:12345 1129191000:12357 1129191300:12363
rrdtool update test.rrd 1129191600:12363 1129191900:12363 1129192200:12373
rrdtool update test.rrd 1129192500:12383 1129192800:12393 1129193100:12399
rrdtool update test.rrd 1129193400:12405 1129193700:12411 1129194000:12415
rrdtool update test.rrd 1129194300:12420 1129194600:12422 1129194900:12423

데이터 가져오기

rrdtool fetch 를 이용하면 데이터베이스로 부터 데이터를 가져올 수 있다.
# rrdtool fetch test.rrd AVERAGE --start 1129190700 --end 1129194900
                          speed

1129191000: 4.0000000000e-02
1129191300: 2.0000000000e-02
1129191600: 0.0000000000e+00
1129191900: 0.0000000000e+00
1129192200: 3.3333333333e-02
1129192500: 3.3333333333e-02
1129192800: 3.3333333333e-02
1129193100: 2.0000000000e-02
1129193400: 2.0000000000e-02
1129193700: 2.0000000000e-02
1129194000: 1.3333333333e-02
1129194300: 1.6666666667e-02
1129194600: 6.6666666667e-03
1129194900: 3.3333333333e-03

그래프 만들기

rrdtool graph를 이용하면 간단하게 그래프를 생성할 수 있다.
#rrdtool  graph speed.png --start 1129190700 --end 1129194900  \
     DEF:myspeed=test.rrd:speed:AVERAGE \
     LINE2:myspeed#FF0000
다음은 위의 명령을 이용해서 생성된 그래프다.

https://lh6.googleusercontent.com/-qqzNlV-40yA/T-l7dnWm7hI/AAAAAAAACJM/afWhtrypLSE/s800/speed.png

  • DEF를 이용해서 해당 데이터페이스의 어떤 데이터를 가져올 건지를 정의 할 수 있다. 여기에서는 test.rrd 데이터베이스로 부터 speed 값을 가져오도록 명시하고 있으며, 변수명으로 myspeed를 사용하고 있다.
  • 다음은 그래프의 형태를 정의 하고 있다. myspeed가 가리키는 값들에 대해서 붉은색(#FF0000)의 LINE2타입의 그래프를 그릴 것을 명령하고 있다. 아래는 자주 사용되는 색들의 값이다.
      red     #FF0000
      green   #00FF00
      blue    #0000FF
      magenta #FF00FF     (mixed red with blue)
      gray    #555555     (one third of all components)
적당한 색의 선택은 gimp같은 무거운 프로그램 보다는 KColorChooser과 같은 전용의 간단한 프로그램을 이용하도록 하자.

그래프 수정

우선 기본단위 부터 수정을 해보도록 하자. 최종적으로 출력된 값은 다음의 공식에 의해서 구해진다.
((현재값) - (이전값))/300 = 초당 이동한 거리
그러므로 단위는 m/s 가 된다.

그런데 최초 우리가 입력한 데이터는 km단위이다. 고로 이것을 m단위로 환산할 필요가 있다. *100을 해주도록 하자.

# rrdtool  graph speed2.png --start 1129190700 --end 1129194900 --vertical-label m/s \
   DEF:myspeed=test.rrd:speed:AVERAGE    \
   CDEF:realspeed=myspeed,1000,\*        \
   LINE2:realspeed#FF0000
다음은 위의 명령을 이용해서 생성된 그래프다.

https://lh4.googleusercontent.com/-RXYu0Zgl4MA/T-l7gGji1qI/AAAAAAAACJU/bKzggrqZobI/s800/speed2.png

그럭저럭 볼만하게 바꾸긴 했지만 여전히 많은게 부족하다. 좀더 그럴듯하게 바꾸어 보도록 하자.
  • m/s 는 직관적으로 속도를 파악하기 힘들다 km/h로 바꿀 필요가 있다.
    m/s == (km/h * 3600)
  • 100kmh를 임계치로 해소 100kmh를 넘었을 경우 빨간색으로 표시되도록 해서, 어느 시점에서 과속을 했는지 확인하고 싶다.
    # 과속 확인용
    kmh가 100보다 큰지 비교한다.                                      (kmh, 100) GT
    만약 100보다 크다면 kmh을 리턴하고, 그렇지 않다면 0를 리턴한다.   (((kmh, 100) GT), kmh, 0) IF
    
    # 정상운행 확인용
    kmh가 100보다 큰지 비교한다.                                      (kmh, 100) GT
    만약 100보다 크다면 0을 리턴하고, 그렇지 않다면 kmh를 리턴한다.   (((kmh, 100) GT), 0, kmh) IF
다음 명령은 위의 코드를 포함시킨건데, 좀 복잡해 보일 것이다.
rrdtool graph speed3.png                             \
     --start 1129190700 --end 1129194900             \
     --vertical-label km/h                           \
     DEF:myspeed=test.rrd:speed:AVERAGE              \
     "CDEF:kmh=myspeed,3600,*"                       \
     CDEF:fast=kmh,100,GT,kmh,0,IF                   \
     CDEF:good=kmh,100,GT,0,kmh,IF                   \
     HRULE:100#0000FF:"Maximum allowed"              \
     AREA:good#00FF00:"Good speed"                   \
     AREA:fast#FF0000:"Too fast"

다음은 명령 실행 후 생성된 그래프다.

https://lh3.googleusercontent.com/-WHkcAFGBPvg/T-l7h1wGZFI/AAAAAAAACJc/0SfMmJGJp8E/s800/speed3.png

rrd server 를 이용한 외부 update

It is known, that rrd files are architecture-dependant. So, if you're updating external rrd files and graphing them via cacti, there's a need to make cacti access these rrd files, e.g. by nfs. This will not succeed when mixing architectures.

And nfs may not be the best choice for all cases. But with rrdtool 1.2.x there's a new feature, rrd server. Pasted from rrdtool homepage:

RRD Server

If you want to create a RRD-Server, you must choose a TCP/IP Service number and add them to /etc/services like this:

rrdsrv 13900/tcp # RRD server

Attention: the TCP port 13900 isn't officially registered for rrdsrv. You can use any unused port in your services file, but the server and the client system must use the same port, of course.

With this configuration you can add RRDtool as meta-server to /etc/inetd.conf. For example:

rrdsrv stream tcp nowait root /opt/rrd/bin/rrdtool rrdtool - /var/rrd

Don't forget to create the database directory /var/rrd and reinitialize your inetd.

If all was setup correctly, you can access the server with perl sockets, tools like netcat, or in a quick interactive test by using 'telnet localhost rrdsrv'.

NOTE: that there is no authentication with this feature! Do not setup such a port unless you are sure what you are doing.
For my local setup (RHEL 4.0), I had to modify this a bit. My /etc/services
Code:
rrdsrv         13900/tcp                       # RRD server
is standard. And I put
Code:
# default: off
# description: RRDTool as a service
service rrdsrv
{
        disable         = no
        socket_type     = stream
        protocol        = tcp
        wait            = no
        user            = cactiuser
        server          = /usr/bin/rrdtool
        server_args     = - /var/www/html/cacti/rra
}

as /etc/xinetd.d/rrdsrv. Then xinetd is updated to start rrdsrv. user should be set to the user defined in include/config.php. server_args should be set to cacti's rra directory. server contains the full path to rrdtool's binary. To verify this, try Code: telnet localhost 13900 info external.rrd assuming, that the rrd file "external.rrd" used in this howto is located in the ./rra directory. Now its time for some remote script to use this new feature. As an example, see Code:
#!/usr/bin/perl
use IO::Socket;

my $host = shift @ARGV;
my $port = shift @ARGV;
my $rrd  = shift @ARGV;

my $socket = IO::Socket::INET->new(PeerAddr=> $host,
                                PeerPort=> $port,
                                Proto=> 'tcp',
                                Type=> SOCK_STREAM)
                                or die "Can't talk to $host at $port";

my $_cmd = "update " . $rrd . " N:" . int(rand(10)) . ":" . int(rand(10)) . ":" . int(rand(10));
print $socket $_cmd . "\n";
close $socket;

my $_cmd = "update " . $rrd . " N:" . int(rand(10)) . ":" . int(rand(10)) . ":" . int(rand(10));
is only an example prepared for the "external.rrd" of our example. To use this for updating your own rrd files, this must fit to the data source definitions of your special rrd file. In our example, I put Code:
*/5 * * * *     cactiuser       /usr/bin/perl /var/www/html/cacti/scripts/rrd-remote-update.pl localhost 13900 external.rrd
into crontab to perform regular updates.

Disadvantages This handling has the great disadvantage, that you must configure the rrd file name to each single updating script. This rrd file name on the remote system must match the one on cacti's host. There's a good chance to mess things up when used for lots of rrds. But for some few files this may be appropriate.

Reinhard

관련문서

문서가 도움이 되었나요?