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



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





- vmstat에서 첫 번째 줄은 부팅 이후의 각 통계치에 대한 평균치를 보여주는데 이것은 무시해야 한다. 두 번째 줄부터 보면 된다.

- cpu에서 시스템에서 사용하는 cpu시간이 지나치게 높다면(50% 이상) 디스크 I/O에서 문제가 있을 가능성이 크다. 해당 프로그램의 소스코드를 구할 수 있다면 프로그램에서 얼마나 효율적으로 I/O를 사용하는지 확인해 보아야 한다. vmstat에서 sy 항목은 system time을 의미하며 커널모드로 넘어간 상태이다.

- 시스템 전체의 부하가 높은데도 cpu에서 휴지시간(idle time, id 항목)이 일반적으로 10%를 넘는다면 I/O나 메모리에 문제가 있을 가능성이 크다.

- 휴지시간이 항상 0이라면 CPU를 완전하게 100% 사용하고 있는 상태이다. CPU의 기능을 최대한 활용하는 것은 좋은 현상이다. 그런데 항상 100% 로 바쁜 상태라면 어떤 작업이 계속 축적되고 있다는 것이며 CPU의 과부하를 의미한다. CPU를 계속 사용하고 있는 프로세스를 찾아야한다.

- 디스크의 활동이 분산되지 않았다면, I/O 작업을 효율적으로 분산시켜야한다. 그런데 현재 리눅스용 vmstat에서는 이에 대한 정보는 나오지 않는다. 다른 유닉스의 경우에는 iostat나 sar을 이용하는데 인터넷에서 패키지를 받아서 설치할 수 있다. 이러한 프로그램이 sysstat 로 리눅스용 sar, iostat 패키지이다. 사이트 주소는 다음과 같다. (최근 레드햇 배포판 등에는 들어가고 있다)

http://perso.wanadoo.fr/sebastien.godard/



아래에서는 현재 두 개의 HDD가 장착되어 있는 시스템의 상태를 보여준다.



$ iostat

Linux 2.4.4 (tunelinux.pe.kr) 07/08/01



avg-cpu: %user %nice %sys %idle

5.55 0.00 1.20 93.26



Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn

dev8-0 6.06 9.49 102.23 50185324 540747898

dev8-1 1.99 1.51 25.05 7964700 132509976





위 사항에서 해당하는 것이 없고 메모리와 I/O 관련 튜닝을 할 필요가 없다고 분석이 되면 CPU쪽에서 과부하가 걸린 상태이다. CPU 과부하의 경우 대처할 수 있는 몇가지 방법은 있지만 CPU의 과부하는 메모리와 I/O 문제로 나누어지기 때문에 찾아내기 힘든 부분이다.



CPU의 과부하를 줄일 방법에 대해서 설명한다.

- 필요없는 데몬과 서비스를 줄인다. rwhod와 routed는 시스템의 성능을 저해하는 프로그램으로 이를 없애는 것만으로 많은 도움이 될 것이다. kudzu, portmap, nfslock, apmd, random, netfs, identd, atd, pcmcia, lpd, sendmail, gpm, xfs, linuxconf 등이 불필요하다면 사용하지 않아도 될 서비스들이다. cpu의 부하를 줄일 뿐만 아니라 보안 관점에서도 필요없으면 내리는 것이 낫다. 여기서 잘못 이해하기 쉬운 것이 sendmail 부분이다. pine등을 이용하여 메일을 발송할 때에는 센드메일 데몬을 이용하지 않는다. 센드메일을 백그라운드 작업으로 계속 작동시키는 목적은 외부로부터 메일을 받는데 있다. 그러므로 일반적인 메일서버의 기능을 하지 않고 단지 메일을 보내는 것이 목적이라면 sendmail을 가동시킬 필요가 없다. (**주3)

- at이나 cron 등을 이용 작업을 밤이나 시스템의 부하가 적을 때 실행하는 것도 좋은 방법이다. 보통 로그 로테이션, 백업, 로그분석 등은 새벽 시간을 이용하여 처리하는게 바람직하며 기본설정되어 있는 cron 작업은 대부분 새벽 4시에 가동이 된다.

- CPU 집약적인 작업은 nice를 이용 실행우선순위를 낮추면 편집작업과 갈은 상호대화적인 작업의 성능이 향상될 것이다.

- cpu 집약적인 작업의 실행우선순위를 높이면 작업 자체는 빨라지겠지만 상호대화적인 작업의 성능은 떨어질 것이다. 그런데 보통 일반적인 인터넷 서버로 운영을 한다면 CPU 집약적인 작업은 그렇게 많은 편은 아니며 꼭 서버에서 실행시켜도 되지 않는 작업이라면 다른 시스템을 이용하는 것이 좋다. 웹로그 분석도 이러한 경우에 속한다.

- nice를 이용하는것은 임시방편일 뿐이다. 부하가 계속 증가한다면 nice를 이용하는 것에도 한계가 있다. 시스템을 업그레이드하거나 부하를 분산할 시스템을 구입해야한다.

- 커널이나 프로그램의 컴파일을 하는 경우에도 nice를 이용하면 조금이나마 속도의 향상이 있다. 그렇지만 때로 nice를 잘못 사용하면 문제가 생길 수가 있으니 조심해야 한다. 예를 들어 오라클에서는 오라클 사용자 프로세스와 백그라운드 프로세스들을 같은 우선순위에 유지해야 한다. 설계가 그렇게 되어 있기 때문이다. 우선 순위를 변경할 경우 내용과 반응시간에 원치 않는 효과를 초래할 수도 있다. 예를 들어 log write process(LGWR)에 낮은 우선 순위를 부여할 경우, 이 프로세스는 충분한 횟수만큼 작동하지 못하고 LGWR은 병목현상을 일으키게 된다. 다른 한편, 만약 LGWR이 높은 우선 순위를 부여받게 되면, 사용자 프로세스는 느린 반응시간에 시달리게 될 것이다. 무엇이든 그냥 적용하는게 아니라 그 원리를 이해하고 조심스럽게 해야 한다. (**주4)





5. 메모리 문제 파악하기

시스템에 과부하가 걸려있는데도 휴지기간(idle time)이 많거나 ps에서 많은 양의 메모리를 필요로 하는 프로그램이 실행되고 있다면 메모리 문제를 생각해 볼 수 있다.



 vmstat 5 를 실행해보자.

- swap-out이 지속적으로 항상 발생한다면 메모리가 부족한 것이다. 주기적으로 swap-outs이 발생하는건 정상적인 것이다. BSD 시스템에서는 비상호대화적인 작업을 스왑아웃한다. 현재 실행하고 있는 프로그램에서 스왑아웃이 계속 발생한다면 프로그램이 죽을 수도 있으며심각하게 메모리가 부족하다는것을 가리킨다. 스왑아웃필드(so)가 항상 0에 가까워야한다. 그렇지 않다면 프로세스들간에 가상 메모리에 대하여 경쟁하고 있으며 시스템은 페이징 상태에 있다. 페이징 활동은 또한 심각한 가용 메모리(free)의 부족과 직접적인 관련을 가지고 있으며 간접적으로는 시스템의 높은 CPU 사용시간 비율(sy)과 관련이 있다. 프로세스가 시작을 할 때 항상 이미지(text)와 데이터를 page-in 해야 하므로 page-in 열에서 높은 숫자가 항상 심각한 것은 아니라는 사실은 기억하고 있어야 한다.

- ps나 accounting 시스템에서 메모리 집약적인 작업이 있는지 확인을 한다. RSS필드나 storage integral이 큰 프로그램을 찾아보자. ps나 top에서 RSS는 프로세스가 사용중인 물리적 메모리 크기로 kbytes 단위로 보여준다. ELF 프로세스에서 사용된 라이브러리 페이지도 여기에 같이 계산이 된다. storage integral은 accounting 패키지에 들어있는 sa -K 옵션을 이용해 볼수있다.





메모리 문제를 해결할 몇가지 방법을 찾아보자.

- 시스템에서 버퍼 캐쉬가 있다면 크기를 줄인다. 대신 디스크 I/O성능에 영향을 줄 수있다. 리눅스는 /proc를 이용 전체 메모리에서 버퍼 캐쉬의 사용량을 조절할 수 있다. 이에 대해서는 마지막 장 에서 다루겠다.

- 네트워크 버퍼를 줄인다. 웹서버의 응답은 클라이언트에 직접 전달되는 것이 아니라 소켓 버퍼라는 네트워크 버퍼에 저장을 한다. OS에서는 적절한 수와 크기의 네트워크 버퍼를 가지고 있어야 메모리를 낭비하지도 않고 서버에서 필요한 버퍼를 기다리는 동안 서버의 작업이 중단되지도 않는 상태로 클라이언트의 접속을 처리할 수 있다. 갑작스럽게 접속이 중단되는 클라이언트에서 차지하고 있던 네트워크 버퍼는 웹 서버에서 메모리가 낭비되는 주요한 원인중의 하나이다. 아파치에는 SendBufferSize 지시자가 있어서 운영체제에서 지정되어 있는 TCP의 전송 버퍼를 늘릴 수 있다. 그런데 아직까지 필자도 리눅스쪽에서는 이 부분에 대하여 자세히 소개된 자료를 찾지 못했다. 아직 정확히 이해하지 못하고 있는 부분이지만 도움이 될까하여 고민 끝에 관련 내용을 포함한다. (**주5)

- 커널 테이블의 크기를 줄인다. 이를 통해 시스템의 자원을 제약할 수 있다. 예를 들어 파일 개수, 프로세스 개수등이 해당한다. 운영체제에서 이와 관련된 설정을 높이면 그만큼 커널 테이블의 크기가 늘어나 메모리도 그만큼 더 사용하게 된다.

- 많은 메모리를 필요로 하는 프로그램은 밤에 돌리자.

- 많은 메모리를 필요로 하는 프로그램은 배치 큐를 이용해 작업하자. at, cron등 활용

- 자기만 사용하는 프로그램이라면 프로그램에서 메모리를 효율적으로 사용하는지 점검하자.

- 메모리 요구량을 줄이기 위해 공유 메모리를 사용하자. 공유 메모리는 다수의 프로세스 간에 데이터를 공유하고 전달하는 효과적인 방법을 제공한다. 또한 어떤 특정한 명령을 여러명이 사용하는 경우 가상 주소공간에 해당 프로그램의 여러 복사본을 갖는게 아니라 물리적 공간에 하나의 복사본을 만들고 모든 프로세스가 그것을 공유할 수 있다. 동적 라이브러리는 여러 프로세스가 실행 코드를 공유하는 대표적인 예이다. 그런데 공유 라이브러리를 사용하는 경우 메모리는 절약할 수 있겠지만 프로그램의 성능은 정적으로 컴파일하는 것이 더 빠르다. 예를 들어 Mysql의 경우는 -static을 사용하지 않고 동적으로 링크하면 대략 13%정도 속도가 느려진다고 한다. (**주6)

- sendmail은 메모리를 많이 사용하는 프로그램으로 sendmail을 실행하는데 사용되는 시간에 제한을 두자. 아니면 네트웍을 재구성해서 메일서버를 다른 시스템으로 옮길 수 있다. 위에서 설명을 했던대로 메일을 받는 경우에만 sendmail을 사용하면 된다.

- 이막스(Emacs)는 메모리를 많이 사용하는 프로그램으로 vi 등 다른 에디터를 사용하자.

- 이 모든게 안되면 메모리를 구입하자. 하드웨어의 가격이 예전에 비해 많이 저렴해졌으며 이제 1G 메모리도 그렇게 특별한 시스템은 아닌 상황이다. 대신 프로그램에서 요구하는 기본 메모리양도 커졌다.





6. 디스크 I/O 문제 파악하기

시스템에 과부하가 걸려있는데도 휴지기간(idle time)이 많다면 디스크 I/O 문제를 생각해 볼 수 있다. 보통 메모리 문제와 I/O문제는 서로 관련이 되어있다.



 vmstat 5 를 실행한다. 그리고 이것을 정상적인 시스템 상황과 비교해본다. 정상적인 경우보다 디스크 연산이 더 높은가?

 디스크 활동이 시스템 디스크에 골고루 분산되어있는가? iostat 등을 이용하여 모니터링하면 될 것이다.

 그렇지 않다면 가장 활동적인 디스크가 가장 빠른 디스크인가?

 디스크 활동이 디스크의 특정 영역에 집중되어있는가? 디스크에 적당히 분포되어있는가? 아니면 서로 다른 반대방향의 지점에 있는가?

 NFS를 사용하고 있는가? 사용자들이 자신의 지역파일에 접근하는데 속도가 느리다고 보고를 하는가? 원격 파일시스템을 사용하는가? 만약 원격 파일시스템을 사용하면 네트웍 상황에 대해서 살펴보자. 이경우에는 지역 디스크 I/O문제는 아니다.

 vmstat를 이용 메모리 상황을 살펴보자. 시스템에서 페이징이나 스와핑이 계속 일어나고 있다면, 메모리에 문제가 있으며 이경우 디스크 I/O에 심각한 문제를 초래할 수 있다. 먼저 메모리 문제를 살펴보아야한다.



이에 대한 해결책을 찾아보자.

 파일시스템을 재구성하고 가능한한 I/O작업을 분산시킨다.

 루트 파일시스템에 가장 빠른 디스크 드라이브와 컨트롤러를 사용한다. 루트 파일 시스템이 대부분 가장 많은 I/O작업을 한다. 특정한 파일의 성능이 중요하다면 성능이 중요한 파일을 하나의 파일시스템에 넣고 이 파일시스템에 가장 빠른 드라이브를 사용한다.

 퍼포먼스가 중요한 파일을 블락 크기가 큰 파일시스템에 넣는다. 리눅스에서 블락 크기는 블락당 1024, 2048, 4096이다. 파일시스템을 생성할 때 지정을 해야 한다. 블락 크기를 높이면 성능이 향상될 수는 있어도 불필요하게 낭비되는 하드디스크 공간이 늘어난다.

 버퍼 캐쉬의 크기를 늘린다. 그러면 대신 메모리에 문제가 생길 수 있다.

 단편화를 제거하기 위해 주기적으로 파일시스템을 재구성한다.

 자주 사용하는 파일을 파일시스템의 시작부분에 집중시키는 프로그램을 사용할수 있다.



운영체제 차원의 튜닝에서 가장 많은 성능향상을 얻을 수 있는 분야가 I/O 부분이다. I/O성능은 하드디스크의 속도뿐만 아니라 시스템 버스에 물려있는 여러 구성 요소와 함께 좌우가 된다. 그런데 리눅스를 주로 사용하는 인텔x86 계열의 하드웨어는 타상용 유닉스 시스템에 비하면 I/O와 관련되어 성능이 미약한 편이다. 또 비디오 카드등은 64비트를 넘어 128비트 체계로 간지 오래되었지만 마더보드의 PCI 슬롯은 32비트 체계를 가지고 있다. PC레벨에서는 32비트 CPU가 사요되고 있고 메모리를 부분만 64비트로 동작하고 있을 뿐이다. (**주 7) 그렇지만 PC서버가 일반화되면서 예전 상용 유닉스 장비에만 있었던 여러 가지 기능들이 속속 도입되고 있으며 앞으로도 발전이 기대된다. 여기에 몇가지 이야기를 덧붙이자면 디스크 I/O의 속도향상을 위해 RAID등을 사용할 수도 있고 소프트웨어 차원에서의 소프트웨어 레이드도 현재 리눅스에서 지원이 되고 있다. 저널링 파일 시스템이 최근부터 본격적으로 지원되기 시작하여 파일시스템의 안정성과 무결성을 높임과 더불어 속도도 꾸준한 향상이 되고 있다. 현재 리눅스에서 지원하는 저널링 파일 시스템으로는 reiserfs, SGI의 XFS 등이 있다. (**주8)



디스크 용량에 문제가 생길 수도 있다. 파일시스템에 여유공간이 부족한가? 그렇다면 몇가지 방법을 생각해보자.

ㅇ 필요없는 파일을 cron 등을 이용 정기적으로 삭제하자. 오래된 코어 덤프 파일, 에디터 백업파일, auto-save 파일 등등.

 디스크 쿼터를 이용해 사용자의 디스크 용량 사용을 제한할 수 있다.

 매우 작은 파일이 모여있는 파일시스템에는 작은 블럭 사이즈를 사용한다. (소스 코드, 작은 데이타 파일 등등)

ㅇ /tmp, /var/tmp 등에는 계속 임시파일이 생성되고 man 페이지를 위한 임시파일도 계속 생성이 된다. 이에 대한 처리는 레드햇 리눅스 계열에서/etc/cron.daily/tmpwatch를 이용하여 처리한다. 3장에서 다시 소개할 것이다.





7. 네트웍 문제 점검

네트웍 문제 점검

 rlogin이나 NFS를 이용하여 파일에 접근하는 사용자가 성능이 느리다고 생각이 든다면 이는 네트웍 용량이나 데이터 정합성에 문제가 있을 수 있다.

 netstat -i 를 실행하자. 충돌(collison)이 크면 네트웍에 오버헤드가 걸렸다고 생각할 수 있다. 충돌률은 ifconfig -a 등을 이용해서 나온 결과중 (collisons/TX packets) X 100을 하면 나온다. input이나 output 에러가 많다면 하드웨어 문제일 수 있다. 입력에러가 많다면 네트웍의 특정한 곳에 문제가 있을 가능성이 크며 출력에러가 많다면 시스템과 네트웍 인터페이스에 문제가 있을 가능성이 크다.

 충돌이나 네트웍 하드웨어의 문제가 아니라면, 어떤 시스템이 가장 느린지를 찾아야한다. dropped 패킷이 크다면, 원격 시스템은 아마도 들어오는 자료에 대해 충분히 빠르게 대응하지 못할 것이다. 원격 시스템에 cpu, 메모리, 디스크 I/O문제가 있는지 확인하자. 그게 아니라면 그 시스템은 네트웍의 과부하에 견디지 못할 것이다. 네트웍을 다시 재구성하고 느린 시스템을 파일 서버로 사용하지 말자.

ㅇ 기본적인 연결 테스트에는 ping 명령을 사용하며 네트워크 접속에 대한 점검을 한다면 ifconfig, arp, netsta 등을 이용하고 네트워크 하드웨어 문제를 점검해 보아야 한다.





# ifconfig -i

eth0 Link encap:Ethernet HWaddr 00:01:02:26:BD:CE

inet addr:211.111.111.111 Bcast:211.50.6.255 Mask:255.255.255.192

UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1

RX packets:346297 errors:0 dropped:0 overruns:0 frame:0

TX packets:346683 errors:0 dropped:0 overruns:0 carrier:0

collisions:0 txqueuelen:100

Interrupt:10 Base address:0xd000



lo Link encap:Local Loopback

inet addr:127.0.0.1 Mask:255.0.0.0

UP LOOPBACK RUNNING MTU:16436 Metric:1

RX packets:7745 errors:0 dropped:0 overruns:0 frame:0

TX packets:7745 errors:0 dropped:0 overruns:0 carrier:0

collisions:0 txqueuelen:0





# netstat -i

Kernel Interface table

Iface MTU Met RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg

eth0 1500 0 349675 0 0 0 350447 0 0 0 BRU

lo 16436 0 7825 0 0 0 7825 0 0 0 LRU





네트웍 부하 줄이는 방법 (**주9)

 사용자가 네트웍을 통해 I/O집약적인 프로그램을 실행하지 않도록 막자. grep 프로그램이 I/O 집약적인 프로그램중의 대표적인 예이다. 대신 네트웍을 통해 로그인해서 작업하자.

 네트웍에 연결된 컴퓨터와 디스크를 재구성해서 가능한 많은 사용자가 지역 지역 시스템에서 작업을 하도론 만든다.

 디스크없는 워크스테이션의 숫자를 줄인다. 가능하다면 이런 워크스테이션은 제거한다.

 뛰어난 네트웍 성능을 가진 시스템을 파일서버로 사용한다.

ㅇ 충돌률을 줄이기 위해서는 네트워크 세그먼트 상의 트래픽양을 줄여야 하며 이 경우 이더넷을 분리할 수 있다.



데이터 정합성에 문제가 있다면 유일한 해결책은 문제가 있는 하드웨어를 찾아서 바꾸는 것이다. 네트웍 분석툴이 이러한 작업을 하는데 반드시 필요할 것이다.







8. 마치며

이번 강의에서는 시스템 최적화를 위한 준비 단계로 프로세스, 메모리, I/O 부분을 중심으로 어떻게 현재 시스템 상태를 모니터링하고 문제를 발견하여 해결을 할 수 있는지에 대하여 설명을 하였다. 중요한 것은 시스템을 모니터링하는 것과 더불어 나온 결과에 대하여 정확하게 이해를 해야 한다는 것이다. 이에 대해서는 free를 예로 들어 설명을 하였다. 가장 먼저 주기적으로 시스템을 모니터링하여 문제를 파악하고 있어야 하고 문제가 발생했을 경우 여러 가지 상황에 따라 CPU, 메모리, I/O부분을 점검해야 한다.
2005/07/04 14:24 2005/07/04 14:24
운영체제와 커널 차원에서의 튜닝과 보안에 대해서 중요한 부분을 설명하겠다. 보안도 다루기는 하지만 일반적인 차원에서의 보안에 대한 내용은 뺐다. 일반적인 보안에 대해서는 잘 다룬 서적이나 자료들이 많기 때문에 중복된 내용을 설명하기보다는 다른 곳에서는 자세히 다루지 않았지만 중요한 부분들을 설명하는게 나을 것 같다. 먼저 파일시스템 설정과 관련된 부분에 대해서 설명을 하고 운영체제 및 커널 차원의 튜닝과 보안에 대해서 설명을 하겠다.



1. 파일 시스템 관련

/etc/fstab에는 파일 시스템 관련된 정보가 들어있다.



$ cat /etc/fstab

/dev/sda2 /home ext2 defaults,rw,nosuid,nodev,noexec 1 2

/dev/sda3 /var ext2 defaults,rw,nosuid,nodev,noexec,noatime 1 2

/dev/sda4 /tmp ext2 defaults,rw,nosuid,nodev,noexec 1 2



여기서 세 번째 줄은 해당 파티션에 대한 제어정보가 들어있는데 의미는 다음과 같다.

default : quota, read-write, suid, async

noquota : 쿼터 사용하지 않음

nosuid : SUID/SGID 설정을 할 수 없음

nodev : 문자나 블락 특수 디바이스 설정을 할 수 없음

noexec : 바이너리 파일의 실행 권한을 주지 않음

quota : 쿼터 설정

ro : 읽기 전용 파일시스템

rw : 읽기/쓰기 파일시스템

suid : SUIG/SGID 설정 허용

noatime : atime(파일 접근 시간)을 업데이트하지 않음



리눅스 및 유닉스에서는 파일 생성 시간 및 마지막 변경시간과 함께 마지막 접근시간을 계속 기록한다. 그렇지만 자주 접근하고 변경이 되는 파일에 대해서는 파일 접근시간이 필요하지 않다면 굳이 마지막 파일 접근시간을 기록하지 않아도 된다. 웹서버, 캐쉬파일, 로그파일 등 주로 읽기전용 파일이 이에 해당할 것이다. 이 설정만으로 성능 병목현상의 가장 큰 주범인 디스크 I/O를 줄이는 데에 도움이 될 수 있다. 그렇지만 파일이 변경된 경우에는 업데이트가 되니 걱정하지 말기 바란다. (chattr 프로그램을 이용하여 개별 파일에 대해서도 지정할 수 있다)



nosuid는 SUID,SGID를 하지 못하도록 막는다. SET-UID 프로그램은 보안상 문제가 생길 여지가 많으며 루트 계정으로 접근할 수 있는 지름길이 되는 경우가 많다. 불가피하게 사용해야 할 경우가 있지만 그 외에는 nosuid 설정을 통해 보안을 강화하는게 좋다. 레드햇 계열에서 SET-UID root 프로그램은 다음과 같은 것들이 있다.



# find / -type f \( -perm -04000 -o -perm -02000 \) \-exec ls -alF {} \;

-rwsr-xr-x 1 root root 14188 Mar 7 2000 /bin/su*

-rwsr-xr-x 1 root root 86690 Oct 20 2000 /bin/ping*

-rwsr-xr-x 1 root root 62192 May 4 09:45 /bin/mount*

-rwsr-xr-x 1 root root 28432 May 4 09:45 /bin/umount*

-r-sr-xr-x 1 root root 15688 Dec 1 2000 /sbin/pwdb_chkpwd*

-r-sr-xr-x 1 root root 16312 Dec 1 2000 /sbin/unix_chkpwd*

-rwsr-xr-x 1 root root 22232 Feb 22 10:21 /usr/bin/crontab*

-rws--x--x 1 root root 14056 Jan 11 2001 /usr/bin/chfn*

-rws--x--x 1 root root 13800 Jan 11 2001 /usr/bin/chsh*

-rws--x--x 2 root root 563164 Aug 9 2000 /usr/bin/suidperl*

-rws--x--x 2 root root 563164 Aug 9 2000 /usr/bin/sperl5.00503*

-rwxr-sr-x 1 root man 36368 May 23 13:25 /usr/bin/man*

-r-s--x--x 1 root root 12244 Feb 8 2000 /usr/bin/passwd*

-rwxr-sr-x 1 root mail 11620 Feb 8 2000 /usr/bin/lockfile*

-rwsr-sr-x 1 root mail 76432 Feb 8 2000 /usr/bin/procmail*

-rwxr-sr-x 1 root slocate 23024 Dec 21 2000 /usr/bin/slocate*

-rwsr-xr-x 1 root root 198312 Nov 10 2000 /usr/bin/ssh1*

-rws--x--x 1 root root 5640 Jan 11 2001 /usr/bin/newgrp*

-rwxr-sr-x 1 root tty 8332 Jan 11 2001 /usr/bin/write*

-rwxr-sr-x 1 root utmp 6096 Feb 25 2000 /usr/sbin/utempter*

-rws--x--x 1 root root 9568 Mar 29 18:30 /usr/sbin/suexec*

-rwsr-sr-x 1 root mail 369340 Jun 19 14:31 /usr/sbin/sendmail*

-rwsr-xr-x 1 root root 17704 Oct 7 2000 /usr/sbin/traceroute*

-rwsr-xr-x 1 root root 34751 Jan 16 00:50 /usr/libexec/pt_chown*





여기서 불필요한 파일은 chmod를 이용 설정을 바꾸어야 한다. chage, gpasswd, wall, chfn, chsh, newgrp, write, usernetctl, traceroute, mount, umount, ping, netreport 등이 여기에 해당한다.



그런데 위의 프로그램은 서비스를 제공하기 위해 어쩔 수 없는 경우이지만 그러한 경우가 아니라면 특정한 파티선에 nosuid를 사용해서 계정 등의 사용자가 장난을 치는 경우를 막을 수 있다. 여기에 noexec까지 주면 바이너리 파일을 실행하지 못하기 때문에 더 안전하게 시스템을 유지할 수 있다. noexec를 준 파티션은 루트도 바이너리 파일을 실행하지 못한다. quota를 이용해서 사용자가 제한되어 있는 하드 디스크 공간을 모두 차지하는 일을 막을 수 있다. 쿼터 설정은 여기서는 생략을 하겠다. async 옵션은 파일시스템에 대한 I/O를 비동기적으로 메모리에 버퍼링하는 것인데 기본값으로 되어 있다. 디스크 접근 시간을 최소화하기 위한 부분이므로 바꿀 필요가 없다. 이것을 sync로 바꾸면 메모리에서 변경된 자료가 바로 디스크 I/O에 반영이 되므로 속도가 얼마나 느려질지 장담할 수 없다.





2. 보안관련 커널 설정

커널과 관련된 옵션은 /proc에서 직접 값을 써 줄 수도 있고 /etc/sysctl.conf 파일을 이용하여 바꿀 수도 있다. 커널과 관련된 옵션은 그냥 무조건 사용하는게 아니라 자신의 환경을 생각해야하고 그 원리를 제대로 이해했을 때 사용하는 것이 좋다. 그런데 이 작업이 그렇게 만만한 작업은 아니고 운영체제와 네트웍에 대해서 많은 지식이 있어야 이해가 가능하다. 여기서는 주로 많이 사용되는 커널 옵션에 대해서 살펴보겠다. 커널과 관련된 설정은 sysctl 프로그램을 이용하여 편리하게 설정할 수 있다. sysctl -a 하면 현재 설정된 값이 나오고 -w 옵션을 이용하여 특정값을 저장할 수 있다. 재부팅후에도 계속 사용하려면 /etc/sysctl.conf 파일에 저장하여 사용하면 된다.



ㅇ ping 요청에 반응하기 막기 : ping 요청에 반응하는 것을 막을 수 있다. 외부에서 누구도 서버에 핑을 보낼 수도 없고 보내도 반응을 하지 않기에 보안상으로 도움이 될 수 있고 네트웍 보안을 향상시킬 수 있다. 그러나 원격에서 서비스를 관리하는 경우 간단하게 시스템의 상태를 확인할 수 있는 수단을 막는 결과를 초래할 수도 있다.

net.ipv4.icmp_echo_ignore_all = 1



ㅇ Broadcast 로 오는 핑을 차단하기 : 브로드캐스트 주소에 ping을 쏘는 것을 막는다. smurf 공격 방지용이다. 스머프 공격은 에코 리퀘스트 패킷을 어떤 네트웍의 브로드캐스트 주소로 보내면 해당 네트워크의 모든 호스트가 request 패킷에 응답하느라 다른 일은 하지 못하는 것을 말한다. 그렇지만 정작 문제는 해당 네트워크의 호스트가 아니다. 이 엄청난 개수의 컴퓨터들에서 일시에 어느 한 곳으로 ICMP echo replay 패킷을 보내면 패킷을 보냈던 시스템은 마비상태로 가기 싶다. 하지만 이미 출발지 주소 자체가 실제 패킷을 보낸 시스템이 아니라 공격을 할 호스트로 바뀌어있는 상태일 것이다. (IP 스푸핑)

net.ipv4.icmp_echo_ignore_broadcasts = 1



ㅇ IP 소스 라우팅 막기 : 라우팅과 라우팅 프로토콜은 몇가지 문제를 생성해낸다. RFC 1122에 따르면 목적지의 경로에 대한 세부적인 내용을 담고 있는 IP 소스 라우팅은 목적지 호스트에서도 같은 경로를 따라 반응을 해야 하다는 문제점이 있다. 크래커가 특정 네트웍에 소스 라우팅 패킷을 보낼 수 있다면 돌아오는 반응을 가로채서 상대방의 호스트와 신뢰받은 호스트처럼 속일 수 있다. 기본값이 1이므로 0으로 바꾼다.

net.ipv4.conf.all.accept_source_route = 0



ㅇ backlog 늘리기와 syncookie 기능 사용하기 : SYN Attack 은 서비스 거부 공격(DOS)의 하나로 공격할 시스템의 모든 자원을 소비하게 해서 재부팅하게 만든다. 두 호스트 사이에 TCP 연결이 이루어지는 것은 클라이언트 호스트가 TCP 헤더에 SYN 플래그를 on한 상태로 서버 호스트로 연결 요청을 하면서 시작된다. 그러면 요청을 받은 서버는 클라이언트로 SYN/ACK를 보내고 이를 받은 클라이언트는 서버에게 ACK를 보낸다. 그런데 클라이언트에서 ACK를 보내지 않고 있으면 어떻게 될까? 문제는 TCP에서 한 소켓에서 동시에 SYN 요청을 처리하기에는 한계가 있으며 이 한계가 백로그(backlog)라고 한다. 백로그는 연결 요청이 아직 완전히 처리되지 아니한 대기상태에 있는 큐의 길이이다. 이 백로그 큐가 꽉 차게 되면 이후 들어오는 SYN 요청은 무시되며 이러한 공격을 SYN 플러딩이라고 한다. 다른 유닉스 중에서는 들어오는 소켓 요청에 대하여 두 개의 큐를 만드는 경우도 있다. 이 경우 하나는 half-open 소켓(SYN을 받고 SYN/ACK를 보낸 상태)을 위한 큐이고 또하나는 완전히 연결이 되었지만 애플리케이션에서 accept() 콜을 기다리는 큐이다. (솔라리스의 경우 tcp_conn_req_max_q0, tcp_conn_req_max_q가 이에 해당한다) backlog도 무조건 늘리는 것이 좋은 것은 아니라는 보고가 있으며 1024 이상으로 설정시에는 커널 소스를 수정해야 한다. syncookie는 SYN Flood 공격에 대응하기 위해 나온 것이지만 large windows에서는 성능에 문제가 발생할 가능성이 있다고 한다. syncookie를 사용하려면 커널에서 지정이 되어 있어야 한다.

net.ipv4.tcp_max_syn_backlog=1024

net.ipv4.tcp_syncookies = 1



ㅇ ICMP redirect를 막는다 : 호스트에서 특정 목적지로 최적화되지 않은 라우팅을 한다고 할때 ICMP redirect 패킷은 호스트에게 정확한 라우팅 경로를 알려주는 역할을 한다. 그런데 크래커가 ICMP redirect 패킷을 위조할 수 있게 된다면 호스트의 라우팅 테이블을 변경할 수 있게 되고 원하지 않는 경로로 트래픽을 보내 호스트의 보안을 해칠 수 있다. 잘 디자인된 네트웍에서는 최종 목적지로의 redirect가 필요하지 않다. redirect 보내고 받는 것을 모두 없애야 한다. (**주1)

net.ipv4.conf.all.send_redirects=0

net.ipv4.conf.all.accept_redirects=0





ㅇ bad icmp 패킷 차단 : 어떤 router 들은 broadcast frame들로 거짓 응답을 보냄으로서 RFC 1122를 위반한다. 이러한 것들은 보통 커널 경고를 통해 로깅이 된다. 이것을 TRUE로 설정을 할경우 커널은 이러한 경고를 하지 않을 것이며, 로그 파일이 지저분해 지는 것을 피할 수 있다. 기본값은 FALSE 이다. 1로 설정하여 활성화를 하면 IP나 TCP 헤더가 깨진 bad icmp packet을 무시한다.

net.ipv4.icmp_ignore_bogus_error_responses = 1



ㅇ IP 스푸핑 방지하기 : DOS 공격에서 자신의 네트워크가 스푸핑된 공격지의 소스로 쓰이는 것을 차단한다. RFC182에 따른 IP spoof 방지를 위한 설정이다.

net.ipv4.conf.all.rp_filter = 1



ㅇ IP 스푸핑된 패킷 로그에 기록하기 : 스푸핑된 패킷, 소스 라우팅 패킷, redirect 패킷에 대하여 로그파일에 기록을 남긴다.

net.ipv4.conf.all.log_martians = 1



참고로 /etc/host.conf 파일에 nospoof 옵션을 주어 IP 스푸핑 방지를 위한 설정을 추가하기 바란다.



# cat /etc/host.conf

order bind, hosts

multi on

nospoof on





3. 최적화 관련 커널 및 운영체제 설정

커널과 운영체제에서의 최적화는 네트웍, 가상 메모리, 디스크 I/O, 각종 자원 제한 등으로 나눌 수 있다. TCP-IP에서 네트웍 최적화는 TCP/IP의 기본값을 줄여서 TCP/IP에서 더 많은 연결을 처리할 수 있도록 하는게 목적이다. TCP의 연결 해제 시간을 줄이고 불필요한 IP 확장기능을 사용하지 않는다.



ㅇ 연결종료시간을 줄인다 : tcp_fin_timeout은 close되었을 때 FIN-WAIT-2 상태로 얼마나 오랫동안 소켓을 유지하고 있는가를 지정한다. 상대 호스트에 문제가 생겨서 close를 못할 수도 있고 예상치 않게 죽을 수도 있다. 커널 2.4에서 기본값은 60초인데 커널 2.2에서는 180초였다. 커널 2.2와 같이 더 늘릴 수는 있지만 시스템이 웹서버의 용도라면 수많은 소켓들 때문에 메모리에 문제가 생길 수 있다. FIN-WAIT-2 소켓은 최대 1.5K의 메모리를 사용하기 때문에 FIN-WAIT-1보다는 위험이 덜하지만 더 오래 가는 경향이 있다.

net.ipv4.tcp_fin_timeout = 30



ㅇ keepalive 시간 줄이기 : tcp_keepalive_time은 keepalive가 활성화되어 있을 때 얼마나 자주 keepalive 메시지를 보내줄지 정한다. 이는 HTTP 1.1의 연결지속 옵션과 관계없이 TCP 자체에 있는 기능이다. TCP 접속은 한쪽에서 다른 쪽으로 데이터를 전송할 필요가 없는 경우에는 트래픽이 전혀 발생하지 않으므로 휴지 상태인 접속의 경우에는 폴링이나 네트워크 부하가 없다. 그런데 더 이상 사용하지 않는 네트워크 접속을 위해 서버에서는 메모리 버퍼를 유지하고 있는 것으로 자원을 낭비하는 것이다. 사용자가 모뎀을 꺼버리거나 컴퓨터의 전원을 끄는 경우도 이에 해당한다. 기본값은 2시간(7200초)인데 처리량이 많은 웹서버인 경우에는 사용자가 페이지를 읽고 얼마나 오래 머무는지를 판단하여 이 대기시간을 최대 시간 간격으로 설정하면 되며 보통 30분정도면 적당하다.

net.ipv4.tcp_keepalive_time = 1800



ㅇ 열수 있는 포트 늘리기 : ip_local_port_range 옵션은 TCP와 UDP에서 사용할 수 있는 로컬 포트의 범위를 지정한다. 두가지 숫자로 이루어져 있는데 앞의 번호는 시작포트이고 뒤의 번호는 마지막 로컬 포트 번호이다. 메모리양에 따라 기본값이 조정되는데 128M 이하일 경우에는 1024-4999, 128M 이상일 경우에는 32768-61000 이다.

net.ipv4.ip_local_port_range = 32768 61000





ㅇ 컴파일 옵션 변경

x86 프로그램에서 최대의 성능을 내기 위해서는 컴파일 옵션에 -O9 플래그를 지정할 수 있다. 대부분의 프로그램은 Makefile에 -O2를 지정하는데 -O9는 코드를 가장 최고로 최적화하는 것이다. 프로그램의 크기는 커지지만 속도가 빨라진다. 그렇지만 CPU가 686이상에서만 성능 향상이 있다. -mcpu=cpu_type -march=cpu_type을 사용하면 각 CPU에 최적화된 코드가 생성된다. 이럴 경우에는 프로그램이 해당 CPU에서만 돈다는 단점이 있다. gcc에서 -S 옵션을 이용하면 어셈블리어로 번역되어 결과가 출력되는데 최적화를 할수록 어셈블리 코드가 짧게 변하는 것을 볼 수 있다. 이외에도 gcc를 egcs로 바꾸어서 사용할 수 있다. 이외에도 최적화된 컴파일을 하기 위해 몇가지 추천하는 옵션이 있었지만 커널 컴파일 등에서 제대로 부팅이 되지 않는 경우가 있어 여기서는 일반적인 옵션에 대해서만 소개를 하였다.



ㅇ bdflush 제어 : bdflush는 가상 메모리(VM) 서브시스템의 활동과 관련이 되어있는데 bdflush 커널 대몬에 대한 제어를 한다. bdflush는 블럭 디바이스 입출력 버퍼를 관리하는 커널 대몬으로 주로 버퍼를 비우는 역할을 맡고 있다. 하드 디스크에 쓰여질 데이터는 바로 하드 디스크로 저장되는 것이 아니라 중간에 버퍼를 통한다고 앞부분에서 설명을 하였다. 주기적으로 버퍼의 내용을 하드 디스크에 기록하는 형태로 하드 디스크 접근을 최대로 줄여서 파일 시스템의 성능을 높이기 위한 것이다. bdflush는 9개의 값으로 구성이 되어있으며 기본값은 커널 2.2에서는 40 500 64 256 500 3000 500 1884 2 이었다가 커널 2.4에서는 구성이 약간 바뀌었다. 기본값만 바뀐 것이 아니라 순서도 바뀌었다. 순서가 nfract, ndirty, nrefill, dummy1, interval, age_buffer, nfract_sync, dummy2, dummy3 이며 기본값은 “30 64 64 256 500 3000 60 0 0” 이다.

커널 소스는 /usr/src/linux/fs/buffer.c이다. 여기에서 중요한 부분은 앞의 세가지이다. nfract는 전체 버퍼 캐쉬중에서 더티 버퍼의 비율을 나타낸다. 여기서 더티는 프로세스에서 변경이 되어 하드 디스크에 쓰여질 데이터를 나타낸다. (반대는 clean 버퍼이다) 수치를 높이면 디스크에 쓰는 동작은 최대한 지연이 되지만 메모리가 부족할 경우 I/O부하가 걸릴 수 있다. 또 어느 책에서는 이 수치를 100%로 지정하는 것을 추천하고 있는데 메모리와 관련하여 "do_try_to_free_pages failed for ...." 등의 문제가 발생한 경우가 생기고 있다. ndirty는 한번에 기록될 더티 블락의 최대 숫자이다. 수치를 높이면 I/O작업을 지연시킬 수 있는데 수치가 너무 낮으면 bdflush가 오랫동안 작동을 하지 않아 메모리 부족 현상이 생길 수 있다. nrefill은 refill을 호출할 때마다 가져올 클린 버퍼 개수이다. 때로는 버퍼가 메모리 페이지에 비해 다른 크기가 될 수 있기 때문에 미리 free 버퍼를 할당하는 것이 필요하다. 수치가 클수록 메모리가 낭비될 확률은 높지만 refill_freelist()를 실행할 필요는 적어진다.

vm.bdflush = 30 64 64 256 500 3000 60 0 0



ㅇ 버퍼 메모리 사용량 조절 : buffermem 은 전체 메모리에서 버퍼 메모리 사용량을 % 비율로 조절한다. 기본값은 2 10 60으로 되어 있다. 여기서 실제 사용하는 값은 제일 앞의 한 개만 사용하며 전체 메모리에서 버퍼로 사용할 수 있는 최소량을 %로 나타낸다.

vm.buffermem = 2 10 60



위에서 말을 한 대로 가상 메모리와 관련한 설정은 시스템의 성능에 큰 영향을 미치지만 잘못 바꾸었을 경우에는 아예 시스템이 멎어버리는 현상이 생길 수가 있다. 테스팅 서버에서 조금씩 값을 바꾸어가면서 자신에게 맞는 설정을 찾아야 할 듯하다. 절대 현재 서비스되고 있는 시스템에서 테스팅을 하지는 말자.



ㅇ 스와핑 조절 : 가상 메모리와 관련된 설정 중 시스템의 성능과 연관이 깊은 것으로는 freepages(vm.freepages)가 있다. freepages는 커널에서 스와핑을 언제 어떻게 할지에 대한 동작을 제어한다. 첫 번째 값은 min으로 free pages가 이 숫자 이하로 넘어갈 때만 커널에서 더 많은 메모리를 할당한다. 두 번째 값은 low로 free pages가 이 숫자 이하로 넘어갈 때 커널에서 스와핑을 시작한다. 세 번째 값은 high로 시스템에서 스와핑을 원활하게 하기 시작하기 위해서 최소한 가지고 있어야 할 free 메모리 페이지를 지정한다. 그러므로 항상 시스템에서 여기에 해당하는 페이지를 free로 가지고 있으려 한다. 아래는 기본 설정값이다.

vm.freepages = 383 766 1149





ㅇ 열 수 있는 파일 핸들 조정 : file-max는 리눅스 커널에서 할당할 수 있는 최대 파일 핸들을 지정한다. “running out of file handles” 라는 에러 메시지가 나오는 경우에는 적절히 늘려주어야 한다. 이는 파일 오픈이 많은 사이트에서 나타나는 현상이다. 웹호스팅 업체의 경우 웹로그파일, 메일서버 관련파일 등을 제대로 관리하지 않으면 이런 경우가 생긴다. 불필요한 파일을 없애고 로그파일을 통합하여 처리한 후 이후에 별도로 도메인별로 분리하는 방법을 생각해 볼 수 있다. 4M당 256개의 파일을 할당해주면 된다. 메모리에 맞추어 설정해주면 된다.

fs.file-max = 8192



/proc/sys/fs에서 file-nr을 보면 현재 할당되어 있는 파일 개수를 알 수 있다.



# cat /proc/sys/fs/file-nr

696 158 32768



첫 번째 숫자는 현재 할당된 파일핸들, 두 번째 숫자는 그중 사용된 파일핸들이고 제일 뒤의 숫자는 파일핸들의 최대 숫자이다. 위에서 지정한 file-max 값이다.



시스템에서 현재 할당되어 있는 inode 개수는 inode-state 나 inode-nr의 제일 앞의 숫자를 보면 된다.



# cat /proc/sys/fs/inode-state

3457 6 0 0 0 0 0



ㅇ 프로세스 개수와 파일 개수 조정 : ulimit -a를 이용하여 사용자별 프로세스 숫자와 열수 있는 파일 개수를 제한할 수 있다. 커널 2.2에서는 동시에 생성 가능한 프로세스 수에 대한 제한이 있었는데 커널 2.4로 넘어오면서 이에 대한 제한이 없어졌다. (task.h에서 지정했는데 커널 2.4에는 파일이 없어졌다) 이제 유일한 제약은 메모리 한계이며 많은 수의 프로세스를 지원하기 위해 스케쥴러도 향상이 되었다. max user processes는 16383이며 open files는 1024이다. 슈퍼유저인 root에게는 max user processes 제한을 ulimit -n unlimited 라는 명령을 통하여 없앤다. 이후에도 계속 적용을 하려면 .bashrc 등에 지정을 하면 된다.



# ulimit -a

core file size (blocks) 0

data seg size (kbytes) unlimited

file size (blocks) unlimited

max memory size (kbytes) unlimited

stack size (kbytes) 8192

cpu time (seconds) unlimited

max user processes 16383

pipe size (512 bytes) 8

open files 1024

virtual memory (kbytes) 2105343



그런데 자원 한도를 변경한다고 하더라도 사용자가 소프트 한도를 변경할 수 있다. 또한 위의 모든 제한은 프로세스별로 되어 있는데 실제 작업은 여러개의 프로세스로 구성이 되어 있다. 그렇지만 코어 파일 크기의 한도를 제한하는 것은 유용한 일이다. 이를 보완할 수 있는 것이 PAM(Pluggable Authentication Module)을 이용한 limit.conf 파일의 활용이다. /etc/security 디렉토리에 있다. 이 파일을 이용하여 로그인한 사용자의 시스템 자원을 제한할 수 있다.



먼저 /etc/pam./login 파일에 아래 내용이 없으면 추가한다. limit.conf를 사용할 수 있도록 설정하는 것이다.



session required /lib/security/pam_limits.so



이제 /etc/security/limit.conf 파일을 필요에 따라 수정한다. 간단한 예를 들어 설명해보겠다.



* hard core 0

* hard rss 5000

* hard nproc 20

* hard cpu 5

* hard data 10000



코어 파일은 생성하지 못하고 최대 resident set size는 5M로, 프로세스는 최대 20개로 제한을 하였고 CPU 선점 시간은 최대 5분이며 최대 데이터는 10M이다. 계정을 가진 사용자가 아무런 제한없이 접속하여 메모리를 엄청나게 잡아먹는 프로그램을 만들었다고 해보자. (**주2)



$ cat memdown.c

#include

#include



int main()

{

char *memory;

int size=1024;

int m=0;

int i=0;



while(1)

{

for(i=0;i<1024;i++)

{

memory = (char *)malloc(size);

if(memory == NULL) exit(-1);

sprintf(memory, "메모리를 사랑해~\n");

}

m++;

printf("현재 %d M 소비\n",m);

}

exit(0);

}



$ gcc -o memdown memdown.c



그러면 memdown을 실행해보자. 절대 서버에서는 하지 말기 바란다.



아무런 제한이 없는 경우에는 메모리가 부족한 시스템에서는 현재 있는 메모리를 모두 잡아먹고 나중에는 스왑까지 전부 소비할 수가 있다. 이렇게 메모리 고갈, 프로세스 고갈 등을 막는데 유용하다.



여기서 제한을 걸 수 있는 사항은 다음과 같다.

- core : 코어파일 크기(KB)

- data : 최대 데이터 크기(KB)

- fsize : 최대 파일크기(KB)

- memlock - 최대 메모리잠김(locked-in-memory) 주소 공간(KB)

- nofile : 최대 열수 있는 파일수

- rss : 최대 상주셋(resident set) 크기(KB)

- stack : 최대 스택 크기(KB)

- cpu : 최대 CPU 시간(MIN)

- nproc : 최대 프로세스 개수

- as - 주소 공간 제한

- maxlogins - 최대 로그인 숫자

- priority - 사용자 프로세스 실행 우선순위



위에서 보았던 간단한 프로그램은 “username hard data 10000” 이렇게 간단한 한줄로 충분히 막을 수 있다. 다시 위의 프로그램을 실행해보면 9M까지 메모리를 사용한후 멈춘다.



$ ./memdown

현재 1 M 소비

현재 2 M 소비

현재 3 M 소비

현재 4 M 소비

현재 5 M 소비

현재 6 M 소비

현재 7 M 소비

현재 8 M 소비

현재 9 M 소비



maxlogin은 웹호스팅 업체에서 사용자들의 접속을 제한하는데 유용하다. 계정을 주고 몇십명이서 접속을 하도록 내버려두어서는 안되기 때문이다.



ㅇ 프로세스당 열 수 있는 파일 개수 : 위에서 설정을 바꾼다고 하더라도 프로세스당 열 수 있는 파일 개수는 1024로 되어 있다. 이를 수정하려면 커널 소스를 고쳐야하는데 커널 소스 디렉토리의 include/linux 디렉토리로 이동하여 fs.h 와 limits.h를 수정하면 된다. fs.h에서는 INR_OEPN 과 NR_OEPN을 원하는 수치로 조정하고 새로 컴파일을 하면 된다. 그런데 시스템에서 동시에 열 수 있는 파일수 이상으로 이 수치를 높이는 것은 불필요한 일이다. 그리고 굳이 수정하지 않더라도 일반적인 환경에서 하나의 프로세스가 1024개 이상의 파일을 여는 일은 드물다고 생각이 된다.
2005/07/04 14:23 2005/07/04 14:23

웹 퍼포먼스 튜닝

FAQ 2005/07/04 14:22
1. Web Performance Tunning 소개 및 정의
웹 서비스의 성능 최적화는 오직 서버측에서만의 튜닝을 생각하기 쉬운데 사실,
정확한 의미의 성능 최적화는 웹 서비스 이용자와 서버측 모두의 성능 개선에 있다.
이 글은 아파치 웹 서버나, 유닉스, 리눅스 그리고 웹 브라우저에 이르기까지
통합적인 웹 서비스 성능 개선 방안을 다루므로, 세부적인 웹 서버 구축에 대한
설명등은 포함하지 않았다. 그러나 글의 후반부에서는 가상 호스팅 관리자를 위한
아파치 웹 서버의 성능 개선에 필요한 요소나 관련 세부 옵션에 대한 언급을 하고
있다.
필자는 현재 인터넷 관리자를 위한 온라인 공동체라는 [ 넷킬러 웹 사이트 :
http://www.netkiller.com ]를 운영하고 있으며, 글에 대한 세부적인 질문과 의견은
해당 분야별 게시판을 이용하기 바란다. : - )

2. 기본적인 성능 개선 방안

가. 이용자측의 성능 개선 [익스플로러, 네스케이프]

웹 브라우저의 캐시를 최대한 활용한다.
브라우저의 옵션을 보면 다운 로드 받은 웹 문서를 브라우저의 캐시에 저장하여 다음
접속시 문서 변경 확인 여부 설정을 할수 있다.
여기서 가급적 자동(섹션당 한번)으로 설정해 준다. 익스플로러의 경우 캐시
사용량까지 미리 정해 줄수 있다.


Proxy 서비스를 활용한다.
프락시 서버는 이용자가 요청한 웹 페이지를 서버의 캐시에 임시로 저장하여 다음
요청이 있을시 해당 캐시 파일을 보내주어 속도의 개선 및 인터넷 부하를 줄여준다.

더 빠른 DNS 서버를 사용한다.
임의의 웹 사이트를 접속할 때 자주 볼수 있는 웹 브라우저의 접속 상황 메시지는
Contacting Host , Host Connected, File Transferred at 3.4kbps 등이다. 여기서
Contacting Host에서 Host Connected의 시간 간격이 비정상적으로 길다면 DNS 서버를
한번 체크해볼 필요가 있다. DNS 서버는 이용자가 인터넷 에 접속할 때마다 사용하는
서비스이므로, 가급적 자신의 ISP에서 제공하는 빠른 네임 서버를 쓰는 것이 좋다.

자신의 ISP가 제공하는 프로그램 배포 관련Mirror 사이트를 활용한다.
해외 인터넷 사이트에서 프로그램 다운로드등에 대한 부하를 감소시키기 위하여 국내
ISP들은 대부분 자사의 홈페이지아래 각종 Mirroring 사이트를 운영하고 있다. 예를
들어 tucows라는 인터넷 유틸리티 전문 사이트는 국내 isp에서 주기적으로 웹 사이트
전체를 복사하여 Mirror 사이트를 운영하고 있다.

자바 애플릿을 웹 브라우저에 미리 설치한다.
자바의 로딩 속도를 향상 시키기 위하여 필요한 자바 애플릿의 클라스 파일들을
이용자 웹 브라우저의 자바 라이브러리에 미리 설치한다. 가령 네스케이프의 경우
zip으로 압축된 라이브러리 파일을 열어 필요한 클라스 파일들을 추가하고 다시
zip으로 묵어주면 된다. 또는 임의의 디렉토리안에 클라스 파일들을 넣어 이용자가
직접 CLASSPATH에 해당 디렉토리를 추가하면 웹 서버로부터 애플릿을 다운받아 로컬에
설치된 코드를 참조하여 사용할 수 있다. 그러나 이 방법은 임의의 이용자를 위한
성능 개선안이 될순 없다.
[O’Reilly : Web Performance Tuning 인용]

더 빠른 모뎀과 시스템 그리고 더 나은 그래픽 카드를 구입한다.
모뎀은 인터넷 속도를 좌우하므로 빠를수록 좋으며 그래픽 카드가 좋을수록 화면에
브라우징하는 속도가 개선될 수 있다.

나. 서버측의 성능 개선 [ 웹 서버 ]

더 빠른 인터넷 전용선을 확보한다.
성능을 개선할수 있는 가장 확실한 선택은 바로 더 빠른 전용선을 확보하는 것이다.
그러나 비용면에서 월 유지비가 많이 들어 가급적 사용량에 따라 최적의 전용선
속도를 선택하는 것이 현명하다. 인터넷 전용선 사용량은 Unix, Linux 용 네트워크
모니터링 프로그램으로 널리 알려진
MRTG(http://ee-staff.ethz.ch/~oetiker/webtools/mrtg/mrtg.html)를 가 많이 쓰인다.
이미 국내 모 ISP에서는 전용선 가입자에 대한 MRTG 및 보안 체크 서비스까지
제공하고 있다. MRTG에서 자사의 인터넷 사용량(IN/OUT)이 전용선 속도의 80%
이상까지 다다르면 패킷 손실이 생겨 폭주 및 과부하가 자주 발생할수 있으므로,
전용선 업그레이드를 고려할 필요가 있다.


최적의 Subnet Mask를 설정한다.
라우터의 경우 불필요한 Subnet Mask를 줄여줄 필요가 있다.
가령 같은 라우터에 연결된 컴퓨터들의 IP address 갯수가 30개밖에 되지 않으면서
굳이 subnetmask를 255.255.255.0로 잡아 사용하게 되면 나머지 225개의 D class IP
address를 검색하느라 라우팅 속도가 느려질 수 있다.

웹 서비스만을 위한 단독 시스템을 확보한다.
웹 서버와 메일 서버, 그리고 DNS 서버에 이르기까지 하나의 시스템으로 사용하는
경우가 많은데, 이것은 웹 서비스로는 치명적이다. 보안 문제가 생길수도 있으며, 웹
서버의 부하에 의해 다른 서비스에 차질이 생길수 있다. 물론, 그 반대의 경우도
가능하다. 가급적이면 웹 서버 시스템을 따로 구성하는데, 웹 서버 시스템의 경우
보통 RAM 용량을 충분히 확보하고 하드 드라이브는 빠른 스카시 타입을 사용함으로써
IO의 부하를 줄여 속도 향상을 가져올 수 있다. 연산이 과도한 CGI 프로그램이나
대용량의 DB 서버가 없다면 CPU까지는 굳이 업그레이드 할 필요는 없다. ^^

운영체제의 각종 제한 수치를 조정한다.
Linux의 경우 Sun과 같이 대용량 시스템이 아닌 PC급 서버를 기본 플렛폼으로
개발되고 서비스되는 까닭에 OS의 기본 설정이 Solaris에 비해 낮게 설정되어 있다.
결국 Linux에서 과부하를 이겨내기 위해서는 Linux 커널의 수정이 불가피하다. 그리고
운영체제에서의 TCP 재전송 최대 대기 시간 (TCP retransmit timeout)을 증가시킬
필요가 있다. 보통200 msec로 잡혀 있는데 느린 인터넷 환경에서는 200msec의 경우
TCP의 재전송 최대 대기 시간으론 부족할 수 있다. 이 외에도 웹 서버의 성능을 위해
각종 프로세스 관련 제한 수치를 조정할 필요가 있다.

웹 서버 프로그램의 성능을 최적화 한다.
웹 서버의 config 파일등에서 성능 향상을 위한 적절한 설정이 필요하다. 특히 아파치
웹 서버의 경우 기본 디폴트 값이 중 대형 웹 서비스를 하기엔 부족한면이 없지 않다.
최신 버전으로 업그레이드를 거듭할수록 더 많은 부하 및 속도에 대한 향상이 이루어
지므로, 가급적이면 최신 버전으로 업데이트를 해주는것도 좋은 방안이 될것이다. 이
글의 후반부에서 아파치 웹 서버에 대한 자세한 튜닝을 언급할 것이다.

자주 사용되는 cgi 결과들은 FILE(HTML…) 로 만든다.
이용자가 자주 실행하는 CGI 프로그램에 대한 결과나 DB 검색 결과등은 주기적으로
File(HTML…)로 만들 필요가 있다. 실행할 때마다 DB connect 에 의한 부하등을
획기적으로 줄일수 있기 때문이다. 현재 대부분의 검색 사이트들은 위와 같이 자주
읽히는 검색 결과들을 crontab을 이용하여 주기적으로 File로 만들어 두고 있다.

웹 서버를 분산 시킬 필요가 있다.
그래도 과부하에 의해 서비스가 지연될 경우에는 부하가 많이 걸리는 웹 사이트들을
따로 분리할 필요가 있다. 또는 DNS에서의 Round Robin 설정을 통해 이용자가
nslookup할때마다 다수의 IP 주소를 순차적으로 보내어 같은 웹 페이지를 가진
여러대의 웹 서버로 접속을 분산하면 그만큼 부하가 줄어들 것이다. 이외에도 전문
로드 밸런싱 소프트웨어를 이용하면 웹 서버의 접속 분산에 있어서 보다 지능화된
연결이 가능하다. 가령 DNS에서의 Round Robin 방식의 경우 단순히 IP 주소만을 달리
말해줄 뿐이지만, 전문 로드 밸런싱 서버를 이용하면 그때 마다의 각 웹 서버별
부하량을 체크하여 가장 부하가 적은 웹 서버로 접속을 유도할 수 있다. 물론, 접속
분산에 대한 스케줄 설정까지 가능하다. 유명한 무료 개인 홈페이지 제공 업체인
Geocity의 경우 지능형 로드 벨런싱 서버를 이용하여 수십대의 웹 서버를 분산시켜
운영하고 있다.

다. 웹 페이지의 성능 개선 [ HTML 문서]

HTML 문서의 용량을 최소한으로 줄인다.
여기서 말하는 HTML 문서의 용량은 웹 페이지에 속하는 각종 이미지등을 모두 고려한
용량을 말한다. 가령 이미지가 너무 크거나 웹 페이지의 소스가 필요없이 길경우
전체적인 웹 페이지의 용량은 증가하기 마련이다. 가령 56kbit/sec 모뎀의 이용자는
최대 초당 7 kbyte/sec 의 용량을 받을 수 있으므로, 웹 페이지의 전체 용량이 약
70Kbyte를 넘어설 경우 최소 10초 이상의 다운 로딩 시간이 필요하게 된다. 국내 및
해외 유명 웹 사이트들은 그 용량이 보통 60K 이하이다.

웹 브라우저의 캐시 기능을 활용한다.
전체적인 웹 페이지의 용량을 고려할 때 가급적 70K를 넘지 않는 것이 좋다고 했는데,
용량이 큰 이미지가 있다면 바로 앞의 용량에 여유가 있는 웹 페이지안에 픽셀 크기를
1로 잡아 점으로 처리하여 이용자의 브라우저 캐시에 미리 넣어 두는것도 좋은
방법이다. 물론, 목적 페이지에 도달하면 브라우저의 캐시에 저장된 이미지가 단숨에
로딩된다.

3. 웹 부하량 체크 방법

제대로된 튜닝을 하기 위해서는 우선 자신의 네트워크 및 시스템에 대한 부하를
체크할 필요가 있다. 여기서는 네트워크 및 웹 서버에 대한 종합적인 부하량 측정
방안을 알아보겠다.

가. 네트워크 부하량 체크

Traceroute (ftp://ftp.ee.lbl.gov/traceroute.tar.Z)
네트워크 연결 경로에 대한 라우팅 홉(HOP)지점마다의 주소와 그 속도를 측정할수
있는 유틸리티로 Linux의 경우 기본적으로 설치되어 있다.
- Sample -
[root@ns named]# traceroute -q 3 www.netkiller.com
## www.netkiller.com 에 대한 각 지점간 연결 속도를 3번씩 측정

traceroute to www.netkiller.com (210.103.183.35), 30 hops max, 40 byte packets
1 204.252.144.146 (204.252.144.146) 1.465 ms 1.433 ms 1.419 ms
2 210.116.126.41 (210.116.126.41) 17.030 ms 17.389 ms 357.989 ms
3 203.235.126.250 (203.235.126.250) 132.341 ms 18.414 ms 19.626 ms
4 210.103.227.38 (210.103.227.38) 203.928 ms 206.006 ms 179.701 ms
5 210.103.183.35 (210.103.183.35) 243.521 ms 24.088 ms 20.738 ms

Ping
양 끝단의 전체적인 속도 및 패킷 에러율을 체크하고자 할 경우 ping을 통해 일정량의
패킷을 보내어 다시 받을 때까지 걸리는 전체 시간과 패킷 손실율을 측정할 수 있다.

- Sample -
[root@ns named]# ping -c 10 www.netkiller.com
## www.netkiller.com 으로 총 10번의 ping을 실행한다.
PING www.netkiller.com (210.103.183.35): 56 data bytes
64 bytes from 210.103.183.35: icmp_seq=0 ttl=251 time=377.5 ms
64 bytes from 210.103.183.35: icmp_seq=1 ttl=251 time=417.6 ms
64 bytes from 210.103.183.35: icmp_seq=2 ttl=251 time=247.7 ms
64 bytes from 210.103.183.35: icmp_seq=3 ttl=251 time=367.1 ms
64 bytes from 210.103.183.35: icmp_seq=4 ttl=251 time=462.1 ms
64 bytes from 210.103.183.35: icmp_seq=5 ttl=251 time=957.6 ms
64 bytes from 210.103.183.35: icmp_seq=6 ttl=251 time=179.3 ms
64 bytes from 210.103.183.35: icmp_seq=7 ttl=251 time=77.0 ms
64 bytes from 210.103.183.35: icmp_seq=8 ttl=251 time=69.9 ms
64 bytes from 210.103.183.35: icmp_seq=9 ttl=251 time=498.8 ms

--- www.netkiller.com ping statistics ---
10 packets transmitted, 10 packets received, 0% packet loss
round-trip min/avg/max = 69.9/365.4/957.6 ms

이 경우 Avg Round-Trip time이 365.4 ms 가 나왔다.
일반적으로 자사의 라우터와 ISP간에 약 1,000 번의 ping 결과에서 에러율이 3~4%
미만이어야 한다.

netstat , ifconfig
서버의 전체적인 네트워크 패킷 충돌율을 체크할 경우 netstat – i 나
ifconfig –a 의 결과에서 직접 계산할 수 있다.
- Sample -
[root@ns named]# ifconfig -a
lo Link encap:Local Loopback
inet addr:127.0.0.1 Bcast:127.255.255.255 Mask:255.0.0.0
UP BROADCAST LOOPBACK RUNNING MTU:3584 Metric:1
RX packets:99477 errors:0 dropped:0 overruns:0 frame:0
TX packets:99477 errors:0 dropped:0 overruns:0 carrier:0
collisions:0

eth0 Link encap:Ethernet HWaddr 00:10:5A:69:ED:92
inet addr:203.231.38.2 Bcast:203.231.38.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:813704 errors:0 dropped:0 overruns:0 frame:0
TX packets:646433 errors:0 dropped:0 overruns:0 carrier:0
collisions:17681
Interrupt:10 Base address:0xec00
여기서 lo는 로컬이므로 의미가 없으며, eth0란에서 Collisions수만큼의 충돌이 TX
packets (출력 패킷)에 대해 발생하였으므로 (17681/646433) X 100 을 통해 충돌율이
약 2.7% 라는것을 확인할수 있다.
보통 약 8% 이상의 충돌율을 보인다면 네트워크를 점검해 보아야 한다.

MRTG등의 네트워크 전문 유틸리티를 통한 부하량 체크
앞서 언급한 MRTG나 XNI 등의 부하량 및 패킷 전문 체크 프로그램을 이용하면 보다
시각적으로 패킷 에러와 속도를 측정할 수 있다.

- Sample http://www.xni.com -


나. 웹 성능 측정 방법들

time
time은 유닉스에서 프로그램의 실행 시간을 측정해주는 기본 명렁어이다. 웹 서버의
접속 및 첫 Source를 받아오는데 걸리는 시간을 정확히 측정하고자 한다면 아래와
같이 해볼수 있다.

- Sample -

[root@ns named]# time lynx -source http://www.netkiller.com > /dev/null
0.05user 0.05system 0:02.34elapsed 4%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (1651major+639minor)pagefaults 0swaps

이것은 www.netkiller.com 의 웹 사이트에 lynx 브라우저로 접속하여 초기 웹
페이지의 source를 가져오는데 걸리는 총 시간을 측정한 결과인데, 소스의 경우 굳이
볼 필요가 없으므로 /dev/null로 보냈다. User : 0.05 , System : 0.05 그리고 총
실행 시간이 0:02.34 (2초 34) 가 걸렸으므로, 실제 접속 시간은 2.34 –
(0.05 + 0.05) = 2.24초가 된다. 보다 정확한 측정을 위하여 위의 명령을 몇번
실행시켜 평균 시간을 측정하여야 될것이다. 특히 처음 접속은 DNS서버의 캐시를
이용하지 않기 때문에 가장 느릴수 있기 때문이다.


ApacheBench (http://www.zeustech.net/)
아파치 서버를 위한 전문 측정 툴이다. 이 유틸리티는 레드햇 5.2 정품 리눅스의 경우
기타 application CD에 RPM으로 함께 제공되고 있는데 상당히 세밀하게 웹 서버의
성능을 체크할수 있다.

- Sample -
[root@ns named]# ab
ab: wrong number of arguments
Usage: ab [options] [http://]hostname[:port]/path
Options are:
-n requests Number of requests to perform
-c concurrency Number of multiple requests to make
-t timelimit Seconds to max. wait for responses
-p postfile File containg data to POST
-T content-type Content-type header for POSTing
-v verbosity How much troubleshooting info to print
-V Print version number and exit
-k Use HTTP KeepAlive feature
-h Display usage information (this message)
[root@ns named]# ab -n 10 http://www.netkiller.com:80/
This is ApacheBench, Version 1.2
Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright (c) 1998 The Apache Group, http://www.apache.org/

Server Software: Apache/1.3.1
Server Hostname: www.netkiller.com
Server Port: 80

Document Path: /
Document Length: 11417 bytes

Concurrency Level: 1
Time taken for tests: 16.625 seconds
Complete requests: 10
Failed requests: 0
Total transferred: 115460 bytes
HTML transferred: 114170 bytes
Requests per second: 0.60
Transfer rate: 6.94 kb/s received

Connnection Times (ms)
min avg max
Connect: 65 209 390
Processing: 886 1453 2210
Total: 951 1662 2600

TOP
상당히 많이 사용되고 있는 Processor의 상태를 보여주는 유틸리티로 RAM, CPU, IO ,
SwapSpace의 사용량까지 %로 자세히 보여준다.
특히 웹 서버의 경우 CPU 사용량이 계속적으로 50% 이상이고 IO쪽의 사용량이 크면서
하드 드라이브의 소음(?)이 심해지면 이것은 웹 서버 부하에 대한 시스템의 부족한
RAM에 의해 CPU가 과도한 일을 하고 있는 것이므로 CPU가 아닌 RAM의 증가가
필요하다.


4. 아파치 웹 서버의 성능 개선안

실제 유닉스 환경에서 가장 많이 사용되고 있는 웹 서버가 아파치 웹 서버인데, 이제
마지막으로 아파치 웹 서버에서의 성능을 개선하기 위한 방안을 한번 알아보자.

가. httpd.conf , srm.conf , access.conf 파일의 최적화 수정
예전에는 httpd.conf, srm.conf, access.conf 파일로 나누어져 있었지만 요즘의
아파치 웹 서버는 모든 config 관련 내용이 httpd.conf에 들어가 있다.

a. ServerType : StandAlone
이것은 이용자 접속 요청시 웹 서버의 Child Processor의 생성에 있어서 기존 Spare
Child Processor를 복사(Fork)하여 빠르게 대쳐할수 있도록 한다. 가령 100명의
이용자가 동시에 웹 서버로 접속할 경우 그때마다 config 파일을 참고로 하여 새로운
Child Processor가 만들어지는 inetd 방식보다 기존의 여유 Child processor를 fork
하여 대응하는 것이 훨씬 빠르고 효율적이다.
b. HostNameLookup off
이것은 접속자의 IP 주소에 대한 Reverse Lookup 을 방지한다. 대부분의 이용자들은
자신의 IP 주소에 대한 호스트, 도메인 이름이 없다. 그러므로 만일 HostNameLookup
on 을 하여 웹 서버가 매번 접속 요청자에 대한 네임 서버 검색 후 로그 파일을
작성하도록 하면 그 만큼 접속 시간과 부하량이 증가하게 된다.
c. Rotate log를 사용한다.
이용자가 접속할때마다 기록되는 access_log의 경우 한번 접속당 약 85Byte가
증가하여 하루 100만번의 접속으로 access_log 파일은 무려 약 405MByte가 증가한다.
이렇게 되면 접속때마다 log file을 access 하는데 상당한 시간과 부하가 발생된다.
그러므로 로그 파일을 일정 시간마다 초기화 함으로서 언제나 경량화 시켜줄 필요가
있는데, 이것은 httpd/support 디렉토리에 존재하는 rotatelogs라는 유틸리티를 쓰면
해결할 수 있다. 레드햇 리눅스 5.2 이상의 경우 syslog을 이용하여 log 파일을
관리하고 있다.
[ 형 식 : rotatelog logfilename time ]
httpd.conf의 TransferLog logs/access_log를 아래와 같이 수정
TransferLog “|/usr/loca/etc/httpd/support/rotatelogs
/usr/local/etc/httpd/logs/access_log 86400”
## 86,400초 (24시간)마다 access_log을 갱신한다는 뜻
참고 : error log 역시 위와같은 방법으로 수정 가능
d. ServerAlias를 이용한다.
가상 호스팅 추가시 ServerName www.domain.com 외에 ServerAlias *.domain.com
domain.com 를 아래에 추가하여 Alias 도메인의 가상 호스팅을 위해 불필요한
필드의 추가를 생략할 수 있다.
e. Error_log파일을 통합한다.
가상 호스팅의 경우 가급적 error_log 파일들은 하나의 error_log 파일로 지정해
관리한다. (운영체제의 동시 file open수 제한을 피하는 소극적 방법?)
f. KeepAlive on
이것은 접속 요청자에게 웹 서버 프로세스가 웹 페이지들을 전송할 때 내부의 여러
개체(그림파일) 전송까지 새로운 프로세스를 만들지 않고 담당 프로세스가 계속
접속을 유지 할 수 있도록 한다.
g. MaxRequestPerChild 를 증가시킨다.
프로세스가 일정 횟수의 클라이언트 요청을 처리하고 종료되는 추치인
MaxRequestPerChild 30을 시스템의 안정성에 따라 증가시켜준다. 보통 100 이상을
권한다. 만일 자신의 웹 서버 시스템이 상당히 안정적이라면 아예 1,000을 주기도
한다.
h. StartServer, Min, Max Spare Server 수를 가급적 증가시켜준다.
디폴트는 각각 5, 5, 10정도인데 웹 서버가 standalone 방식을 경우 새로운 접속
요청을 받으면 기존의 spare Child Processor를 Fork 하여 새로운 Child Processor를
만들어 내므로 기본적으로 Spare 프로세스가 많을 수 록 폭주에 빨리 대처할 수 있다.
각각 비례적으로 증가시키는 것이 바람직하다.
예) StartServer 20, Min SpareServer 20, Max SpareServer 40 (4배씩 증가)
i. MaxClient 150
이것은 동시에 떠 있을수 있는 최대 Processor 수를 제한하는 것인데, 이것은 결국
최대 동시 이용자수 제한과 같다. 물론, http 프로토콜의 특성상 접속자체가
비연결성을 가지므로, 150정도가 충분할수 있으나 필요시 더 늘려줄수도 있다. 그러나
OS에서의 기본 제한 수치를 넘어설 수 있으므로, 주의 해야 한다. 가령 nobody가
만들어낼수 있는 최대 프로세스의 개수가 150개로 OS에서 제한하고 있는데
MaxClient를 그 이상으로 조정하면 문제가 생길수 있다.

나. 운영체제(OS)의 각종 제한 설정 확인
앞서 언급한 각 Processor 수치와 가상 호스팅을 위한 동시에 Open되는 Log 파일의
개수를 확장하기 위해서는 해당 웹 서버의 운영체제의 자원에 대한 제한 수치를
확인할 필요가 있다.

ulimit
ulimit은 운영체제의 각종 Limit을 확인하는 명령어로서 아래의 수치를 확인할수
있다.
The Max number of system processess
The Max number of processes per user
The Max number of open files (can have open files)

웹 서버는 보통 nobody라는 이용자 권한을 가진 ChildProcessor에 의해 서비스된다.
가령 레드햇 리눅스의 경우 6.0 버전 이상부터 그 기본 수치가 상당히 증가되었는데,
이전 5.2버전의 경우 ulimit –a 으로 아래의 결과를 보인다.

[root@ns named]# ulimit -a
core file size (blocks) 1000000
data seg size (kbytes) unlimited
file size (blocks) unlimited
max memory size (kbytes) unlimited
stack size (kbytes) 8192
cpu time (seconds) unlimited
max user processes 256
pipe size (512 bytes) 8
open files 256
virtual memory (kbytes) 2105343

여기서 max user processes가 256 정도인데, 아파치 웹 서버의 conf 파일에서
MaxClient 를 256 이상 설정하면 OS의 기본 설정을 초과하므로 문제가 발생할 수
있다.
OpenFiles 역시 256이므로, access_log, error_log를 각 가상 호스팅 이용자에게 따로
부여할 경우에는 웹 서버의 log 파일의 총 개수가 256보다 아래여야 할것이다. 물론
이용자가 cgi 프로그램을 동시에 실행하여 open되는 file수도 고려해야 한다.

참고로 ulimit는 OS의 기본 설정을 확인하거나 기본 수치에 대해 줄일 때 사용할수
있다. 그러므로 ulimit을 통해 각 분야별 수치를 증가시키는 것은 아무런 효과가
없다.
OS의 기본 제한 수치를 증가시키고자 한다면 리눅스의 경우 별도의 커널 수정과 커널
컴파일이 필요하다. 그러나 레드헷 6.0부터 커널의 각종 설정들이 상당히 증가되어
(예 : openfiles, max user processes 가 1024로 증가) 이젠 굳이 커널을 수정하여
컴파일할 필요가 없다.


- 참고 자료 -

Apache Server Survival Guide [SAMS-Net]
Web Performance Tuning [O’REILLY]
TCP/IP [O’REILLY]
http://www.apache.org Web Site
http://www.linux.org Web Site
2005/07/04 14:22 2005/07/04 14:22

FTP 접속자 알아보기

FAQ 2005/07/04 14:21
ftp로 접속되어 있는 사용자를 확인하고 싶을 때
쓰는 명령어 입니다. 간단하지만 알고 있으면 유용
하게 사용할 수 있습니다.
ftpcount와 ftpwho가 있습니다. 다음은 사용 예입니다.

ex)
[root@op isseo]# ftpcount
Master proftpd process 562:
Service class - 1 user

[root@op isseo]# ftpwho
Master proftpd process 562:
19649 1m55s proftpd: isseo - 210.116.123.246: IDLE
Service class - 1 user
2005/07/04 14:21 2005/07/04 14:21
간혹 core파일의 크기가 커서 디스크에 쌓이는 경우가 있습니다.

core 파일의 크기를 0 으로 설정 한다면 core 파일로 인한

디스크의 공간적 손해를 막을수 있습니다..

방법은 /etc/system 파일에 다음과 같이 정의 하면 됩니다.


set sys:coredumpsize = 0
2005/07/04 14:21 2005/07/04 14:21
The / file system (/dev/rdsk/c0t0d0s0) is being checked.
/dev/rdsk/c0t0d0s0: UNREF DIR I=88085 OWNER=root MODE=40755
/dev/rdsk/c0t0d0s0: SIZE=512 MTIME=Mar 13 17:42 2003 (RECONNECTED)
/dev/rdsk/c0t0d0s0: DIR I=88085 CONNECTED. PARENT WAS I=16103
/dev/rdsk/c0t0d0s0: UNREF DIR I=16103 OWNER=root MODE=40755
/dev/rdsk/c0t0d0s0: SIZE=512 MTIME=Mar 13 17:42 2003 (RECONNECTED)
/dev/rdsk/c0t0d0s0: DIR I=16103 CONNECTED. PARENT WAS I=88007
/dev/rdsk/c0t0d0s0: LINK COUNT DIR I=16103 OWNER=root MODE=40755
/dev/rdsk/c0t0d0s0: SIZE=512 MTIME=Mar 13 17:42 2003 COUNT 0 SHOULD BE 2
/dev/rdsk/c0t0d0s0: LINK COUNT INCREASING
/dev/rdsk/c0t0d0s0: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.

Type Ctrl-d to proceed with normal startup,
(or give root passwrd for system maintenace):

위에서 엔터를 쳤을 경우 아래와 같이 나오면서 복구가 안될때.

INIT: Cannot create /var/adm/utmp or /var/adm/utmpx

INIT: failed write of utmpx entry:" "

INIT: failed write of utmpx entry:" "

INIT: Single User Mode


위와 같은 경우 아래와 같은 순서로 하시면 복구가 됩니다.

부팅시에 "STOP-A" or "Ctrl-c"(터미널인경우)

ok boot cdrom -s --> 설치된 OS와 동일한 OS CD가 있어야 합니다.

부팅과정 후 싱글모드로 떨어집니다.

# fsck /dev/rdsk/c0t0d0s0
# mount /dev/dsk/c0t0d0s0 /a
# TERM=suncmd; export TERM
# cd /a/var/adm
# touch wtmp
# touch utmp
# touch wtmpx
# touch utmpx
# cd /
# umount -a
# reboot

부팅후 보시면 시스템이 정상적으로 동작 될겁니다.
2005/07/04 14:20 2005/07/04 14:20

MTU 설정 방법

FAQ 2005/07/04 14:20
네트워크에는 최대 전송 단위, 즉 그 물리적인 네트워크를 통하여 전송할 수 있는 가장
큰 패킷이 지정됩니다.
하지만, 패킷 단편화 현상이 발생하지 않게 하려면 MTU를 변경하는 것이 좋습니다.
예를 들어, 트래픽이 MTU가 큰 네트워크(MTU가 4500 바이트인 FDDI 네트워크와 같은
네트워크)에서 떠나 이더넷과 같이 MTU가 작은 네트워크를 통과하는 경우, 패킷 단편화
현상이 발생하지 않게 하려면 MTU 크기를 작게 설정하는 것이 가장 좋습니다.
버퍼 오버런이나 그와 비슷한 문제를 줄이기 위해서도 MTU를 변경하는 것이 바람직합니다.

설정 방법은 아래와 같습니다.

1. ifconfig명령으로 네트워크 상태 확인. 아래에서 보시면 MTU가 1500으로 지정되어 있습니다.
[root@op etc]# ifconfig
eth0 Link encap:Ethernet HWaddr 00:50:DA:89:AC:33
inet addr:210.116.123.243 Bcast:210.116.123.255 Mask:255.255.255.192
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 ....

2. ifconfig 명령으로 아래와 같이 MTU값 변경
[root@op etc]# ifconfig eth0 210.116.123.243 netmask 255.255.255.192 mtu 256

3. ifconfig 명령으로 적용 확인 MTU가 256으로 변경되었습니다..
[root@op etc]# ifconfig -a
eth0 Link encap:Ethernet HWaddr 00:50:DA:89:AC:33
inet addr:210.116.123.243 Bcast:210.116.123.255 Mask:255.255.255.192
UP BROADCAST RUNNING MULTICAST MTU:256 Metric:1...
2005/07/04 14:20 2005/07/04 14:20
자신의 서버의 이더넷 포트를 통해 오고가는 패킷의
양과 패킷에러 정도를 알고 싶을 때는 netstat 명령어를
이용하여 확인 할 수 있습니다.

ex)
[root@op etc]# netstat -in 2
Kernel Interface table
Iface MTU Met RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg
eth0 256 0 1469960 0 0 0 87669 0 0 0 BMRU
lo 16436 0 12082 0 0 0 12082 0 0 0 LRU
2005/07/04 14:19 2005/07/04 14:19

tee 명령어 사용

FAQ 2005/07/04 14:19
때때로 현재 디렉터리의 목록을 본후 그 목록을 파일로 저장하고 싶다면
tee 명령어를 사용 하면 됩니다.

# touch dirfile
# ls -al | tee dirfile
# more dirfile
# ls -al | tee -a dirfile -----> 먼저 저장된 dirfile 내용의 끝부분
후부터 저장 됩니다.

ex)
[root@op isseo]# touch dirfile
[root@op isseo]# ls -al | tee dirfile
합계 33488
drwxr-xr-x 7 isseo isseo 4096 10월 28 22:56 .
drwxr-xr-x 19 root root 4096 10월 16 23:58 ..
-rw------- 1 huntsman huntsman 23 3월 13 2003 .bash_history
-rw-r--r-- 1 isseo isseo 24 3월 22 2003 .bash_logout
-rw-r--r-- 1 isseo isseo 191 3월 22 2003 .bash_profile
-rw-r--r-- 1 isseo isseo 124 3월 22 2003 .bashrc
-rw-r--r-- 1 isseo isseo 854 3월 22 2003 .emacs
-rw-r--r-- 1 isseo isseo 120 3월 22 2003 .gtkrc
.
.
.
.

[root@op isseo]# more dirfile
합계 33488
drwxr-xr-x 7 isseo isseo 4096 10월 28 22:56 .
drwxr-xr-x 19 root root 4096 10월 16 23:58 ..
-rw------- 1 huntsman huntsman 23 3월 13 2003 .bash_history
-rw-r--r-- 1 isseo isseo 24 3월 22 2003 .bash_logout
-rw-r--r-- 1 isseo isseo 191 3월 22 2003 .bash_profile
-rw-r--r-- 1 isseo isseo 124 3월 22 2003 .bashrc

위와 같이 디렉토리 내용이 파일로 저장 됩니다.
2005/07/04 14:19 2005/07/04 14:19
아래는 아파치 에러코드와 코멘트 입니다.

