리눅스 시스템 모니터링 시스템 최적화


글쓴이 : 문태준

대한매일 뉴스넷 서비스지원팀장 (http://www.kdaily.com, http://seoul.co.kr)

taejun@tunelinux.pe.kr

http://tunelinux.pe.kr, http://database.sarang.net 운영자



0. 들어가며

이글은 효율적으로 시스템을 모니터링하고 어떻게 리눅스 서버를 최적화할 수 있을까에 대해서 다룬다.


첫 번째 장에서는 현재 시스템이 어떻게 운영되고 있고 어디에서 문제가 생기고 있는지를 알기 위한 시스템 모니터링에 대해서 설명을 한다. 시스템관리의 출발은 현재의 상태를 제대로 파악하고 여기에서 시스템을 최적화하기 위해 무엇을 해야하는지 파악을 해야하는 것이다. 프로세스, 메모리, 디스크 I/O와 네트워크의 모니터링에 대해서 알아본다.


두 번째 장에서는 운영체제가 부팅을 하면서부터 시작하는 작업인 로그파일 기록에 대하여 알아본다. 현재의 시스템에서 발생하고 있는 모든 작업은 로그를 통해 기록을 남고 문제가 발생했을 경우 가장 먼저 해야 할 작업이 로그분석작업이다. 이와 더불어 계속 불어나는 로그파일을 어떻게 효율적으로 처리할 수 있는 지에 대해서 알아보겠다.


세 번째 장에서는 앞의 두 강좌를 통해 시스템의 활동을 분석하는 방법에 대해서 배운 것을 기초로 하여 시스템 모니터링을 자동화하는 방법에 대하여 설명을 할 것이다. 시스템관리자가 해야 할 역할이 많은데 언제나 사무실에 앉아서 top만 치고 있을 수는 없지 않은가. 또 시스템이 한 대라면 모르겠지만 적게는 몇 대에서 수십, 수백대가 되는 경우 시스템관리를 한다고 애인까지 만나지 못하고 더운 여름을 전산실 에어컨과 함께 밀월을 즐길 수는 없을 것이다.


네 번째 장에서는 운영체제의 설치 및 서비스를 위한 프로그램 설치과정과 관련되어 필요한 최적화 방법에 대해서 설명을 할 것이다. 효율적인 서비스를 위해서는 설치 과정부터 필요한 프로그램만 설치하고 불필요한 프로그램을 제거를 하여 시스템의 성능은 물론 보안으로부터 대처를 할 수 있을 것이다.


마지막 장에서는 커널 차원에서의 튜닝과 보안에 대해서 다루겠다. 커널은 운영체제의 핵심부분으로 메모리 관리, 프로세스 관리, 파일 시스템 관리 등 모든 작업을 배후에서 처리하고 있는 부분이다. 그러므로 커널의 작동 원리를 이해하면 현재의 시스템에 대해서 좀 더 깊은 지식을 가질 수 있고 시스템 성능과 관련한 여러 가지 옵션들을 효율적으로 조정하여 같은 하드웨어를 가지고도 더 좋은 성능을 낼 수 있다.



기본기를 다지자

전산학의 빅5는 컴퓨터 구조론, 운영체제, 자료구조와 알고리즘, 프로그래밍 언어론 및 컴파일러, 데이터베이스론이라고 흔히 이야기를 한다. 소프트웨어 개발자의 경우 단순하게 문법을 잘 외운다고 해서 프로그래밍 능력이 높은 것은 아니다. 효율적으로 프로그램을 설계하고 적절한 알고리즘을 사용하는 것이 중요하고 하드웨어와 운영체제에 대해서 더 깊이 알고 있을수록 뛰어난 프로그램을 작성할 수 있다. 시스템 관리자의 경우도 여기에서 벗어날 수 없다. 운영체제가 어떤 방식으로 작동을 하고 있는지, 어떻게 인터넷이라는 무한한 공간에서 컴퓨터가 자료를 주고 받는지에 대한 기본 지식이 풍부할수록 시스템 관리도 단순한 세팅에서 벗어나 제대로 된 시스템 관리를 할 수가 있는 것이다. 물론 여기 글을 쓴 것처럼 그 중요성을 알고 있지만 생각만큼 쉬운 작업은 아니고 많은 노력이 필요한 작업이며 이 글을 쓰는 필자도 운영체제 및 네트웍에 대해서 뛰어난 고수는 아니다. 그렇지만 계속 발전하기 위해서는 기본기가 탄탄해야 한다는 생각을 가지고 있으며 다른 사람들과 같이 노력을 해 가고자 한다.


본 글과 관련하여 궁금한 점은 본인이 운영하는 사이트 등을 통하여 같이 논의를 했으면 좋겠다. 글을 시작하기에 앞서 본인이 이러한 글을 정리할 수 있도록 수많은 자료를 제공해준 인터넷의 수많은 사람들에 대하여 감사한 마음을 전한다. 개인의 지식은 한정될 수 밖에 없지만 네트웍을 통해 공유한 지식은 전인류의 자산이 될 것이다.





1. 시스템 모니터링 하기

- 시스템이 어떻게 움직이고 있는가?


1. 시스템 모니터링 결과에 대해서 정확히 알고 있자

ㅇ 메모리가 왜 이리 모자라지? - free 에 대하여

밤에 잠을 자고 있는데 사무실에서 급하게 전화가 왔다. 웹서비스가 엄청 느려져서 도저히 웹사이트를 볼 수가 없다는 것이다. 잽싸게 일어나서 컴퓨터를 켰다. 원격으로 접속을 해서 서버를 관찰한다. 가장 먼저 무엇을 해야할까? 어디에서 시스템이 느려지고 있는지 찾아야한다. 그리고 평상시의 상태와 비교를 해야한다. 시스템 관리자라면 흔히 일어나는 경우이다. 시스템 관리의 첫 출발은 평상시에 계속 시스템의 상태를 파악하고 모니터링 결과를 비교하는 작업이다. 또한 나온 결과를 제대로 파악하고 있어야하는데 주기적으로 시스템을 모니터링해놓고도 그 결과를 엉뚱하게 해석한다면 전혀 다른 결과를 초래할 수 있다.


예를 한번 들어보자. 리눅스에서 메모리를 점검하기 위해 흔히 free를 사용한다. 그런데 free의 결과를 잘못 이해하는 경우가 상당히 많고 필자도 마찬가지였다. 아래 결과를 보자. 512M의 메모리를 가진 시스템이다.



$ free

             total       used       free     shared    buffers     cached

Mem:        513368     503180      10188          0       3772     332740

-/+ buffers/cache:     166668     346700

Swap:      1028152      84908     943244



이상하게 쓰는 것도 없는데 513M에서 현재 사용하는 것이 503M이다. 아무래도 시스템에 문제가 생겼나해서 재부팅을 했는데 조금 지나자 또 대부분의 메모리를 used에서 잡아먹는다. 에라 모르겠다 메모리를 512M 더 추가시키자. 농담이 아니라 실제로 충분히 발생할 수 있는 상황이다.


디스크를 읽는 일은 메모리에 비해서 아주 느리다. 수많은 사람들이 접속해서 ls 명령어를 모두 디스크에 읽어서 실행을 한다면 그 시스템의 속도가 아주 느려질 것이다. 물론 여기서는 ls라는 간단한 명령을 말했지만 시스템의 자원을 엄청 잡아먹는 프로그램이라면 문제가 또 달라질 것이다. 이런 경우 디스크에서 한번 읽어들인 정보를 메모리에 일정기간 보관하고 있다면 처음 읽을때만 속도가 느리지 이후에는 전반적으로 빨라질 것이다. 이것을 가르켜 디스크 버퍼링이라고 하며 이런 목적으로 사용되는 메모리가 위에서 나오는 버퍼 캐쉬이다.**주1 (실제로 버퍼 캐쉬는 파일을 버퍼링하는 것은 아니고 디스크 입출력의 가장 작은 단위인 블록을 버퍼링한다. 블록 디바이스 드라이버가 사용하는 데이터 버퍼를 가지고 있는 것이다) 만일 캐쉬의 크기가 고정되어 있다면 그 크기가 너무 커도 메모리 부족현상이 생길 수 있을 것이고 지나친 스와핑을 발생하게 해서 시스템이 느려질 가능성이 크다. 리눅스에서는 자동적으로 모든 램의 빈 공간을 버퍼 캐쉬로 사용하여 메모리를 효율성을 높이고 있으며 프로그램에서 많은 메모리를 필요로 하는 경우에는 자동으로 캐쉬의 크기를 줄인다. 그렇다면 위에서 실제로 사용가능한 메모리는 free+buffers+cached 이다. -/+ buffers/cache: 이 줄이 이러한 내용을 반영하고 있다. 일반적인 리눅스 시스템관리와 관련된 서적에는 이 부분에 대하여 지적을 한 곳이 거의 없으며 맨페이지에도 이런 설명은 아직 찾지 못했다. 운영체제와 커널의 원리에 대해서 모른다면 같은 결과를 놓고도 정말 엉뚱한 분석을 할 수 있는 것이다. 위의 내용을 아는 분이라면 모르겠지만 이 글을 보는 사람들중에 위의 내용을 몰랐던 사람들은 정말 모르고 있었구나 하는 생각이 들지 않을까?



2. 현재 시스템의 문제를 찾자

시스템의 성능은 현재의 시스템 자원을 여러 가지 프로그램들의 요청에 대하여 얼마나 효율적으로 적용을 하는가에 달려있다. 요즘처럼 인터넷이 보편화된 상황에서 네트워크도 중요한 부분이기는 하지만 일반적으로 성능에서 가장 중요한 시스템 자원은 CPU, 메모리, 디스크 입출력이다. 그래서 위의 부분들을 중심으로 성능에 문제가 생기기 전에 미리 시스템을 분석하는 것이 중요하다. 시스템에 문제가 생긴다면 다음을 먼저 점검해보자


ᄋ CPU 문제 점검 - top, ps, uptime, vmstat, pstree 등

ᄋ 메모리 문제 점검 - free, vmstat 등

ᄋ 메모리에 문제가 없다면 디스크 I/O 점검 - df, du, 쿼타 등

ᄋ 디스크와 메모리에 문제가 없는데도 시스템에 문제가 생기면 CPU의 오버헤드에 문제가 있을 가능성이 크다

ㅇ 네트웍 문제 점검 - netstat, ping, traceroute, tcpdump 등


3. 사전 점검 사항

시스템이 정상적으로 작동하고 있을 때 정기적으로 모니터링을 해 두어야 시스템에 문제가 생겼을 때 대처를 할 수 있다. 아래를 참고로 하여 주기적으로 시스템 모니터링 결과를 모아두자.


ᄋ 주요 사용자들한테 성능이 괜찮다는 동의를 먼저 얻어야한다. 그리고 시스템 성능을 계속 유지할 수 있도록 정기적으로 점검한다.

ᄋ 시스템 accounting 프로그램을 이용한다. 시스템에서 CPU, I/O, 메모리 집약적인 프로그램들을 알고 있어야한다. (**주2)


$ sa


   75563  169479.02re     510.44cp         0avio       506k

   14056     450.37re     448.85cp         0avio       497k   webalizer

     361   91931.12re      37.86cp         0avio      1355k   httpd*

     275       7.50re       5.38cp         0avio       402k   gawk

   14056     455.55re       4.95cp         0avio       438k   weblog

   14226     588.92re       2.57cp         0avio       437k   sh

      11      18.88re       2.45cp         0avio       332k   slocate

     162     670.85re       1.46cp         0avio       666k   in.telnetd

    2298      45.83re       1.09cp         0avio      2858k   mysqld*

     325       0.86re       0.76cp         0avio       642k   ps

     358    1185.61re       0.66cp         0avio       454k   bash

    1419       0.48re       0.47cp         0avio       283k   rmmod


accounting 결과 예제



ᄋ vmstat 등의 프로그램을 이용 I/O연산이 얼마나 분산되어있는지, CPU가 작동하지 않고 노는 시간(idle)은 얼마인지, 정상적인 부하가 걸릴 경우 메모리를 얼마나 사용하고 있는지 확인한다.


주기적으로 시스템 상황을 자동으로 모니터링하는 방법에 대해서는 세 번째 강좌에서 설명을 할 예정이다.




4. 문제가 발생했을 경우의 대처 방법

시스템이 정상적으로 작동하고 있을때 제대로 모니터링을 하고 분석을 해 두었다면, 사용자가 불평하거나 문제가 터지기 않더라도 언제 시스템의 성능이 나빠질지 알 수 있다. 그러면 시스템에 문제가 발생하였을 경우에는 어떻게 대처를 해야 할까?


ᄋ 어떤 프로그램을 실행하고 있으며 어떻게 사용하고 있는가? 현재 시스템에서 주요하게 제공하는 서비스는 어떤 것인가? 예를 들어 NFS를 통해 파일에 접근을 한다면 네트웍 성능이 떨어지는게 문제의 한 부분이라는 것을 알 수 있다. 웹서비스를 한다면 시스템 자체의 부하가 아니라 네트웍 회선의 문제로 속도가 느려질 가능성도 있다.

ᄋ uptime을 이용하여 시스템의 부하를 확인한다. 시스템의 부하가 어떤 추세로 움직이고 있고 어느 정도 수치로 작동하는지 확인을 한다. 웹서비스의 경우 보통 낮시간대에 접속이 폭주하므로 S자 형태로 시스템 부하가 변화될 것이다. 그런데 최대 접속할 시간이 아닌데도 시스템의 부하가 높아진다면 불필요한 프로그램이 계속 돌면서 시스템의 자원을 소비할 가능성도 있고 DOS 공격 등을 받고 있을 가능성도 크다.


$  uptime

  9:23pm  up 61 days,  5:23,  1 user,  load average: 0.02, 0.05, 0.00



ᄋ ps와 top를 활용한다.

- 디스크 액세스나 페이징을 기다리고 이는 프로세스가 있는가? 그렇다면 I/O와 메모리를 점검하자. 리눅스에서 프로세스 대기 상태는 인터럽트 허용과 인터럽트 금지의 두가지 형태가 있다. 세마포어를 기다리거나 파일을 읽을 수 있게 되길 기다리는 것처럼 자원을 기다리는 일반적인 대기상태는 대개 인터럽트로 처리가 가능하다. (인터럽트가 허용되는 sleep 상태는 ps,top 등에서 S로 나타난다.) 그렇지만 인터럽트가 금지되는 대기상태는 스왑파일에서 메모리로 페이지를 읽어들이는 것과 같이 임계지역에서 일이 끝마치기를 기다리고 있는 상태이다. 프로세스 상태에서 D 는 uninterruptible sleep로서 page fault 등을 의미하며 page fault 등을 통해 I/O중인 상태를 나타낸다. W는 has no resident pages를 의미하며 프로세스가 스왑아웃된 상태를 나타낸다. (W는 커널 프로세스에 대해서는 정확히 동작을 하지않는다.

- CPU와 메모리를 가장 많이 사용하는 프로세스를 찾으면 부하를 분산시키는데 도움이 될 것이다.


$ ps auxw

USER       PID %CPU %MEM   VSZ  RSS TTY      STAT START   TIME COMMAND

root         1  0.0  0.0  1120   68 ?        S    Jun17   0:06 init [3]

root         2  0.0  0.0     0    0 ?        SW   Jun17   0:00 [keventd]

root         3  0.0  0.0     0    0 ?        SW   Jun17   0:00 [kswapd]

root         4  0.0  0.0     0    0 ?        SW   Jun17   0:00 [kreclaimd]

root         5  0.0  0.0     0    0 ?        SW   Jun17   0:32 [bdflush]

root         6  0.0  0.0     0    0 ?        SW   Jun17   0:02 [kupdated]

root       351  0.0  0.0  1164  284 ?        S    Jun17   0:01 syslogd -m 0

root       360  0.0  0.0  1728  356 ?        S    Jun17   0:00 klogd

root       388  0.0  0.0  1156  220 ?        S    Jun17   0:00 inetd

root       402  0.0  0.2  3824 1452 ?        S    Jun17   3:09 /usr/sbin/snmpd

named      416  0.0  0.3  3376 1904 ?        S    Jun17   0:27 named -u named




$ top

  7:34pm  up 14:19,  3 users,  load average: 1.20, 0.54, 0.20

57 processes: 53 sleeping, 4 running, 0 zombie, 0 stopped

CPU states: 94.6% user,  5.3% system,  0.0% nice,  0.0% idle

Mem:   513368K av,  321260K used,  192108K free,       0K shrd,    9208K buff

Swap: 1028152K av,  115000K used,  913152K free                  270924K cached


  PID USER     PRI  NI  SIZE  RSS SHARE STAT  LIB %CPU %MEM   TIME COMMAND

12436 root      20   0  6428 6428  1564 R       0 13.1  1.2   0:00 cc1

3570 nobody    12   0 11148 6140  5016 R       0  2.5  1.1   0:09 httpd

12435 root       8   0  1528 1528   388 S       0  1.3  0.2   0:00 cpp

4185 root       9   0   512  328   312 S       0  0.3  0.0   0:01 sshd2

11364 taejun    10   0   876  876   680 R       0  0.3  0.1   0:00 top

    1 root       8   0   120   68    68 S       0  0.0  0.0   0:04 init

    2 root       9   0     0    0     0 SW      0  0.0  0.0   0:00 keventd

    3 root       9   0     0    0     0 SW      0  0.0  0.0   0:03 kswapd

    4 root       9   0     0    0     0 SW      0  0.0  0.0   0:00 kreclaimd

    5 root       9   0     0    0     0 SW      0  0.0  0.0   0:01 bdflush

    6 root       9   0     0    0     0 SW      0  0.0  0.0   0:00 kupdated

  348 root       9   0   208  156   156 S       0  0.0  0.0   0:00 syslogd

  357 root       9   0   608    4     4 S       0  0.0  0.0   0:00 klogd

  371 root       8   0   180  124   120 S       0  0.0  0.0   0:00 crond



ᄋ vmstat를 이용한다. (vmstat 5 5)


$ vmstat 5 5

   procs                      memory    swap          io     system         cpu

r  b  w   swpd   free   buff  cache  si  so    bi    bo   in    cs  us  sy  id

3  0  0 115000 189428   9220 272608   1  28    10    36  108    25   2   0  98

1  0  0 115000 189972   9220 272680   0   0     0   205  196   416  95   5   0

1  0  0 115000 187060   9220 272740   0   0     0   157  156   229  95   5   0

2  0  0 115000 194852   9220 272856   0   0     0   149  142   229  96   4   0

Posted by 큰바우
: