본문 바로가기
서버연구 블로그 서버연구 블로그

서버 성능 튜닝에서 가장 먼저 확인해야 하는 10가지 지표

읽는 시간 약 16분

서버가 느려졌을 때 가장 위험한 대응은 원인을 확인하기 전에 설정부터 바꾸는 것입니다.

Nginx Worker 수를 늘리고, JVM Heap을 키우고, sysctl 값을 조정하거나 서버 사양부터 올리는 경우가 있습니다. 하지만 서버 성능 저하는 CPU, 메모리, 디스크, 네트워크 가운데 하나의 자원이 부족해서 발생할 수도 있고, 여러 자원이 서로 영향을 주면서 나타날 수도 있습니다.

예를 들어 Load Average가 높다고 해서 반드시 CPU가 부족한 것은 아닙니다. 디스크 I/O를 기다리는 프로세스가 많아도 Load Average는 상승할 수 있습니다. 메모리가 부족해 Swap이 발생하면 디스크 I/O가 증가하고, 그 결과 CPU의 I/O Wait까지 높아질 수 있습니다.

따라서 성능 튜닝의 시작점은 설정 변경이 아니라 현재 서버에서 어떤 자원이 병목인지 확인하는 것입니다.

운영 환경에서 서버 성능 문제가 발생했을 때 가장 먼저 확인해야 하는 핵심 지표 10가지를 살펴보겠습니다.

서버 성능 문제는 왜 하나의 지표만 보면 안 될까?

서버 내부의 자원은 독립적으로 동작하지 않습니다.

CPU가 요청을 처리하려면 메모리에서 데이터를 읽어야 하고, 필요한 데이터가 메모리에 없다면 디스크에서 가져와야 합니다. 애플리케이션이 외부 서버와 통신한다면 네트워크 응답도 기다려야 합니다.

따라서 실제 요청 처리 과정은 대략 다음과 같이 연결됩니다.

클라이언트 요청
→ 네트워크 수신
→ CPU 처리
→ 메모리 접근
→ 디스크 또는 외부 서버 접근
→ CPU 처리
→ 네트워크 응답

이 과정 중 하나라도 느려지면 전체 응답 시간이 증가합니다.

문제는 최종 증상만으로 병목 위치를 정확하게 판단하기 어렵다는 것입니다.

웹 요청이 느리다고 해서 반드시 웹서버가 문제인 것도 아니며 CPU 사용률이 높다고 해서 CPU 자체가 부족한 것도 아닙니다.

성능 튜닝에서는 여러 지표를 함께 확인해 병목이 발생한 위치를 좁혀가는 과정이 필요합니다.

Load Average

Linux 서버에서 가장 먼저 확인할 수 있는 대표적인 지표가 Load Average입니다.

uptime 또는 cat /proc/loadavg를 실행하면 다음과 비슷한 값이 표시됩니다.
load average: 2.15, 1.87, 1.42

각 값은 일반적으로 최근 1분, 5분, 15분 동안의 시스템 부하를 나타냅니다.

중요한 것은 Load Average가 단순한 CPU 사용률이 아니라는 점입니다.

Linux에서는 CPU를 사용하려고 기다리는 작업뿐 아니라 특정 I/O 작업을 기다리는 프로세스도 Load에 영향을 줄 수 있습니다.

따라서 Load Average가 높다면 다음 단계로 CPU와 디스크 상태를 함께 확인해야 합니다.

또한 숫자 자체만 보고 높다거나 낮다고 판단하기보다는 CPU Core 수와 평소 서버의 기준값을 함께 비교해야 합니다.

CPU 사용률

CPU 상태는 서버 성능 문제를 분석할 때 가장 기본적으로 확인하는 항목입니다.

mpstat -P ALL 1 또는 top을 사용할 수 있습니다.

CPU에서는 단순히 전체 사용률만 보는 것보다 세부 항목을 확인하는 것이 중요합니다.

대표적으로 다음과 같은 값이 있습니다.

%usr
%sys
%iowait
%steal
%idle

%usr가 높다면 애플리케이션이나 사용자 영역 프로세스가 CPU를 많이 사용하고 있을 가능성이 있습니다.

%sys가 높다면 시스템 콜이나 커널 처리 비중이 증가했는지 살펴볼 필요가 있습니다.