100 : Continue
101 : Switching protocols
200 : OK, 에러없이 전송 성공
201 : Created, POST 명령 실행 및 성공
202 : Accepted, 서버가 클라이언트 명령을 받음
203 : Non-authoritative information, 서버가 클라이언트 요구 중 일부만 전송
204 : No content, 클라언트 요구을 처리했으나 전송할 데이터가 없음
205 : Reset content
206 : Partial content
300 : Multiple choices, 최근에 옮겨진 데이터를 요청
301 : Moved permanently, 요구한 데이터를 변경된 임시 URL에서 찾았음
302 : Moved temporarily, 요구한 데이터가 변경된 URL에 있음을 명시
303 : See other, 요구한 데이터를 변경하지 않았기 때문에 문제가 있음
304 : Not modified
305 : Use proxy
400 : Bad request, 클라이언트의 잘못된 요청으로 처리할 수 없음
401 : Unauthorized, 클라이언트의 인증 실패
402 : Payment required, 예약됨
403 : Forbidden, 접근이 거부된 문서를 요청함
404 : Not found, 문서를 찾을 수 없음
405 : Method not allowed, 리소스를 허용안함
406 : Not acceptable, 허용할 수 없음
407 : Proxy authentication required, 프록시 인증 필요
408 : Request timeout, 요청시간이 지남
409 : Conflict
410 : Gone, 영구적으로 사용할 수 없음
411 : Length required
412 : Precondition failed, 전체조건 실패
413 : Request entity too large,
414 : Request-URI too long, URL이 너무 김
415 : Unsupported media type
500 : Internal server error, 내부서버 오류(잘못된 스크립트 실행시)
501 : Not implemented, 클라이언트에서 서버가 수행할 수 없는 행동을 요구함
502 : Bad gateway, 서버의 과부하 상태
503 : Service unavailable, 외부 서비스가 죽었거나 현재 멈춤 상태
504 : Gateway timeout
505 : HTTP version not supported
2005/07/04 14:18 2005/07/04 14:18
아래와 같은 명령어로 서버에서 웹페이지의 방문수를 알 수 있습니다.

<레드햇 사용자>
grep "GET / HTTP" /var/log/httpd/access_log | wc -l

<칼데라 사용자>
grep "GET / HTTP" /var/log/httpd/apache/access_log | wc -l

<데비안 사용자>
grep "GET / HTTP" /var/log/apache/access_log | wc -l

아파치를 default로 설치 했을 경우에는 위와 같이 아파지
access_log파일이 위치하지만 따로 소스를 컴파일 해서 설치
했을 경우에는 access_log파일이 위치한 곳을 찾아서 경로만
바꿔주면 됩니다.

ex)
[root@op logs]# pwd
/usr/local/apache/logs
[root@op logs]# grep "GET / HTTP" /usr/local/apache/logs/access_log | wc -l
739
[root@op logs]#
2005/07/04 12:44 2005/07/04 12:44
PHP에서 사용자가 입력한 E-mail의 주소를 체크하여 줄 필요가 있습니다.
그럴 경우 아래와 같은 정규표현식에 의해서 구현을 합니다.

E-mail 패턴검사

