서버 메모리 부족 문제 해결 가이드: 원인 파악부터 최적화까지

서버를 운영하다 보면 갑자기 웹사이트가 느려지거나 응답이 없어지는 경험을 하게 됩니다. 이러한 문제의 주요 원인 중 하나가 바로 메모리 부족입니다. 오늘은 서버 메모리 부족 문제를 진단하고 해결하는 방법을 체계적으로 알아보겠습니다.

메모리 부족 현상이란?

서버 메모리 부족은 시스템의 RAM이 실행 중인 프로세스들의 요구를 충족시키지 못할 때 발생합니다. 이 경우 서버는 스왑 메모리를 사용하게 되고, 심각한 경우 프로세스를 강제 종료시키거나 시스템이 멈출 수 있습니다. 웹사이트 속도 저하, 데이터베이스 응답 지연, 502/503 에러 등이 대표적인 증상입니다.

메모리 부족의 주요 원인

1. 메모리 누수 (Memory Leak)

애플리케이션이 사용한 메모리를 제대로 해제하지 않아 시간이 지날수록 메모리 사용량이 증가하는 현상입니다. 특히 PHP, Python, Node.js 등의 웹 애플리케이션에서 자주 발생합니다.

2. 과도한 동시 접속

웹사이트에 예상보다 많은 트래픽이 몰리면 각 연결마다 메모리를 소비하여 전체 메모리가 부족해질 수 있습니다. 특히 Apache의 경우 프리포크 방식에서 많은 메모리를 사용합니다.

3. 비효율적인 데이터베이스 쿼리

최적화되지 않은 SQL 쿼리는 대량의 데이터를 메모리에 로드하여 메모리 부족을 유발합니다. JOIN이 많거나 인덱스가 없는 테이블 조회가 주요 원인입니다.

4. 캐시 설정 오류

Redis나 Memcached 같은 캐시 시스템의 메모리 제한이 적절하지 않거나, 캐시 만료 정책이 없어 메모리가 계속 증가할 수 있습니다.

메모리 사용 현황 진단 방법

기본 메모리 확인 명령어

서버의 현재 메모리 상태를 확인하는 가장 기본적인 방법입니다.

# 메모리 사용량 확인 (MB 단위)
free -m

# 실시간 메모리 사용량 모니터링
watch -n 1 free -m

# 상세한 메모리 정보
cat /proc/meminfo

출력 결과에서 available 항목이 전체 메모리의 10% 이하라면 메모리 부족 상태로 판단할 수 있습니다.

프로세스별 메모리 사용량 확인

어떤 프로세스가 메모리를 많이 사용하는지 파악하는 것이 문제 해결의 핵심입니다.

# 메모리 사용량 순으로 프로세스 정렬
ps aux --sort=-%mem | head -n 10

# 실시간 프로세스 모니터링
top
# top 실행 후 Shift+M을 누르면 메모리 사용량 순으로 정렬

# 더 나은 시각화를 위한 htop
htop

스왑 사용량 확인

스왑 메모리 사용이 많다면 물리 메모리가 부족하다는 명확한 신호입니다.

# 스왑 사용 현황
swapon --show

# 스왑을 사용 중인 프로세스 확인
for file in /proc/*/status ; do awk '/VmSwap|Name/{printf $2 " " $3}END{ print ""}' $file; done | sort -k 2 -n -r | head

단계별 메모리 부족 해결 방법

1단계: 불필요한 서비스 종료

실행 중이지만 사용하지 않는 서비스를 종료하여 즉각적인 메모리 확보가 가능합니다.

# 실행 중인 서비스 확인
systemctl list-units --type=service --state=running

# 불필요한 서비스 중지
systemctl stop service_name
systemctl disable service_name

2단계: 웹서버 최적화

Apache 최적화:

Apache는 기본 설정에서 많은 메모리를 사용합니다. /etc/apache2/mods-available/mpm_prefork.conf 파일을 수정합니다.

<IfModule mpm_prefork_module>
    StartServers 2
    MinSpareServers 2
    MaxSpareServers 5
    MaxRequestWorkers 50
    MaxConnectionsPerChild 3000
</IfModule>

Nginx로 전환 고려:

Nginx는 Apache보다 훨씬 적은 메모리를 사용하면서도 높은 성능을 제공합니다. 특히 정적 파일 서빙이나 리버스 프록시 용도로 적합합니다.

3단계: PHP 메모리 최적화

PHP-FPM 설정을 조정하여 메모리 사용을 최적화합니다.

# /etc/php/8.1/fpm/pool.d/www.conf 수정

pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 6
pm.max_requests = 500

각 PHP 프로세스가 약 30-50MB를 사용한다면, max_children을 적절히 조정해야 합니다. 2GB 메모리 서버라면 20-30개가 적당합니다.

4단계: 데이터베이스 최적화

MySQL/MariaDB 설정 조정:

/etc/mysql/my.cnf 파일을 수정하여 메모리 사용을 제한합니다.

[mysqld]
innodb_buffer_pool_size = 512M
max_connections = 50
query_cache_size = 0
query_cache_type = 0
table_open_cache = 400

innodb_buffer_pool_size는 전체 메모리의 50-70%를 할당하되, 다른 서비스 메모리를 고려해야 합니다.

5단계: 캐시 시스템 메모리 제한

Redis 메모리 설정:

/etc/redis/redis.conf에서 최대 메모리를 명시적으로 제한합니다.

maxmemory 256mb
maxmemory-policy allkeys-lru

6단계: 스왑 메모리 최적화

물리 메모리가 부족할 때를 대비해 스왑 메모리를 적절히 설정합니다.

# 스왑 파일 생성 (2GB)
fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile

# 영구 설정
echo '/swapfile none swap sw 0 0' >> /etc/fstab

# 스왑 사용 적극성 조정 (낮을수록 물리 메모리 우선)
sysctl vm.swappiness=10
echo 'vm.swappiness=10' >> /etc/sysctl.conf

7단계: 메모리 누수 탐지

애플리케이션의 메모리 누수를 찾기 위해 지속적으로 모니터링합니다.

# 특정 프로세스의 메모리 사용량 추적
watch -n 5 'ps aux | grep php-fpm | awk "{sum+=\$6} END {print sum/1024 \" MB\"}"'

메모리 사용량이 지속적으로 증가한다면 애플리케이션 코드를 점검해야 합니다.

장기적인 메모리 관리 전략

모니터링 시스템 구축

서버 메모리를 실시간으로 모니터링할 수 있는 도구를 설치합니다. Grafana와 Prometheus, Netdata 등이 좋은 선택입니다.

# Netdata 설치 (간단한 모니터링)
bash <(curl -Ss https://my-netdata.io/kickstart.sh)

로그 분석

메모리 부족으로 인한 OOM Killer 발생 여부를 확인합니다.

# OOM Killer 로그 확인
dmesg | grep -i "killed process"
grep -i "out of memory" /var/log/syslog

정기적인 재시작 스케줄링

메모리 누수가 완전히 해결되지 않았다면, 임시 방편으로 서비스를 정기적으로 재시작할 수 있습니다.

# crontab에 주간 재시작 추가
0 3 * * 0 systemctl restart php-fpm && systemctl restart nginx

메모리 업그레이드 시점 판단

최적화를 모두 수행했음에도 메모리 사용률이 지속적으로 80% 이상이라면 하드웨어 업그레이드를 고려해야 합니다. 클라우드 서버의 경우 인스턴스 타입을 변경하거나, 물리 서버라면 RAM 증설이 필요합니다.

마치며

서버 메모리 부족 문제는 웹사이트 성능에 직접적인 영향을 미치는 중요한 이슈입니다. 정기적인 모니터링과 적절한 설정 최적화를 통해 대부분의 문제를 예방할 수 있습니다. 현재 메모리 상태를 정확히 진단하고, 각 서비스의 메모리 사용을 최적화하며, 필요시 하드웨어 업그레이드를 고려하는 체계적인 접근이 안정적인 서버 운영의 핵심입니다.

댓글 남기기