6.1 상태 모니터링의 기초 지식
상태 모니터링을 할 때에는 각 그래프에서 이상을 알아차리기 위한 공통적인 포인트를 먼저 확인하는 것이 중요하다. ① 없어야 하는 변화가 있는지 먼저 확인하여 평소에는 변화가 없는 타이밍에 평소와는 다른 움직임을 보이는지를 먼저 확인한다. ② 있어야 하는 변화가 없는지 확인하여 부하가 증가해야 하는 타이밍에 증가하지 않는다면 처리해야 하는 일괄처리가 이상 종료되었는지를 확인하고, 파형이 울퉁불퉁해야 하는데 일정한 값을 유지하고 있는 경우에는 데이터를 취득하지 못했는지, 성능이 한계에 다달았는지를 확인한다. 또, ③ 양과 단위가 다른지 확인한다. 그래프의 형태는 같아 보여도 특정 서버만 세로축의 단위가 다른 경우가 있을 수도 있으며, 이 경우 단위가 다른 경우 크게는 1,000배의 차이가 나기도 하므로 주의 깊게 확인한다. ④ 해상도를 고려하여 경향을 살펴보는 것도 중요한데, 여기서 해상도란 데이터를 취득하는 간격을 말한다. 여기서 데이터를 취득하는 방법은 또 2가지로 나뉘게 된다.
① | 데이터 취득 작업을 한 경우의 값을 사용 | 데이터 취득 간격 사이의 변동을 전혀 고려하지 않는다. |
② | 데이터 취득 작업에 의해 취득한 값과 직전에 취득한 값의 차이를 사용 | 데이터 취득 간격 사이의 변동을 고려하지만 그다지 깨끗하게 나타나지 않는다. |
여기서 ②의 경우는 데이터 취득 간격을 분할하여 초당 평균으로 계산한 경우가 많기 때문에 데이터 취득 간격이 달라지면 값도 달라질 수 있으므로 유의해야 한다. 모니터링 툴의 데이터 취득 방법은 Polling형과 Push형 두 가지로 나뉘는데, Polling(Pull) 형의 경우 모니터링 툴 쪽에서 정보를 수집하기 위해 액세스를 하며 취득 타이밍이 모니터링 툴 쪽에 의존되어 모니터링 툴의 처리 성능에 따라 취득 타이밍이 결정된다. Push형은 모니터링 툴 쪽으로 데이터를 송신하며 취득 타이밍이 모니터링 툴 쪽의 처리 성능에 의존하지 않고 일정하게 데이터를 취득할 수 있다.
6.2 상태 모니터링 데이터를 읽는 방법 - OS
Linux OS의 상태를 모니터링할 때에는 CPU 관련(CPU Usage, Context Switches, Forks, Interrupts, Load Average), 메모리 관련(Memory, Swap Usage), 디스크 관련(Disk Elapsed IO Time, DISK IOPS, DISK Operations, DISK Read, Write Time, DISK Read, Write Time per IO Request, DISK Sectors Read/Written, DISK Space), 네트워크 관련(Network Connection States, Network Errors, Network Traffic) 3가지로 크게 나눠볼 수 있다. 해당 항목들은 아래에서 하나씩 설명한다.
[CPU Usage의 항목과 의미]
항목 | 의미 |
CPU User | 사용자 영역(커널 영역이 아님)에서의 CPU 이용률 |
CPU Nice | Nice 처리된 부분의 CPU 이용률 |
CPU System | 커널 영역의 CPU 이용률 |
CPU Idle | Idle 상태의 CPU 이용률 |
CPU iowait | I/O 대기의 CPU 이용률 |
CPU irq | irq(인터럽트) 처리의 CPU 이용률 |
CPU Softirq | Softirq(소프트웨어 인터럽트) 처리의 CPU 이용률 |
CPU Steal | 가상머신이 가로챈 만큼의 CPU 이용률 |
CPU Guest | 가상머신이 이용한 만큼의 CPU 이용률 |
웹 서비스의 경우, PHP 등 프로그램 처리에 이용한 부분은 CPU User항목으로 확인이 가능하고, 메모리 액세스 등 커널 영역에서의 CPU 사용률은 CPU System으로 따로 표기된다. CPU Nice는 운용 계통의 일괄처리 등 nice 명령어를 이용한 우선순위 조정 처리에서 이용한 부분이다. CPU iowait이 높아지면 주의해야 한다. 대부분의 서버에서 CPU iowait은 보틀넥을 일으키는 요인이 되기 쉬우므로 통상적으로 30% 이하로 제한하는 것이 좋다.
'Context Switches'는 CPU에서 처리할 프로세스 등의 전환 횟수를 나타내어, 프로세스의 병렬도가 높거나 단위 시간당 처리가 많은 시스템에서는 해당 값이 커진다. 'Forks'는 프로세스 생성 처리를 하는 Fork 실행 횟수를 나타내며, 기본적으로 프로세스의 생성은 CPU비용이 요구되는 처리임으로 해당 값이 큰 경우 불필요한 프로세스를 생성하거나 외부 프로세스를 호출하고 있는지 않은지를 확인한다. 'Interrupts'의 경우 네트워크 송수신 등에 따른 인터럽트의 수로, 네트워크 송수신이 많으면 증가하게 된다. 이 값이 한계에 다다른 경우 'CPU Usage'. 'irq', 'Softirq' 등을 추가로 확인한다. 'Load Average' 값은 성능 측면의 지표로서는 절댓값이 별 의미가 없지만, 해당 값의 변화는 시스템 상황의 변화를 알려주는 역할을 한다. 시스템 성능의 한계를 초과하면 해당 값이 단번에 뛰어오르기 때문에 Load Average값이 급격하게 변화하는 경우에는 다른 지표를 확인하여 보틀넥이 발생하는지를 확인할 필요가 있다. 시스템 처리가 느리기 때문에 Load Average가 높아지는 것이므로 이 지표를 확인할 때에는 인과관계가 바뀌지 않도록 조심하여야 한다.
[Memory의 항목과 의미]
항목 | 의미 |
Memused | OS나 프로그램에서 사용 중인 메모리 용량 |
Memcached | 캐시로 사용 중인 메모리 용량 |
Membuffer | 버퍼로 사용 중인 메모리 용량 |
Memshared | 공유 메모리로 사용 중인 메모리 용량 |
Memfree | 전혀 사용하고 있지 않은 메모리 용량 |
'Memcached'는 메모리를 디스크의 캐시로서 이용하고 있다는 의미로, 운용 시 해당 부분이 점차 증가하여 Memfree가 0이 되는 경우를 자주 볼 수 있지만 이것은 Linux 커널의 정상적인 동작이다. 메모리에서 데이터를 읽는 속도는 디스크에서 읽는 속도보다 압도적으로 빠르기 때문에, Linux에서는 메모리를 남김없이 사용하여 처리를 최대한 고속화하는 구조로 되어있다. 이때, 메모리가 필요해지면 Memcached가 해제되며 Memused값이 증가하도록 처리가 된다. Swap의 경우는 하드디스크와 같은 보조 기억장치의 영역에 일시적으로 메모리의 데이터를 쓰거나 읽는 것을 말한다. 이때 Swap을 사용하고 있다는 것이 무조건 메모리의 용량이 부족한 것이라는 의미로 해석될 수는 없다. Swap은 Swap의 전체 이용량이 아닌 Swap이 쓰고 있거나 읽고 있는 양에 주목하여야 한다. Swap의 동작은 완전히 OS의 결정에 따라 결정되는 것이므로 Swap을 사용하고 싶지 않은 경우에는 Swap 용량을 0으로 설정하면 되지만, 이 경우 메모리의 단편화가 일어나기 쉬우므로 메모리 확보와 해제가 빈번한 서버에서는 0으로 설정하지 않는 것을 추천한다. 추가로, 메모리가 부족한 경우에는 OS가 'OOM Killer'라는 구조에 따라 실행 중인 프로그램을 강제로 정지시켜 메모리의 여유공간을 확보하기 때문에 해당 프로세스가 동작하지 않도록 주의 깊게 튜닝하여야 한다.
[Disk Elapsed IO Time(ms)의 항목과 의미]
항목 | 의미 |
IO Time | I/O의 시간 |
IO Time Weighted | I/O의 총 소요 시간 |
디스크 관련 그래프에는 물리적인 디바이스 단위와 파티션 단위가 있으니 모니터링 시 주의하여야 한다. 대부분은 물리적인 디바이스 단위로 표기되지만 'Disk Space'는 파티션 단위로 표기된다. 물리적인 디바이스라고는 해도 디스크 자체에 한정하지 않은 OS 관점에서의 디바이스 단위이기 때문에 이것 또한 주의하여야 한다. 소프트웨어 RAID를 사용한 경우에는 디스크 단위, 하드웨어 RAID를 사용한 경우에는 논리적인 디스크 단위를 사용하기 때문에 개별 디스크에 대해서는 측정 대상에서 제외한다. 위 항목에서는 IO Time Weighted에 주목하여, IO Time에 비해 IO Time Weighted가 큰 경우에는 디스크 I/O의 성능이 부족할 가능성이 있으니 이 경우 I/O자체를 줄이거나 디스크 I/O 성능을 높여 해당 값이 낮아질 수 있도록 튜닝한다.
[Disk IOPS의 항목과 의미]
항목 | 의미 |
Io Ops | I/O 동작 횟수 |
[Disk Operations의 항목과 의미]
항목 | 의미 |
Reads | 디스크 읽기의 요구 횟수 |
Reads Merged | 통합된 디스크 읽기의 요구 횟수 |
Writes | 디스크 쓰기의 요구 횟수 |
Writes Merged | 통합된 디스크 쓰기의 요구 횟수 |
[Disk Read/Write Time의 항목과 의미]
항목 | 의미 |
Time Spent Reading | 읽기에 소요된 시간 |
Time Spent Writing | 쓰기에 소요된 시간 |
디스크의 성능은 MB/s와 Io Ops로 표현된다. Io Ops를 기록하고 파악해 두면 성능 지표를 적절하게 파악할 수 있으며, Io Ops는 'Read+Writes'의 값으로 구성된다(즉, Reads+Writes=Io Ops). I/O 요구는 통상적으로 4KB 단위이지만, 효율성을 높이기 위해 I/O요구를 합쳐 처리하기도 한다. 이렇게 통합되어 효율적으로 처리되는 I/O를 Merged 지표로 확인할 수 있다.
[Disk Read/Write Time per IO Request의 항목과 의미]
항목 | 의미 |
Read Time per IO | 1 I/O당 읽기의 소요 시간 |
Write Time per IO | 1 I/O당 쓰기의 소요 시간 |
[Disk Sectors Read/Written의 항목과 의미]
항목 | 의미 |
Sectors Read | 읽은 섹터의 수 |
Sectors Written | 기록한 섹터의 수 |
1 I/O당 읽기, 쓰기 소요 시간은 앞서 언급된 'Disk Operations'의 Reads와 Writes, 'Disk Read/Write Time'의 Time Spent Reading, Writing으로부터 추출되며 'DISK IOPS'와 'Disk Operations' 그래프와 함께 확인하여 디스크 I/O 성능이 부족한지를 확인할 수 있다. 추가로 Sectors Read/Write 지표도 동일하게 'DISK IOPS'와 'Disk Operations'와 관계있는 그래프로써, 다른 그래프와의 비교를 통해 성능을 확인한다.
[Disk Space의 항목과 의미]
항목 | 의미 |
Used | 이용 중인 디스크 용량 |
Available | 이용 가능한 디스크 용량 |
디스크의 여유용량은 Avasilable항목에서 Used 항목을 뺀 값이다. 이 값이 0이 되면 서비스에 다양한 오류가 발생하므로 운용하는도중 절대 0이 되지 않도록 주의해야 한다(여유공간이 0이 되면 로그 출력을 못하거나 임시파일을 작성할 수 없게 되는 등의 문제가 발생). 안정적인 운용에 들어선 서비스의 디스크 사용량 증가는 어느 정도 예측이 가능한 부분이니 디스크 사용량의 자연적 증가에 의한 용량 부족이 발생하지 않도록 주의하자. 장기간에 걸쳐 자연적인 증가를 기록해 두면 때때로 발생하는 이벤트와 디스크 사용량의 상관관계를 확인할 수 있으므로, 차후에 문제가 생기는 것을 방지하는데 도움이 될 수 있다. 디스크의 여유 용량이 0이 되지 않도록 관리하기 위해서는 로그의 백업과 로테이션(세대 관리)이 중요하다.
[Network Connection States의 항목과 의미]
항목 | 의미 |
Established | ESTABLISHED 상태의 소켓 수 |
Syn Sent | SYN_SENT 상태의 소켓 수 |
Syn Recv | SYN_RECV 상태의 소켓 수 |
Fin Wait1 | FIN_WAIT1 상태의 소켓 수 |
Fin Wait2 | FIN_WAIT2 상태의 소켓 수 |
Time Wait | TIME_WAIT 상태의 소켓 수 |
Closed | CLOSED 상태의 소켓 수 |
Close Wait | CLOSE_WAIT 상태의 소켓 수 |
Last Ack | LAST_ACK 상태의 소켓 수 |
Listen | LISTEN 상태의 소켓 수 |
Closing | CLOSING 상태의 소켓 수 |
Unknown | UNKNOWN 상태의 소켓 수 |
네트워크 상태에 있어 'Time Wait', 'Syn Recv', 'Fin Wait1', 'Fin Wait2'는 프로세스가 연결되어 있지 않은 상태이므로 괜찮지만, 'Established', 'Close Wait' 등은 프로세스가 연결된 상태이기 때문에 이 수치가 크다는 것은 서버 측의 병렬 처리의 수가 크다는 것이다. 특히 'Close Wait' 상태로 서비스가 끊이지 않고 지속적인 연결을 하는 상태의 경우 서비스 여러 방면으로 해결책을 확인할 필요가 있다.
[Network Errors의 항목과 의미]
항목 | 의미 |
Rxerrs | 수신 Error 패킷의 수 |
Rxdrop | 수신 Drop 패킷의 수 |
Rxfifo | 수신 FIFO 버퍼의 Error 수 |
Rxframe | 프레임 크기를 초과한 패킷의 수 |
Txerrs | 송신 Error 패킷의 수 |
Txdrop | 송신 Drop 패킷의 수 |
Txfifo | 송신 FIFO 버퍼의 Error 수 |
Txcolls | 송신 시 충돌을 감지한 횟수 |
Txcarrier | 송신 캐리어의 수 |
위 항목들은 기본적으로 모든 항목이 0이 되는 것이 좋지만, 일반적으로 공개되어 있는 웹 서버의 경우 통신 상대의 품질에 따라 에러가 발생할 수도 있으니 그 점을 고려하여 상태를 모니터링한다. 수치가 계속 증가하는 경우에는 네트워크 설정의 오류나 기기의 고장이 발생한 경우일 수도 있다. 또한 ICMP를 차단하고 있는 네트워크 기기의 성능 부족이나 고장, 또는 네트워크 케이블의 품질 불안정(파손, 빠짐) 등의 경우도 생각해 볼 수 있다.
[Network Traffic의 항목과 의미]
항목 | 의미 |
Inbound | Inbound Traffic(수신) |
Outbound | Outbound Traffic(송신) |
네트워크 대역의 사용량은 Inbound, Outbound 항목으로 확인된다. 이 수치가 상한에 다다른 경우에는 네트워크 대역이 부족한 것이므로 대역을 많이 쓰는 항목을 검증하거나 대역 자체를 넓힐 필요가 있다.
6.3 상태 모니터링 데이터를 읽는 방법 - MySQL (제외)
6.4 실시간 모니터링의 방법 / 6.5 트러블 대응에 사용하는 모니터링 툴
서비스를 운용하다 보면 타 서비스를 통해 상태 모니터링을 하는 것과는 달리, 서버에 직접 접속하여 실시간으로 해당 서버의 상태를 확인해야 할 때도 있다. 이때 서버에서 가장 많이 사용되는 명령어는 'dstat', 'top', 'iostat'이며, 각각 yum을 통해 설치가 가능하다. dstat의 경우 CPU 사용률과 디스크 및 네트워크의 I/O 상황을 모아서 확인할 수 있고, crontab을 이용하여 데이터를 추출하면 일일 데이터를 취득하여 모니터링에 참고할 수 도 있다. top명령어는 CPU 코어별 데이터를 매 초마다 확인할 수 있다. iostat은 I/O관련 데이터를 확인할 수 있고 해당 모니터링 결과에서 %util 항목이 큰 경우에는 디스크 I/O가 요구되는 것보다 성능이 부족한 상태이므로 7장을 참고하여 대책을 마련하는 것이 좋다.
[iostat의 옵션]
-t | 일시를 표시 |
-x | 확장 상태를 표시 |
-n | NFS의 상태를 표시 |
q | 1초마다 표시 |
시스템을 운용하다 보면 시스템에 대한 변경 사항이 발생하게 된다. 운용 중인 시스템을 변경할 때에는 원래 동작하고 있던 기능이 동작하지 않게 되는(Degrade) 등의 성능 저하에 의한 장애를 주의해야 한다. 이러한 경우를 방지하기 위해서는 평소에 위험 예측과 회피 방법에 대한 훈련을 함으로써 작업의 정밀도를 좀 더 높이는 방법이 있으며, 작업 전에 각 단계에서 예정된 작업이 원래대로 복원될 수 있는지를 미리 확인하거나 작업 전후로 서비스의 정상 상태를 확인하여 사고를 방지하는 방법이 있다.
시스템에 오류가 발생하는 경우, 명확하게 오류 메시지가 출력되고 있는 경우에는 그 오류 메시지를 바탕으로 대응하면 된다. 오류 메시지를 정확하게 파악하는 것도 기술이며, 여기서는 발생되는 메시지를 확실히 읽어 이해하고 대응하는 것이 가장 중요하다. 네트워크의 문제를 파악하기 위해서는 데이터가 정확하게 도달하고 있는지를 'tcpdump'를 통해 확인할 수 있다. 이 경우 TCP/IP 접속의 경우에는 캡처가 가능하지만 소켓 접속인 경우에는 캡처가 불가능하니 통신방법을 정확히 확인하고 진행하도록 한다.
TCPDUMP의 사용방법(네트워크 인터페이스 eth0에서 발생한 HTTP 액세스 캡처) $ tcpdump -i eth0 -n port 80 |
프로세스의 동작을 확인하기 위해 많이 사용되는 툴은 'strace'와 'lsof'이다. strace를 통해서는 동작 중에 있는 프로세스의 시스템 콜을 확인할 수 있어, strace를 통해 Apache 자식 프로세스에 attach 해보면 접속을 열고, 데이터를 수신하고 도큐먼트 루트에서 인덱스 파일을 찾아 읽고 송신하는 일련의 과정을 확인할 수 있다. 이러한 출력을 통해 해당 프로세스가 예상외의 동작을 하고 있는 것은 아닌지 확인할 수 있으며, 추가로 lsof 명령어를 통해서는 프로세스를 열고 있는 파일을 확인할 수 있다. Linux는 디바이스도 파일처럼 취급하기 때문에 프로세스가 열려있는 디바이스나 라이브러리 등도 확인이 가능하다.
'Book Study > 웹 엔지니어가 알아야 할 인프라의 기본' 카테고리의 다른 글
Chapter 8. 웹 서비스 튜닝 2 : 튜닝 레시피 (0) | 2021.05.04 |
---|---|
Chapter 7. 웹 서비스 튜닝 1 : 보틀넥을 찾는 방법 (0) | 2021.04.17 |
Chapter 5. 웹 서비스 운용 1 : 시스템 감시의 기본 (0) | 2021.04.04 |
Chapter 4. 인프라 준비의 기초 지식 (0) | 2021.03.30 |
Chapter 3. 웹 서비스 서버 구성의 모범 사례 (0) | 2021.03.25 |