%iowait가 지속적으로 높다면 CPU가 일을 하지 못해서 느린 것이 아니라 디스크 등의 I/O 완료를 기다리고 있을 가능성을 의심해야 합니다.

가상머신 환경에서는 %steal도 중요합니다. 이 값이 높다면 해당 VM이 사용할 CPU 시간을 Hypervisor 환경에서 충분히 할당받지 못하는 상황일 수 있습니다.

Run Queue와 Context Switch

CPU 사용률만으로는 CPU 병목을 완전히 판단하기 어렵습니다.

실제로 CPU를 사용하려고 기다리는 작업이 얼마나 있는지도 확인해야 합니다.

vmstat 1 에서 다음 항목을 살펴볼 수 있습니다.
r
cs

r은 CPU 실행을 기다리는 작업 수를 판단하는 데 참고할 수 있고, cs는 초당 Context Switch 수를 보여줍니다.

CPU 사용률이 높으면서 실행 대기 작업까지 계속 쌓인다면 CPU 자원이 실제 병목일 가능성이 높아집니다.

Context Switch가 지나치게 증가하는 경우에는 프로세스나 스레드가 과도하게 생성되어 있거나 짧은 작업이 지나치게 많이 전환되고 있는 상황도 의심할 수 있습니다.

따라서 단순히 CPU 사용률만 보고 Core를 추가하기보다 어떤 프로세스와 스레드가 CPU를 사용하고 있는지 추가 분석이 필요합니다.

Available Memory

Linux에서 메모리를 확인할 때 흔히 사용하는 명령어는 다음과 같습니다.

free -h

여기서 많은 운영자가 처음 보는 값이 free 메모리입니다.

하지만 Linux는 사용하지 않는 메모리를 파일 캐시 등에 적극적으로 활용하기 때문에 free 값이 작다고 해서 바로 메모리 부족으로 판단하면 안 됩니다.

보다 중요하게 봐야 하는 값은 다음과 같습니다.

available

Available Memory는 새로운 애플리케이션이 메모리를 필요로 할 때 시스템이 실제로 활용할 수 있는 메모리를 판단하는 데 유용합니다.

따라서 메모리 문제를 분석할 때는 단순 Used Memory 비율보다 Available Memory의 추세를 확인하는 것이 중요합니다.

Swap 사용과 Swap I/O

Swap을 사용하고 있다는 사실 자체만으로 서버에 문제가 있다고 단정할 수는 없습니다.

더 중요한 것은 현재도 지속적으로 Swap In과 Swap Out이 발생하고 있는지입니다.

vmstat 1 에서 다음 값을 확인할 수 있습니다.
si
so

si는 Swap In, so는 Swap Out을 의미합니다.

메모리가 부족해 활성 데이터가 계속 Swap 영역으로 이동하고 다시 메모리로 불러와지는 상황이 반복되면 응답 속도가 크게 떨어질 수 있습니다.

이때 나타나는 전형적인 흐름은 다음과 같습니다.

메모리 부족
→ Swap 발생
→ 디스크 I/O 증가
→ 프로세스 I/O 대기 증가
→ Load Average 상승
→ 애플리케이션 응답 지연

이 때문에 Load가 높다고 CPU만 확인하면 실제 원인을 놓칠 수 있습니다.

디스크 I/O Latency

디스크 문제를 확인할 때 단순히 디스크 사용률만 보는 것으로는 충분하지 않습니다.

실제 운영 환경에서는 요청을 처리하는 데 얼마나 시간이 걸리는지, 즉 I/O Latency가 중요합니다.

대표적으로 다음 명령어를 사용할 수 있습니다.

iostat -xz 1

확인할 값은 환경과 도구 버전에 따라 조금씩 다르지만 일반적으로 다음과 같은 지표를 봅니다.

await
r_await
w_await
%util

await는 I/O 요청이 처리되는 데 걸린 시간을 파악하는 데 도움이 됩니다.

Read와 Write 지연을 따로 제공하는 환경에서는 r_await, w_await를 함께 보면 어느 방향의 I/O가 문제인지 구분하는 데 도움이 됩니다.

%util 역시 참고할 수 있지만 저장장치 종류와 병렬 처리 구조에 따라 해석이 달라질 수 있으므로 하나의 값만 가지고 병목을 단정해서는 안 됩니다.

네트워크 Drop과 Error

서버의 CPU와 메모리가 정상인데도 응답이 느리거나 간헐적으로 연결 문제가 발생한다면 네트워크 상태를 확인해야 합니다.

ip -s link를 사용하면 인터페이스별 패킷 상태를 확인할 수 있습니다.

특히 다음 항목을 살펴봅니다.

errors
dropped
overrun

패킷 Drop이 계속 증가한다면 네트워크 인터페이스, 커널 버퍼, 트래픽 폭증 또는 네트워크 장비 구간 등을 추가로 확인해야 합니다.

TCP 통신에서는 패킷 손실로 인해 재전송이 발생할 수 있으며, 애플리케이션에서는 단순히 응답 시간이 느려진 것처럼 보일 수 있습니다.

따라서 웹 응답 지연을 애플리케이션 문제로만 판단하면 안 됩니다.

TCP Retransmission

TCP 통신에서는 패킷이 손실되면 재전송이 발생합니다.

Linux에서는 다음과 같은 명령을 활용할 수 있습니다.

netstat -s 또는 시스템 환경에 따라 ss, nstat, sar -n TCP 등의 도구를 함께 사용할 수 있습니다.

재전송이 지속적으로 증가하면 클라이언트와 서버 사이 네트워크 품질뿐 아니라 서버 내부의 패킷 처리 상황도 함께 살펴야 합니다.

TCP Retransmission이 증가하면 요청 자체는 실패하지 않더라도 응답 시간이 길어질 수 있습니다.

특히 외부 API, DB 서버, Load Balancer 등 여러 구간을 거치는 시스템에서는 어느 구간에서 지연이 발생하는지 구분하는 작업이 중요합니다.

TCP Connection 상태

웹서버나 API 서버에서는 현재 TCP Connection 상태도 중요한 성능 지표입니다.

ss -s 보다 자세히 확인하려면 다음과 같은 방식도 사용할 수 있습니다.
ss -ant 운영 중에는 특히 다음 상태를 확인하는 경우가 많습니다.
ESTABLISHED
TIME-WAIT
CLOSE-WAIT
SYN-RECV

ESTABLISHED가 갑자기 크게 증가했다면 실제 트래픽 증가인지, 요청 처리가 늦어져 연결이 오래 유지되고 있는지 구분해야 합니다.

CLOSE-WAIT가 지속적으로 누적된다면 애플리케이션이 종료된 연결을 적절히 정리하지 못하고 있는 상황을 의심할 수 있습니다.

SYN-RECV가 비정상적으로 증가한다면 새로운 연결 수립 과정에 문제가 있는지도 확인해야 합니다.

TCP 상태를 분석하면 단순 CPU나 메모리 지표로 확인하기 어려운 연결 계층 문제를 발견할 수 있습니다.

프로세스별 CPU·메모리·I/O

시스템 전체에서 문제가 발견됐다면 다음 단계는 실제 원인을 발생시키는 프로세스를 찾는 것입니다.

CPU와 메모리는 다음과 같이 확인할 수 있습니다.

top 또는 ps aux --sort=-%cpu | head

메모리 사용량 기준으로 확인하려면 다음과 같이 볼 수 있습니다.

ps aux --sort=-%mem | head

프로세스별 I/O 상태는 환경에 따라 pidstat 같은 도구를 활용할 수 있습니다.

pidstat -d 1

이 단계가 중요한 이유는 시스템 전체 지표만으로는 원인을 해결할 수 없기 때문입니다.

예를 들어 CPU 사용률이 95%라고 해도 하나의 프로세스가 CPU를 독점하는 것과 수십 개의 정상적인 요청 처리 프로세스가 CPU를 사용하는 것은 해결 방법이 완전히 다릅니다.

성능 튜닝에서는 반드시 시스템 지표 → 프로세스 지표 → 애플리케이션 내부 순서로 범위를 좁혀야 합니다.

파일시스템 사용률과 Inode

디스크 성능만큼 놓치기 쉬운 것이 파일시스템 용량입니다.

df -h 로 파일시스템 사용률을 확인할 수 있습니다.

Linux에서는 Inode 상태도 함께 확인하는 것이 좋습니다.

df -i

디스크 공간이 남아 있어도 작은 파일이 지나치게 많이 생성되면 Inode가 부족해 새로운 파일을 만들지 못하는 상황이 발생할 수 있습니다.