if(ereg("([^[:space:]]+)", $email) && (!ereg("(^[_0-9a-zA-Z-]+(\.[_0-9a-zA-Z-]+)*@
[0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*$)", $email)) )
{
echo ("E-mail을 정확히 입력하여주십시오!");
exit;
}
?>

세부설명

(ereg("([^[:space:]]+)", $email))
위의 내용은 사용자가 공백문자열을 입력하였을 경우를 체크합니다.

(!ereg("(^[_0-9a-zA-Z-]+(\.[_0-9a-zA-Z-]+)*@[0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*$)
위의 내용은 사용자가 입력한 전자우편주소가 올바른지를 체크합니다.

만약 사용자가 공란이나, 정확한 E-mail주소를 입력하지 않을 경우 echo문을 출력합니다.
echo ("E-mail을 정확히 입력하여주십시오!");

위의 방법들은 웹상에서 구현되는 가장 일반적인 E-mail 정규표현식입니다.
2005/07/04 12:43 2005/07/04 12:43
/etc/pam.d/login 과 /etc/pam.d/rlogin 의 첫 줄에 다음을 추가 합니다.

auth required /lib/security/pam_listfile.so item=user
sense=deny file=/etc/notelnetusers onerr=succeed

/etc/notelnetuser 화일을 만들어서 telnet login 금지시킬 사용자의 id를
적습니다.
2005/07/04 12:42 2005/07/04 12:42
etc/pam.d/su 에 첫줄에 다음을 추가 합니다.

auth required /lib/security/pam_wheel.so debug group=wheel

/etc/group 의 wheel 그룹에 su - 허용하고자 하는 사용자 그룹 등록

wheel:x:10:root,someone


만약 허용되지 않은 그룹의 사용자가 su - 를 시도하면
/var/log/message 에
PAM-Wheel[25873]: Access denied for 'babo' to 'root'
와 같이 로그가 남습니다.
2005/07/04 12:42 2005/07/04 12:42

log 파일 삭제하기.

FAQ 2005/07/04 12:41
서버를 운영하시다 보면 가끔 갑자기 크게 늘어난 로그파일
(스팸이나, 웜등으로 인한)때문에 디스크가 full이 나는 경우가
있습니다.

위의 경우 로그 파일을 무턱대고 지우면 해당 로그파일이 다시
생성이 안되는 경우가 있습니다.
물론 대부분 해당 서비스를 재시작 하면 해결이 되지만 다음과
같은 방법으로 하시면 간단히 해결하실 수 있습니다.

로그 파일의 삭제와 생성은 다음과 같이...

[root@op pam.d]# cp /dev/null /usr/local/apache/logs/access_log
cp: overwrite `/usr/local/apache/logs/access_log'? y

다른 로그파일들 역시 경로와 파일네임을 상황에 맞게 바꿔주시면 됩니다.
2005/07/04 12:41 2005/07/04 12:41
리눅스 커널의 버전 번호에는 아래와 같은 의미를 담고 있습니다.

* 커널 버전 번호 형태: X.Y.Z
- X : 주 버전번호
- Y : 부 버전번호
- Z : 개정 번호(Z번의 버그 수정을 했다는 표시)

* 안정버전/개발버전
- 안정버전: Y(부 버전번호)가 짝수
- 개발버전: Y(부 버전번호)가 홀수

ex)
uname -a"명령을 수행하면 다음과 같은 메시지가 출력됩니다.
[root@op isseo]# uname -a
Linux op 2.4.20-19.8 #1 Tue Jul 15 15:25:37 EDT 2003 i686 i686 i386 GNU/Linux

* 위의 커널 버젼을 해석 하자면 현재 안정 커널 2.4.20으로 20번의 버그를 수정했음
이라고 보시면 됩니다.
2005/07/04 12:40 2005/07/04 12:40

AutoUpdate

FAQ 2005/07/04 12:39
[출처] http://bbs.kldp.org/viewtopic.php?t=24352


RedHat 계열을 사용하는 사람들에게 대략 좋은 내용이니 잘 받아 적길 바란다.
rpm 은 Redhat Package Manager 로 말 그대로 패키지 관리자이다.
패키지 파일을 버전으로 관리하는 rpm은 RedHat에서 개발한 자동 갱신 소프트웨어인
up2date로 언제나 최신버전을 유지할 수 있다.

그러나 up2date 는 https://rhn.redhat.com 에 가입해야만 사용할 수 있는
소프트웨어이다. 물론 60일 무료계정을 이용할 수 있으며,
기한이 만기되면 간단한 설문조사를 하면 다음 60일까지 무난히 쓸 수 있다.

ㅡ0-) 그러나... 설문조사 마져도 귀차니즘 압박에 시달리는 사람과,

RedHat에서 공식 배포하지 않는 패키지(ex. RedHat9에서 ProFTPd를 제공하지 않는다)를 사용하는 사람에게
매우 좋은 autoupdate라는 프로그램이 있다.

autoupdate는 단순히 RedHat 배포판에만 적용되는 것이 아니라
rpm을 사용하는 Mandrake, SUSE 같은 배포판에도 적용할 수 있다.

Officaial Site : http://www.mat.univie.ac.at/~gerald/ftp/autoupdate

autoupdate는 Perl 로 쓰여진 언어이다. rpm, perl, perl-DB_File, perl-RPM2 등의
패키지가 필요하며 모든 것은 위의 홈페이지에서 받을 수 있다.
(perl용 FTP모듈은 최신버전 Perl 패키지에 포함되어 있다. 만약 없으면 위의 홈페이지에서
perl-libnet 패키지를 받자)

위의 사이트에서 autoupdate-xxx.rpm 와 autoupdate-cfg-배포판-xxx.rpm 을 받는다.
(xxx는 버전)

받은 모든 rpm을 설치한다.

$ rpm -Uvh *.rpm (받은 rpm 만 있는 디렉토리에서...)

설치는 다 됐다. 이제 단순히 autodld 라고 치면 up2date 와 비스무레한 행동을 할 것이다.

$ autodld
Found no new rpms at ftp.redhat.com.
Checking selected rpms.
Found no rpms to upgrade.
(흠... 모든 소프트웨어가 최신 버전이로군)


만약 새로 설치하고 싶은 패키지가 있다면 autoget을 이용하자.


$ autoget mod_ssl
New rpms from ftp.redhat.com:
mod_ssl-2.0.40-11.7.i386.rpm
Checking selected rpms.
Installing rpms:
mod_ssl-2.0.40-11.7.i386.rpm
Removing updated rpms:
mod_ssl-2.0.40-11.7.i386.rpm
(apache용 ssl 모듈을 설치해봤다.)


예제엔 나오지 않았지만 autoupdate는 up2date와 같이 의존성을 검사하여
필요한 패키지까지 모두 받아온다.
up2date는 rhnsd 이라는 Daemon을 이용하여 2시간마다 RedHat에 접속하여
새 패키지를 검사한다. (검사하는 속도가 좀 빠르긴 하지만...)

autoupdate 역시 비슷한 역할을 시킬 수 있다. cron을 이용해서 말이다.


(RedHat8 기준)
$ cd /etc/cron.daily
$ ln -s /usr/sbin/autodld


매일 한 번씩 autodld가 자동으로 실행된다.
물론 주기를 다르게 해서 등록하고 싶다면 다른 디렉토리나 /etc/crontab 을
수정을 해주면 된다.
2005/07/04 12:39 2005/07/04 12:39

rlogin 자료

FAQ 2005/07/04 12:38
# 는 root로 작업을 의미함

1. rlogin 관련 서버 프로그램들이 설정되어 있는지 확인
# ntsysv

여기에 rexec, rlogin, rsh 에 체크가 되어 있어야함
여기에 rlogin 등의 서비스가 없으면 해당 서버 프로그램을 설치해야 합니다.
rloing 클라이언트 프로그램은 rsh-0.17-5.i386.rpm 에 들어있지만 서버 프로그램은 rsh-server-0.17-5.i386.rpm 에 있습니다.
(버전은 운영체제의 버전에 따라 다를 수 있습니다)

# rpm -qa | grep rsh
===> 여기서 rsh, rsh-server 가 둘다 있어야 합니다. rsh는 클라이언트 프로그램, rsh-server는 서버 프로그램입니다. 현재 ntsysv에서 rlogin 서비스가 나오지 않는다면 서버 프로그램이 없을 가능성이 가장 큽니다.

# rpm -ql rsh
/usr/bin/rcp
/usr/bin/rexec
/usr/bin/rlogin
/usr/bin/rsh
/usr/share/man/man1/rcp.1.gz
/usr/share/man/man1/rlogin.1.gz
/usr/share/man/man1/rsh.1.gz


# rpm -ql rsh-server
/etc/pam.d/rexec
/etc/pam.d/rlogin
/etc/pam.d/rsh
/etc/xinetd.d/rexec
/etc/xinetd.d/rlogin
/etc/xinetd.d/rsh
/usr/sbin/in.rexecd
/usr/sbin/in.rlogind
/usr/sbin/in.rshd
/usr/share/man/man8/in.rexecd.8.gz
/usr/share/man/man8/in.rlogind.8.gz
/usr/share/man/man8/in.rshd.8.gz
/usr/share/man/man8/rexecd.8.gz
/usr/share/man/man8/rlogind.8.gz
/usr/share/man/man8/rshd.8.gz

rsh-server 프로그램이 없으면 인터넷에서 다운받아 설치해야 합니다. 물론 cd를 통해서 설치하는것도 가능합니다.
여러곳에 레드햇 미러 사이트가 있는데 아래 사이트를 참고하셔도 됩니다. (여러 ftp 사이트에서 redhat 을 미러링하고 있습니다)

ncftp ...en/os/i386/RedHat/RPMS > pwd
ftp://ftp.nuri.net/pub/redhat/linux/7.3/en/os/i386/RedHat/RPMS/
ncftp ...en/os/i386/RedHat/RPMS > ls rsh*
rsh-0.17-5.i386.rpm rsh-server-0.17-5.i386.rpm


rsh-server 프로그램을 다운로드받아서 먼저 설치를 합니다

# rpm -Uvh rsh-server-0.17-5.i386.rpm

설치가 끝났다면 해당 서비스를 활성화해야합니다.

먼저 ntsysv 에서 해당 서비스를 활성화합니다. 그리고 활성화한것을 서버에서 인식하도록 해야 하고 접근할 ip등을 설정해야 합니다.

redhat 6.x 버전까지는 inetd를 이용했지만 redhat 7.x 버전에서는 xinetd 라는 프로그램을 이용하고 있습니다.

# /etc/init.d/xinetd restart

그런데 xinetd는 각 서비스에 접근할 수 있는 ip등을 지정할 수 있습니다. 현재 외부 인터넷망에는 연결되지 않고 내부에서만 사용하기에 내부에서는 모두
다 접속되도록 설정했다고 생각이 드는데요.

# cat /etc/xinetd.conf
#
# Simple configuration file for xinetd
#
# Some defaults, and include /etc/xinetd.d/

defaults
{
instances = 60
log_type = SYSLOG authpriv
log_on_success = HOST PID
log_on_failure = HOST
cps = 25 30
only_from = 0.0.0.0
}

includedir /etc/xinetd.d

위에서 /etc/xinetd.conf 파일은 xinetd를 이용하여 작동을 하는 모든 프로그램에 대한 기본설정이 들어갑니다.
위에서 말을 했듯이 현재 서버가 외부에는 연결되지 않은 것이라면
only_from = 0.0.0.0 이렇게 해놓고 사용을 해도 됩니다.
모든 ip에서 접속가능하다는 뜻입니다. 일반적으로는 해당 서비스만 열어놓으면 되는데 이경우에는 /etc/xinetd.d/ 디렉토리에서 해당 프로그램만 접속할 ip를 지정하면 됩니다. 예를 들어 211.11.11.11 에서만 rlogin을 활성화한다면

only_from = 211.11.11.11

이런 식으로 설정하면 됩니다.

그리고 xinetd.conf 나 /etc/xinetd.d/ 디렉토리에서 변경한 파일이 있으면 xinetd를 다시 띄워주어야 변경한 내용을 반영합니다.

# /etc/init.d/xinetd restart

해당 서비스가 열려있는지 netstat를 이용해서도 확인할 수 있습니다.

# netstat -a
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 *:exec *:* LISTEN
tcp 0 0 *:login *:* LISTEN
tcp 0 0 *:shell *:* LISTEN



2. rlogin 설정
서로 접근할 호스트를 /etc/hosts.equiv 에 등록합니다. 물론 host 이름으로 사용하려면 아래 server1, server2를 /etc/hosts에 등록해놓아야 합니다.

# cat /etc/hosts.equiv
server1
server2


이제 rlogin 등의 프로그램을 이용하여 확인을 합니다.

# rsh server2 date

# rcp /etc/hosts server2:/tmp

# rlogin server2
# ls /tmp/hosts


---------------------------------------------------

1. rlogin 설정
client의 test, oracle user 가 server 의 oracle 계정에 접근하려고 하는 경우를 예로 들겠습니다.
(client, server는 hosts 파일에 ip를 등록해놓음)

server 에서 /etc/hosts.equiv 가 아래와 같이 설정되었을 경우.
client

호스트이름만 있을 경우 client 와 server 사이에 동일하게 있는 user는 client 에서 server로 동일한 계정으로 접근 가능합니다.
oracle user는 rcp 등의 명령을 사용할 수 있습니다.

[oracle@client oracle]$ rcp a.txt server:/home/oracle/b.txt

그런데 client 의 test 유저는 server의 오라클 계정에 접근하려면 접근 에러가 납니다.

[test@client test]$ rcp a.txt oracle@server:/home/oracle/b.txt

# tail -f /var/log/mesage -> 여기서 root 권한으로 로그파일 볼 수 있습니다
Apr 29 23:14:52 server pam_rhosts_auth[11961]: denied to test@client as oracle: access not allowed
Apr 29 23:14:52 server in.rshd[11961]: rsh denied to test@client as oracle: Permission denied.

server 의 /etc/hosts.equiv 에서 호스트명만 지정하면 동일한 계정만 접근이 된다는 것입니다.

server 에서 /etc/hosts.equiv 가 아래와 같이 설정되었을 경우.
client test

이 경우에는 client 호스트에서 test 사용자는 server 의 root 계정을 제외한 모든 계정에 대해 패스워드 없이 액세스할 수 있습니다. server 의 oracle 외
에도 다른 계정의 디렉토리에도 접근할 수 있다는 말입니다. /etc/hosts.equiv 에서 호스트명 사용자명의 형태로 들어가는데 여기서 사용자명은 서버 기준이 아니라 클라이언트 기준으로 된다는 것입니다. 바로 위에서는 client 의 test 사용자에게 어떤 계정에도 접근이 가능하다는 것이지 server의 test 계정에만 접근 가능하다는 것이 아닙니다.


그러면 개별 계정의 .rhosts 가 하는 역할은? 일단 server 에 위의 /etc/hosts.equiv 파일은 없다고 가정하겠습니다.

server 의 oracle 계정의 .rhosts 가 다음과 같을 경우.

client

이경우에는 client 의 oracle 사용자가 server의 oracle 계정에 접근할 수 있다는 것을 의미합니다. test 사용자는 oracle 계정에 접근할 수 없다는 것입니다.

server 의 oracle 계정의 .rhosts 가 다음과 같을 경우.

client test

이경우에는 client 의 test 사용자가 server의 oracle 계정에 접근할 수 있다는 것을 의미합니다. (그런데 client test 라고만 설정해두면 client 의 oracle 사용자는 접근하지 못합니다)

*********** 결론적으로 이야기를 하겠습니다. ******************
편리하게 사용하려면 아래와 같이 사용하는것이 좋을 것 같습니다.
- server 의 /etc/hosts.equiv 에는 rcp 등으로 접근할 클라이언트의 호스트명만 등록합니다. 그러면 client 와 server 의 동일한 계정은 접근이 가능합니다.
- server 의 접근해야 할 계정(예를 들어 oracle) 의 홈 디렉토리에 .rhosts 파일을 만들어 특정 client의 계정까지 등록합니다. (client test)
- .rhost 파일은 그룹이나 other 사용자가 w 권한을 가지고 있으면 에러가 생기므로 퍼미션을 644로 맞추어놓습니다 (chmod 644 .rhosts)

윈도우 2000에도 rcp 명령이 있어서 테스팅을 해보았습니다. 윈도우 2000의 로그인 사용자는 taejun 이며 서버의 oracle 계정에 접근합니다.

- 윈도우의 hosts 파일에 server의 ip와 호스트명을 입력합니다.
- server 의 /etc/hosts 파일에 윈도우의 ip와 호스트명을 입력합니다. (예 192.1.1.5 windows)
- server 의 /etc/hosts.equiv 파일에 /etc/hosts 파일에 등록한 윈도우의 호스트명을 넣습니다
- server의 oracle 계정에 .rhosts 파일을 만들고 윈도우 호스트명과 taejun 계정을 넣습니다 (windows taejun)
- .rhosts 파일의 퍼미션은 644 로 맞춥니다.
- 이제 윈도우의 taejun 사용자가 server 의 oracle 계정에 rcp 명령등을 사용할 수 있습니다.
** 참고로 /etc/hosts.equiv 에 windows taejun 이라고 등록을 하면 server의 다른 계정에도 접근 가능합니다

마지막 문제는 도스에서 접근할 경우 도스가 어떤 사용자로 접속하느냐를 판단해야 합니다. 가장 좋은 것은 /var/log/message 파일을 살펴보는 것입니다.
# tail -f /var/log/mesage

root 계정으로 계속 위의 메시지 파일을 참고하시면서 테스팅하면 되며 도스에서 접속시 어떤 사용자로 접속하는지를 보고 해당 사용자를 .rhosts 파일에
넣어주면 됩니다. (로그파일에는 접속을 하지 못할 경우 에러가 나며 그에 대한 예제는 위에 있습니다. )
2005/07/04 12:38 2005/07/04 12:38
글 • 문태준 taejun@tunelinux.pe.kr

tunelinux.pe.kr/database.sarang.net 운영자



연재 순서

1. 시스템 모니터링 I

2. 시스템 모니터링 II

3. 운영체제와 커널 차원에서의 튜닝과 보안

4. 응용프로그램에서의 최적화

5. 시스템 모니터링 자동화




시스템의 성능은 여러 가지 프로그램의 요청에 대해 현재의 시스템 자원을 얼마나 효율적으로 조정하여 사용하는가에 달려있다. 일반적으로 가장 중요한 시스템 자원은 CPU, 메모리, 디스크 입출력이며 인터넷 서비스가 일반화된 상황에서 네트워크에 대한 부분도 중요하게 다뤄져야 한다. 시스템을 안정적으로 관리하기 위해서는 지속적인 시스템 관리를 통해 문제 발생시 적절히 대처할 수 있는 기술이 필요하다. 이와 관련된 내용은 일반적인 시스템 관리 서적 및 여러 가지 자료를 통해 많이 언급되었기 때문에 여기서는 시스템 모니터링 결과를 정확히 판단하는 방법과 시스템의 문제에 대한 효과적인 대처 방법을 중심으로 알아보겠다.



1. 시스템 모니터링 분야와 관련 프로그램

문제를 점검할 모니터링 분야에 대한 시스템 모니터링 프로그램을 먼저 알아보자. 여기 있는 프로그램들은 대부분 운영체제를 설치하면서 자동으로 설치가 되는 프로그램들이다. (sar, iostat, nmap, netcat, ntop 등은 별도로 설치를 해야 하는 모니터링 프로그램이다)



분야
모니터링 프로그램

CPU
top, ps, uptime, vmstat, pstree, iostat, sar

메모리
free, vmstat, sar

디스크 I/O
df, du, quota, iostat, sar

네트워크
ping, netstat, traceroute, tcpdump, nmap, netcat, ntop

파일(소켓포함)
Lsof


표 1 . 시스템 분야별 모니터링 프로그램

시스템이 정상적으로 작동하고 있을 때 정기적으로 모니터링을 해 두어야 시스템에 문제가 생겼을 경우 신속하게 분석하여 문제를 해결할 수 있다. 즉, 주기적인 점검이 계속되어야 한다는 것이다. 보통 이런 작업등은 반복적이고 지루한 과정이므로 자동화하기 위한 노력이 필요하며 관리자가 직접 스크립트를 작성할 수도 있고 SNMP(Simple Network Management Protocol, 간이 망 관리 프로토콜) 등의 프로그램을 응용하여 자동화할 수도 있다. 모니터링 자동화에 대해서는 이후 강의에서 다룰 예정이다.



2. 시스템 모니터링과 문제 찾기

2.1 시스템의 부하 확인

시스템에 문제가 생겼을 경우 가장 먼저 어떤 프로그램을 실행하고 어떻게 사용하고 있었는지 점검해야 한다. 그리고 uptime을 이용하여 시스템의 부하를 확인한다. 일반적으로 웹서비스의 경우에는 낮 시간대에 접속이 폭주하므로 점심시간 무렵에 시스템의 부하가 올라갈 것이다. 그런데 접속이 폭주할 시간이 아닌대도 시스템의 부하가 높아지고 있다면 특정한 프로그램에서 문제가 발생하여 시스템의 자원을 소비하고 있을 가능성이 크고 서비스 거부 공격을 받고 있을 수도 있다. 시스템 부하가 어떻게 변동하고 있는지 확인을 했다면 ps와 top을 이용하여 구체적으로 프로세스의 상태를 점검한다.



2.2 ps와 top를 이용한 프로세스 모니터링

ps와 top을 살펴보면서 주의할 점과 중요하게 살펴볼 내용에 대해서 설명하겠다. top에서 CPU 상태는 사용자 모드, 시스템 모드, 우선 순위가 조정된 작업(niced task) 과 cpu 휴지시간(idle) 을 모두 포함한다. 그런데 여기서 우선 순위가 조정된 작업은 시스템과 사용자 시간에서 이미 계산이 되어 있으므로 100퍼센트가 넘을 수 있다.

ps와 top을 이용하여 모니터링을 할 경우 먼저 살펴보아야 하는 것이 디스크 액세스나 페이징을 기다리고 있는 프로세스가 있는가이다. 이런 경우에는 I/O와 메모리를 같이 점검해야 한다. 리눅스에서 프로세스 대기 상태는 인터럽트 허용과 인터럽트 금지의 두 가지 형태가 있다. 세마포어를 기다리거나 파일을 읽을 수 있게 되길 기다리는 것처럼 자원을 기다리는 일반적인 대기상태는 대개 인터럽트로 처리가 가능하다(인터럽트가 허용되는 sleep 상태는 ps, top 등에서 S로 나타난다). 그렇지만 인터럽트가 금지되는 대기 상태는 스왑 파일에서 메모리로 페이지를 읽어들이는 것과 같이 일이 끝마치기를 기다리고 있는 상태이다.

프로세스 상태에서 D는 인터럽트가 불가능한 sleep 상태로 page fault 등을 의미하며 page fault 등을 통해 I/O중인 상태를 나타낸다. W는 상주하는 페이지가 없다는 것을 의미하며 프로세스가 스왑아웃된 상태를 나타낸다. 여기서 W는 커널 프로세스에 대해서는 정확히 동작을 하지 않는다는 의미이다. 일반적인 응용프로그램을 실행하면 주기억장치에 상주한 후 프로세스가 처리되고 상대적인 주소를 가지게 된다. 그런데 커널은 다른 응용프로그램처럼 상대적 어드레스를 가지는 것이 아니라 시스템이 부팅된 후 가장 먼저 주기억 상치에 상주하기 때문에 언제나 같은 주기억 장치의 번지에 상주하게 된다. 그러므로 커널 프로세스에서 스왑을 하는 일도 없고 당연히 해서도 안되는 것이다.

ps와 top에서 메모리와 관련된 부분중 차이가 나는 것이 있다. 프로세스의 메모리 구조는 텍스트, 데이터, 스택 등으로 이루어져 있다. 텍스트에는 프로그램 코드와 상수가 정의되어 있으며 읽기만 가능한 메모리 영역이다. 데이터는 정적 변수가 저장되어 있는 영역이고 스택은 동적으로 할당되는 데이터, 함수 내의 변수, 함수의 리턴 어드레스 등이 저장되는 영역이다.

ps에서 보는 프로세스 정보는 ‘/proc/PID/’의 정보를 보여주는 것이다. ‘/proc/PID/status’의 내용을 확인해 보자. ps의 VSZ는 가상 메모리에서 사용중인 모든 메모리를 합친 VmSize를 보여준다. 그러나 top에서 SIZE는 코드, 데이터, 스택을 합친 크기를 보여준다. 가상 메모리는 커널에서 자동으로 조절하기 때문에 문제가 생길 일은 없으며 RSS를 통해서 실제 물리적 메모리에서 사용하는 메모리 양을 알 수 있다. 그리고 SIZE와 RSS 필드에는 페이지 테이블과 프로세스의 task_struct는 포함되어 있지 않은데 최소 12KB의 메모리를 항상 사용한다.



# cat /proc/413/status

Name: named

State: S (sleeping)

Pid: 413

PPid: 1

TracerPid: 0

Uid: 25 25 25 25

Gid: 25 25 25 25

FDSize: 32

Groups: 25

VmSize: 2596 kB

VmLck: 0 kB

VmRSS: 852 kB

VmData: 756 kB

VmStk: 28 kB

VmExe: 560 kB

VmLib: 1196 kB

SigPnd: 0000000000000000

SigBlk: 0000000000000000

SigIgn: 8000000000000000

SigCgt: 0000000009015a0b

CapInh: 0000000000000000

CapPrm: 0000000000000000

CapEff: 0000000000000000


리스트 1 . /proc 에서 프로세스 정보 확인하기

2.3 vmstat를 이용한 메모리와 디스크 I/O 확인



# 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

7 0 0 96940 1588 14712 337044 0 9 18 27 116 40 3 0 96

4 0 0 96940 1648 14700 336172 0 0 805 118 197 260 91 9 0

1 1 0 96940 1588 14700 335680 0 0 1000 106 203 268 93 7 0

3 1 0 96940 1708 14496 334652 0 0 1273 604 220 272 94 6 0


리스트 2. vmstat 이용한 cpu, i/o 모니터링



vmstat를 이용하여 CPU와 I/O 활동을 모니터링할 수 있는데 vmstat에서 나오는 첫 줄은 부팅 이후의 각 통계치에 대한 평균값을 보여주므로 무시하고 두 번째 줄부터 통계를 보면 된다. vmstat에서 중요한 것은 procs 영역의 b 필드이다. r은 현재 실행중인 프로세스 수이고 b는 인터럽트가 불가능한 sleep 상태에 있는 프로세스로 I/O 처리를 하는 동안 블럭 처리된 프로세스이며 w는 강제로 스왑아웃된 프로세스 수이다. si와 so는 스왑인, 스왑아웃을 말한다.

스왑아웃이 지속적으로 발생한다면 메모리가 부족한 것이다. 그러나 일정 간격을 두고 주기적으로 스왑아웃이 발생하는 것은 정상적인 일이다. BSD 시스템에서는 비상호 대화적인 작업을 스왑아웃 한다. 현재 실행하고 있는 프로그램에서 스왑아웃이 계속 발생한다면 프로그램이 멈출 수도 있으며 심각하게 메모리가 부족하다는 것을 의미한다. 스왑아웃필드(so)는 항상 0에 가까워야 한다. 그렇지 않다면 프로세스들은 가상 메모리를 놓고 경쟁하게 되며 시스템은 페이징 상태가 된다. 페이징 활동은 심각한 가용 메모리(free)의 부족과 직접적인 관련을 가지며 간접적으로는 시스템의 높은 CPU 사용 시간 비율(sy)과 관련이 있다. 프로세스가 시작할 때 항상 이미지와 데이터를 page-in 해야 하므로 page-in 열에서 높은 숫자가 항상 심각한 것은 아니라는 사실은 기억하고 있어야 한다.

시스템에서 사용하는 시간이 지나치고 높으면(50퍼센트 이상) 디스크 I/O에서 문제가 있을 가능성이 크다. 시스템 전체의 부하가 높은데 CPU에서 휴지시간(idle time, id 항목)이 일반적으로 10퍼센트를 넘는다면 I/O나 메모리에 문제가 있을 가능성이 크다. 휴지시간(id)이 항상 0이라면 CPU를 100퍼센트 사용하고 있는 상태이다. CPU의 기능을 최대한 활용하는 것은 좋은 현상이다. 그런데 항상 100퍼센트로 활용중인 상태라면 어떤 작업이 계속 축적되고 있다는 것이며 CPU가 과부하를 가진다는 의미한다. 이 때는 CPU를 계속 사용하고 있는 프로세스를 찾아야 하며 디스크의 활동이 분산되지 않았다면 I/O 작업을 효율적으로 분산시켜야 한다.

대부분의 사용자가 vmstat에서 si, so(스왑인, 스왑 아웃)를 주로 보고 id가 넉넉하면 시스템에 무리가 없는 것으로 생각한다. 이는 시스템의 상황에 대해서 잘못 파악할 가능성이 많은 것으로 b의 수치가 높은 경우 I/O작업을 위해 CPU가 계속 대기 상태로 있는 경우이다. 이런 경우에는 디스크 I/O 문제를 확인해야 한다.



2.4 nice를 이용한 우선 순위 조정

nice는 프로세스의 우선 순위를 조정하는 것이다. 그런데 시스템에 문제가 있는 경우 nice를 이용하는 것은 임시방편일 뿐이다. 부하가 계속 증가한다면 nice를 이용하는 것에도 한계가 있다. 시스템을 업그레이드하거나 부하를 분산할 시스템을 구입해야 한다.

커널이나 프로그램의 컴파일을 하는 경우에도 nice를 이용하면 조금이나마 속도의 향상이 있다. 그렇지만 때로는 nice를 잘못 사용하여 문제가 생길 수 있으니 조심해야 한다. 예를 들어 오라클에서는 오라클 사용자 프로세스와 백그라운드 프로세스들을 같은 우선 순위에 유지해야 한다. 오라클 DB의 설계가 그러한 우선 순위로 되어 있기 때문이다. 우선 순위를 변경할 경우 내용과 반응 시간에 원하지 않는 효과를 초래할 수도 있다. 예를 들어 로그 작성 프로세스(LGWR, log write process)에 낮은 우선 순위를 부여할 경우, 이 프로세스는 충분한 횟수만큼 작동하지 못하고 LGWR은 병목현상을 일으키게 된다. 반대로 LGWR이 높은 우선 순위를 부여받게 되면, 사용자 프로세스는 느린 반응시간에 시달리게 될 것이다. 세부적인 원리를 이해하지 못한채 이런 기능을 사용하면 시스템에 커다른 문제가 생길 수 있다는 것을 꼭 기억하기 바란다.



2.5 free를 이용한 자유 메모리 확인과 버퍼 캐쉬

메모리를 점검하기 위해 흔히 free를 사용한다. 그런데 free의 결과를 잘못 이해하면 전혀 이상한 결과를 초래할 수 있다.



$ free

total used free shared buffers cached

Mem: 513368 508316 5052 0 12688 339436

-/+ buffers/cache: 156192 357176

Swap: 1028152 96940 931212


리스트 3. free 이용하여 메모리 확인하기



먼저 버퍼 캐쉬에 대하여 알아보자(kldp.org/Translations/html/SysAdminGuide-KLDP/buffer-cache.html 참조) 디스크를 읽는 일은 메모리를 읽는 것보다 아주 느리다. 더구나 디스크의 동일한 영역을 짧은 시간 동안 반복해서 계속 읽는 일은 아주 빈번하다. 예를 들어, 누군가 e메일 메시지를 읽고, 답장을 하기 위해 편집기로 불러들이고, 그걸 보내기 위해 메일 프로그램에게 다시 읽게 하는 과정을 생각해 보자. 또한 ‘ls’와 같은 명령어를 시스템의 모든 사용자들이 얼마나 자주 사용할지 생각해 보자. 따라서 디스크로부터 한번 읽어들인 정보를 메모리에 상당시간 보관한다면 읽을 때만 시간이 소요될 뿐 속도가 전반적으로 빨라질 것이다. 바로 이런 것을 가리켜 디스크 버퍼링(disk buffering)이라고 하며, 이런 목적으로 쓰이는 메모리를 버퍼 캐쉬(buffer cache)라고 부른다.

그러나 메모리는 아쉽게도 한정되어 있는 중요한 자원이기 때문에 버퍼 캐쉬는 일반적으로 큰 크기를 가질 수 없다. 즉, 우리에게 필요한 모든 데이터를 담아둘 수 있을 정도로 크지는 않다. 따라서 캐쉬가 가득 채워지면 오랫동안 쓰이지 않은 데이터는 버려지며 그 빈 공간을 새로운 데이터가 채우게 된다.

이런 디스크 버퍼링은 쓰기에도 똑같이 적용된다. 데이터들은 쓰여지자 마자 곧바로 다시 읽혀지므로(예를 들어, 소스 코드 파일은 일단 파일로 저장된 후, 컴파일러에 의해 다시 읽혀진다), 이런 데이터들을 캐쉬에 넣어두는 것이 효율적이다. 또한 쓰기 작업을 디스크에 직접 하지 않고 캐쉬에 넣어두면, 프로그램들이 그만큼 출력을 빨리 끝낼 수 있기 때문에 전반적인 시스템 성능 향상에도 도움이 된다.

대부분의 운영체제들이 버퍼 캐쉬를 갖고 있기는 하지만 모두 위와 같은 원리로 동작하는 것은 아니다. 한가지 방법은 ‘write-through’라는 것인데, 이 방법은 쓰기를 할 때면 언제나 디스크에도 즉시 기록하는 것이다(물론 캐쉬에도 남겨둔다). 또 다른 방법은 write-back이라 불리는 것으로 일단 캐쉬에 기록해 두었다가 나중에 한꺼번에 디스크에 기록하는 방식이다. 효율적이기는 write-back 방식이 뛰어나지만, 대신 약간의 에러가 발생할 소지가 있다. 즉, 시스템이 갑자기 멈춰버린다거나, 갑자기 전원이 꺼진다거나 캐쉬 내용을 미처 기록해 두기 전에 플로피 디스크를 빼 버린다면, 캐쉬에 담겨 있던 내용들은 고스란히 없어져 버리고 만다. 특히 손실된 정보가 파일 시스템 유지에 필요한 데이터였다면, 자칫 전체 파일 시스템을 망가뜨리고 마는 결과를 초래할 수도 있다.

그런데 사실상 캐쉬는 파일을 버퍼링하는 것은 아니고, 실제로는 디스크 입출력의 가장 작은 단위인 블럭을 버퍼링한다(리눅스에서는 보통 1KB 크기이다). 그러므로 디렉토리라든가, 수퍼 블럭들, 다른 파일 시스템의 유지 데이터, 심지어 파일 시스템이 없는 디스크까지도 캐쉬될 수 있는 것이다.

캐쉬의 효율성은 기본적으로 그 크기에 좌우된다. 캐쉬의 크기가 너무 작으면 다른 데이터를 캐쉬하기 위해서 캐쉬된 데이터를 계속 내보내야 하므로, 사실상 작은 캐쉬는 별 쓸모가 없는 셈이다. 캐쉬의 최소 크기는 얼마나 많은 데이터가 읽고 씌여지는 지와, 같은 데이터가 얼마나 자주 액세스 되는지에 달려있는데 이것을 알아보기 위한 유일한 방법은 실험해 보는 것 뿐이다.

만일 캐쉬의 크기가 고정되어 있다면, 그 크기가 너무 큰 것도 곤란한 일이다. 캐쉬가 너무 크면 여유 메모리는 그만큼 줄어들 것이고, 많은 스와핑을 일으켜서 시스템은 느려지게 된다. 리눅스는 자동적으로 모든 램의 빈공간을 버퍼 캐쉬로 사용하여 메모리의 효율성을 높이려 하는데, 프로그램들이 많은 메모리를 필요로 할 때는 자동적으로 캐쉬를 크기를 줄여 준다. 그래서 완전 자동화된 리눅스는 캐쉬를 사용하는 데 있어서 전혀 신경쓸 필요가 없는 OS인 것이다. 다만 셧다운 할 때와 플로피를 빼낼 때의 절차는 꼭 지켜야 한다.

위와 같이 디스크 접근을 줄여 시스템의 성능을 향상시킬 목적으로 있는 것이 버퍼 캐쉬이다. 만일 캐쉬의 크기가 고정되어 있다면 그 크기가 너무 커도 메모리 부족 현상이 생길 수 있고 지나친 스와핑을 발생하게 해서 시스템이 느려질 가능성이 크다. 리눅스에서는 자동적으로 모든 램의 빈 공간을 버퍼 캐쉬로 사용하여 메모리를 효율성을 높이고 있으며 프로그램에서 많은 메모리를 필요로 하는 경우에는 자동으로 캐쉬의 크기를 줄인다. 위에서 실제로 사용 가능한 메모리는 ‘free+buffers+cached’이다. 다음 내용을 보면 현재 메모리를 알아볼 수 있는 원리를 잘 반영하고 있다.



-/+ buffers/cache: 156192 357176



자 그러면 이제 올바른 답을 내릴 수 있을 것이다. 현재 여유가 있는 메모리는 ‘free+buffers+cached’를 합친 양으로 위의 소스에서는 357M이다. 그리고 전체 열에 나오는 수치도 실제 물리적인 램 양보다는 약간 적은 양이 표시된다. 왜냐하면 커널이 자체적으로 사용하고 있는 메모리를 뺀 양이기 때문이다.



2.6 iostat와 sar 활용한 디스크 I/O 및 시스템 모니터링

vmstat 명령을 통해 I/O부하를 확인할 수 있다는 것을 알았다. 그런데 여러 개의 하드 디스크를 사용하는 경우 vmstat를 이용해서는 어느 디스크에서 속도가 느리거나 병목 현상이 생기는지 확인을 할 수 없다. 다만 디스크 전체의 평균값만 나타내기 때문이다. 이런 경우에 사용할 수 있는 프로그램이 iostat이다. iostat 프로그램은 레드햇 6.2에는 기본으로 들어있지 않지만 레드햇 7.0 이후 버전에는 기본으로 들어있다(배포본은 6.2이지만 커널은 2.4대에 보안 및 reiserfs, lvm패치 등을 사용하고 있다). iostat는 sysstat라는 패키지에 들어있으며 현재 설치되지 않은 경우에는 다음 사이트에서 다운로드 받을 수 있다.

http://perso.wanadoo.fr/sebastien.godard/

http://freshmeat.net/에서 검색을 해도 된다.



# lynx ftp://metalab.unc.edu/pub/Linux/system/status/sysstat-4.0.1-1.i386.rpm

# rpm -Uvh sysstat-4.0.1-1.i386.rpm

sysstat ##################################################



# rpm -ql sysstat

/usr/bin/iostat

/usr/bin/isag

/usr/bin/mpstat

/usr/bin/sar

/usr/lib/sa/sa1

/usr/lib/sa/sa2

/usr/lib/sa/sadc

/usr/man/man1/iostat.1

/usr/man/man1/isag.1

/usr/man/man1/mpstat.1

/usr/man/man1/sar.1

/usr/man/man8/sa1.8

/usr/man/man8/sa2.8

/usr/man/man8/sadc.8

/usr/share/locale/de/LC_MESSAGES/sysstat.mo

/usr/share/locale/es/LC_MESSAGES/sysstat.mo

/usr/share/locale/fr/LC_MESSAGES/sysstat.mo

/usr/share/locale/pt/LC_MESSAGES/sysstat.mo

/var/log/sa


리스트 4. sysstat 프로그램 설치



iostat만이 아니라 isag, mpstat, sar, sa1, sa2, sadc 등의 프로그램이 같이 들어있다. 여기서 iostat와 sar는 다른 유닉스에서도 시스템 모니터링을 위해서 자주 사용하고 있는 프로그램이다. 여기서도 iostat와 sar을 같이 살펴보겠다.



# iostat

Linux 2.4.4 (tunelinux.pe.kr) 07/17/01



avg-cpu: %user %nice %sys %idle

0.30 0.00 27.30 72.40



Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn

dev8-0 252.20 4.80 60099.20 24 300496

dev8-1 0.00 0.00 0.00 0 0

dev8-2 379.80 48880.00 9.60 244400 48

dev8-3 0.00 0.00 0.00 0 0


리스트 5. iostat 이용하여 디스크 I/O 모니터링하기



위에서 보듯이 iostat는 CPU와 디스크 I/O에 대한 통계를 보여준다. CPU가 여러 개 있는 SMP 시스템에서 CPU 통계는 모든 프로세스를 합한 평균값을 나타낸다. 사용자 모드(응용 프로그램), nice 우선권을 가진 사용자 모드, 시스템 모드(커널), CPU idle 시간으로 통계를 보여준다. CPU 관련 통계는 다른 프로그램을 이용해도 확인을 할 수 있으므로 여기에서 관심이 가는 것은 디스크 드라이브에 대한 통계이다. 여기에서는 현재 네 개의 디바이스가 있다. 출력한 결과가 나타내는 의미는 다음가 같다.



Tps
해당 디바이스에 대한 초당 전송 숫자인데, 여기서는 디바이스에 대한 I/O 요청을 말한다

Blk_read/s
해당 디바이스에서 초당 읽은 블럭 수

Blk_wrtn/s
해당 디바이스에서 초당 기록한 블럭 수

Blk_read
전체 읽은 총 블럭 수

Blk_wrtn
전체 기록한 총 블럭 수


표 2. iostat 의 모니터링 대상



이외에도 초당 읽은 섹터 수, 디바이스에 요청한 평균 크기(섹터 단위) 디바이스에 요청한 평균 큐의 크기, 해당 디바이스 I/O요청을 했을 때의 CPU 시간 등도 모니터링이 가능하다. 그런데 이 기능을 위해서는 커널 패치가 필요한데 아직까지 2.4 버전은 보이지 않는 것 같다. 리눅스에서는 아직까지 디스크 어카운팅 기능이 부족해서 각 블럭 디바이스에 대한 KB/s는 기본적으로 사용하지 못하고 있다고 프로그램 제작자는 지적하고 있다. 그래서 위에서 확장된 다른 기능을 보기 위해서는 커널 패치를 해야 한다는 것이다. ‘/proc/stat’와 ‘/proc/partitions’가 iostat 패키지와 연관된 파일이다. 솔라리스에도 iostat 프로그램이 있는데 여기에서는 ‘-xn’이라는 옵션을 이용하여 큐에서 기다린 시간, 디스크의 바쁜 정도, 평균 서비스 시간 등을 확인할 수 있다. 큐에서 서비스를 받기 위해 기다린 시간을 통해 디스크 병목 여부를 판단하고 디스크의 바쁜 정도의 변화에 따른 응답 시간 변화를 살펴 볼 수 있다.

Sysstat 패키지에 같이 들어있는 모니터링 프로그램 중 하나인 sar 프로그램은 시스템의 다양한 활동에 대하여 모니터링을 할 수 있는데 모니터링 대상이 상당히 넓은 편이다. 기본값은 CPU 활동에 대한 통계를 출력한다. sar는 각종 활동에 대한 통계를 다른 프로그램을 이용하여 파일로 저장하고 통계치를 출력할 수 있는 기능을 제공한다.



# sar –A 5

Linux 2.4.4 (tunelinux.pe.kr) 07/17/01



02:31:58 AM proc/s

02:32:03 AM 0.00



02:31:58 AM cswch/s

02:32:03 AM 8.80



02:31:58 AM CPU %user %nice %system %idle

02:32:03 AM all 0.00 0.00 0.20 99.80

02:32:03 AM 0 0.00 0.00 0.40 99.60

02:32:03 AM 1 0.00 0.00 0.00 100.00


리스트 5. sar 이용한 시스템 모니터링



sar에서 모니터링 가능한 항목은 다음과 같다.



- I/O 전송량

- 페이징

- 프로세스 생성 숫자

- 블락 디바이스 활동

- 인터럽트

- 네트워크 통계

- run 큐 및 시스템 부하 평균

- 메모리와 스왑 공간 활용 통계

- 메모리 통계

- CPU 이용도

- 특정 프로세스에 대한 CPU 이용도

- inode, 파일, 기타 커널 테이블에 대한 상태

- 시스템 스위칭 활동(context switch)

- 스와핑 통계

- 특정 프로세스 통계

- 특정 프로세스의 자식 프로세스 통계

- TTY 디바이스 활동



sar을 이용해 iostat와 비슷하게 I/O통계를 낼 수 있음은 물론 위의 내용과 같이 다양한 시스템 상태를 모니터링할 수 있다. 일반적인 리눅스 서적이나 자료에는 iostat나 sar에 대한 소개가 거의 없는 편이어서 아직까지는 사용하는 사람이 적은 듯 하다. 예를 들어 메모리 규모에 맞게 최대 열 수 있는 파일 갯수 (file-max)와 아이노드 개수를 조정하는데 sar를 이용하여 실제 얼마나 파일 핸들을 사용했는지 최대 file-max와 실제 사용한 파일 핸들의 비율 등도 통계를 낼 수가 있다. 이러한 통계를 주기적으로 내어 적절하게 활용하기 바란다. 참고로 최대 파일 핸들의 경우 4M당 256개로 잡아주고 아이노드 개수는 이의 3-4배 정도로 설정을 한다. file-max 는 /proc/sys/fs/file-max 를 이용하여 설정하며 /proc/sys/fs/file-nr 파일을 이용 현재 할당된 파일수를 확인할 수 있다.



# sar -v 5 5

Linux 2.4.4 (tunelinux.pe.kr) 07/17/01



03:30:21 dentunusd file-sz %file-sz inode-sz super-sz %super-sz dquot-sz %dquot-sz rtsig-sz %rtsig-sz

03:30:26 97582 92 0.28 92582 8 3.12 0 0.00 0 0.00

03:30:31 97582 93 0.28 92600 8 3.12 0 0.00 0 0.00

03:30:36 97582 93 0.28 92610 8 3.12 0 0.00 0 0.00

03:30:41 97582 93 0.28 92622 8 3.12 0 0.00 0 0.00

03:30:46 97582 93 0.28 92636 8 3.12 0 0.00 0 0.00

Average: 97582 93 0.28 92610 8 3.12 0 0.00 0 0.00


리스트 6. sar 이용하여 파일 및 아이노드 상황 모니터링



2.7 df 이용하여 하드 디스크 공간 확인하기

df는 현재 시스템에 마운트된 드라이브의 빈 디스크 공간을 보여준다. 간단한 프로그램이므로 길게 설명할 필요는 없지만 한가지 알아두어야 할 것이 블락 크기이다. 리눅스에서 기본 블락 크기는 1,024byte이다. df, du 등을 사용할 때 블락 크기를 잘못 지정하면 나오는 결과에 대하여 잘못 파악할 수 있는 가능성이 있다. (물론 아래처럼 블락 크기를 바꾸어서 내용을 보는 경우는 거의 없을 것이라 생각이 된다) 지나친 노파심일수 있겠지만 컴퓨터에서는 기본 단위에 대해 잘못 파악을 하는 경우 전혀 엉뚱한 일이 생길 수 있는 것은 한두가지가 아닐 것이다.



리스트 7. df 이용하여 하드 디스크 공간 확인하기

# df --block-size=512

Filesystem 512-blocks Used Available Use% Mounted on

/dev/sda2 4032088 1607824 2219440 42% /

/dev/sda1 124386 21972 95992 19% /boot

/dev/sda4 12444672 5684496 6128024 48% /home

/dev/sdc2 34265688 2748664 29776384 8% /var

tmpfs 4185192 0 4185192 0% /dev/shm



# df

Filesystem 1k-blocks Used Available Use% Mounted on

/dev/sda2 2016044 803912 1109720 42% /

/dev/sda1 62193 10986 47996 19% /boot

/dev/sda4 6222336 2842248 3064012 48% /home

/dev/sdc2 17132844 1374332 14888192 8% /var

tmpfs 2092596 0 2092596 0% /dev/shm
2005/07/04 12:38 2005/07/04 12:38
MRTG 이용한 네트워크 모니터링

http://tunelinux.pe.kr/tune/tunning-pse/pse-05.html
2005/07/04 12:36 2005/07/04 12:36