로그 파일, 캐시 파일, 세션 파일 등이 대량으로 생성되는 서버에서는 특히 주의해야 합니다.

웹 애플리케이션에서는 파일 생성 실패가 직접적으로 드러나지 않고 애플리케이션 오류나 요청 실패 형태로 나타날 수 있기 때문에 운영자가 파일시스템 상태까지 확인해야 합니다.

실제 장애 상황에서는 어떤 순서로 분석해야 할까?

운영 중 서버가 갑자기 느려졌다면 처음부터 모든 명령을 무작정 실행하는 것보다 범위를 좁혀가는 것이 효율적입니다.

먼저 전체 서버 상태를 확인합니다.

uptime
free -h
vmstat 1

Load, CPU 대기 작업, 메모리, Swap 상태를 빠르게 확인합니다.

CPU 문제가 의심된다면 다음 단계로 이동합니다.

mpstat -P ALL 1
pidstat 1

디스크 I/O가 의심된다면 다음을 확인합니다.

iostat -xz 1
pidstat -d 1

네트워크나 연결 문제가 의심된다면 다음을 확인할 수 있습니다.

ss -s
ip -s link

그리고 마지막으로 문제가 발생한 프로세스를 찾아 애플리케이션 로그, Slow Query, GC, Thread 상태 등 애플리케이션 내부 분석으로 들어가는 방식이 좋습니다.

중요한 것은 명령어를 많이 실행하는 것이 아니라 각 지표가 서로 어떤 관계를 가지고 있는지 해석하는 것입니다.

성능 튜닝에서 흔히 하는 실수

가장 흔한 실수는 특정 수치 하나만 보고 바로 설정을 변경하는 것입니다.

Load Average가 높다고 CPU를 증설하거나, 메모리 사용률이 높다고 무조건 메모리를 추가하고, TIME_WAIT가 많다고 TCP 커널 설정부터 수정하는 식입니다.

하지만 서버 성능 지표는 대부분 원인이 아니라 결과일 수 있습니다.

예를 들어 다음과 같은 상황이 가능합니다.

DB 응답 지연
→ 웹 요청 처리 시간 증가
→ TCP Connection 유지 시간 증가
→ Worker 점유 증가
→ Load Average 상승

이 경우 웹서버 설정만 수정해도 근본적인 문제는 해결되지 않습니다.

성능 분석에서는 항상 어떤 지표가 먼저 변했는지, ​그 변화가 다른 지표에 어떤 영향을 주었는지를 함께 봐야 합니다.

정리

서버 성능 튜닝은 설정값을 바꾸는 작업부터 시작하지 않습니다.

먼저 현재 서버에서 어떤 자원이 병목인지 찾아야 합니다.

운영자가 가장 먼저 확인해야 할 핵심 지표를 정리하면 다음과 같습니다.

  • Load Average
  • CPU 사용률과 I/O Wait
  • Run Queue와 Context Switch
  • Available Memory
  • Swap In·Out
  • 디스크 I/O Latency
  • 네트워크 Drop과 Error
  • TCP Retransmission
  • TCP Connection 상태
  • 프로세스별 CPU·메모리·I/O와 파일시스템 상태

이 지표들은 각각 독립적인 숫자가 아니라 서로 연결되어 있습니다.

메모리 부족이 Swap을 만들고, Swap이 디스크 I/O를 증가시키며, I/O 대기가 Load Average를 높일 수 있습니다. 네트워크 패킷 손실이 TCP 재전송을 만들고, 재전송으로 요청 시간이 길어지면서 Connection 수가 증가할 수도 있습니다.

따라서 좋은 성능 튜닝은 특정 명령어 하나를 알고 있는 것이 아니라 CPU → 메모리 → 디스크 → 네트워크 → 프로세스 → 애플리케이션으로 병목 지점을 단계적으로 좁혀가는 능력에서 시작합니다.

서버의 숫자를 보는 것보다 중요한 것은 그 숫자가 왜 변했는지를 이해하는 것입니다.

instone
함께 보면 좋은 글

댓글 0

첫 댓글을 남겨보세요.

error: Content is protected !!

광고 차단 알림

광고 클릭 제한을 초과하여 광고가 차단되었습니다.

단시간에 반복적인 광고 클릭은 시스템에 의해 감지되며, IP가 수집되어 사이트 관리자가 확인 가능합니다.