- 출처 : 유닉스 리눅스 쉘스크립트 예제사전_한빛미디어
명령어: df, awk, read, echo, rm
키워드: 메모리, 감시, 스왑
사용처: 남은 메모리를 정기적으로 감시해서 스왑이 발생하면 경고하고 싶을 때
실행 예제
$ ./swapcheck.sh
[2023/09/08 15:15:15] Swap Alert: 352 (si+so)
ALERT...
스크립트
#!/bin/sh
# 감시할 스왑 발생 횟수. 이 숫자를 넘기면 경고
swapcount_limit=10 # ------------------------------------------------------- 1
# vmstat 명령어 출력에서 스왑인, 스왑아웃 값 취득
swapcount=$(vmstat 1 6 | awk 'NR >=4 {sum += $7 + $8} END{print sum}') # --- 2
# 스왑 횟수가 허용값을 넘기면 경고
if [ "$swapcount" -ge "$swapcount_limit" ]; then # ------------------------- 3
# 현재 시각을 [2023/09/08 15:15:15] 형태로 조합
date_str=$(date +'%Y/%m/%d %H:%M:%S') # ---------------------------------- 4
# 스왑 발생 경고 출력
echo "[$date_str] Swap Alert: $swapcount (si+so)" # ---------------------- 5
/home/user1/bin/alert.sh
fi
해설
이 스크립트는 현재 서버 메모리 상태를 확인해서 메모리 부족이 일어나지 않는지 감시합니다. 여기서 메모리 부족은 서버에서 발생하는 스왑인, 스왑아웃 횟수로 판별합니다. 빈번히 스왑이 발생하면 메모리가 부족하다고 판별하고, 경고 메시지를 표시합니다.
스왑 횟수는 vmstat 명령어로 취득하고, 셸 별수 swapcount_limit로 지정한 값보다 최근 5초간 스왑인, 스왑아웃 횟수가 크면 alert.sh 스크립트를 실행합니다. 그리고 예제에서 alert.sh는 통지 메일을 송신하는 등으로 경고를 보내는 스크립트라고 가정합니다.
1
에서 스왑 횟수 감시 허용값을 설정합니다. 이 스크립트는 1초마다 5번 계측해서 스왑인, 스왑아웃 횟수를 모두 더한 값이 허용값 이상이면 경고합니다. 여기서 스왑 횟수 허용값 10이란 ‘가끔 경고가 나오는 것은 괜찮아도 계속 이어지면 문제가 발생했다고 보는 값’이라고 합시다. 환경에 따라서 실제 허용값으로 변경하기 바랍니다. 일반적으로 아파치 httpd 같은 웹 서버에서 정적 컨텐츠를 반환하기만 한다면 디스크에 있는 컨텐츠를 리퀘스트에 따라 보낼 뿐이므로 그다지 메모리가 들지 않습니다. 웹 서버나 자바 애플리케이션 등을 실행하는 애플리케이션 서버는 많은 메모리를 사용하므로 스왑 발생에 주의해야 합니다.
2
에서 스왑 횟수를 취득하기 위해 vmstat 명령어를 실행하빈다. vmstat 명령어는 서버의 현재 리소스 상태를 표시합니다. OS에 다라 표시 형식이 다르므로 여기에서는 리눅스 예를 소개합니다. FreeBSD나 Mac은 나중에 설명합니다.
- vmstat 명령어 실행 예(리눅스)
$ vmstat 1 3 procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 3 0 160480 116856 0 308320 0 1 25 4 41 74 0 0 99 0 0 0 0 160480 116856 0 308352 0 0 0 0 118 250 5 0 95 0 0 0 0 160480 116856 0 308352 0 0 0 0 148 322 8 1 91 0 0
vmstat 명령어 인수로 1 3을 지정합니다. 첫 인수가 몇 촘다 계측할 것인가를 지정합니다. 두 번째 인수가 몇 번 계측할 것인가를 정하는데 여기서는 1초마다 3회 측정합니다. vmstat 명령어로 다양한 데이터를 얻을 수 있지만 여기서는 —swap— 열에만 주목합니다. si가 스왑인, so가 스왑아웃 횟수입니다. 따라서 7번째 컬럼과 8번째 컬럼 숫자를 더한 값이 지표입니다.
vmstat 명령어 첫 줄은 현재 상태가 아니라 서버 기동 시부터 평균값을 출력합니다. 따라서 이 값은 현재 상태와 다른 값일 때가 많습니다. 따라서 감시 용도로 vmstat명령어 첫 번째 출력값은 무시하는 것이 좋습니다.
2
에서 awk 명령어로 NR >= 4로 필터해서 헤더 두 줄과 첫 번째 출력값을 넘기고 4번째 줄부터 데이터를 취득합니다. 그리고 스왑 횟수 si와 so는 7번째 컬럼과 8번째 컬럼에 있으므로 $7과 $8 값을 sum이란 awk 변수에 더합니다. 마지막으로 END 블록으로 sum을 출력하면 최근 5초간 스왑 횟수를 표시할 수 있습니다. 이 스왑 횟수는 명령어 치환 $()을 이용해서 셸 변수 swapcount에 대입합니다.
3
에서 계측한 스왑 횟수가 미리 정의한 허용값을 넘었는지 if문으로 판별해서 분기합니다. test 명령어의 ‘이상’을 의미하는 -ge 연산자로 셸 변수 swapcount(스왑 횟수)와 셸 변수 swapcount_limit(허용값)을 비교합니다.
스왑 횟수가 허용값보다 크면 우선 4
에서 date 명령어를 사용해서 현재 시각을 2023/09/08 15:15:15 같은 형태로 조합합니다. 감시 스크립트에서는 문제 발생 시각을 확인할 수 있게 시간을 함께 표시하는게 중요합니다.
마지막으로 5
에서 경고 표시를 하고 스왑 발생 횟수를 출력합니다. 이런 스크립트는 서버 메모리 상태를 감시하기 위해 cron에 등록해서 정기적으로 실행하면 좋습니다.
FreeBSD나 Mac의 경우
FreeBSD의 vmstat 명령어는 리눅스와 표시 형식이 다릅니다.
- FreeBSD vmstat 실행 예
% vmstat 1 3 proc memory page disks faults cpu r b w avm fre flt re pi po fr sr ad0 cd0 in sy cs us sy id 1 0 0 490M 420M 686 1 1 0 718 819 0 0 20 253 236 1 3 97 0 0 0 390M 420M 1 0 1 0 0 0 1 0 3 127 137 0 0 100 0 0 0 490M 420M 0 0 0 0 0 0 0 0 3 117 119 0 0 100
FreeBSD는 si/so가 없고 pi(페이지 인)/po(페이지 아웃)으로 스왑 발생 횟수를 취득할 수 있습니다. 여기서는 8, 9번째 컬럼이므로 [2]{:.info}는 다음처럼 수정합니다.
swapcount=$(vmstat 1 6 | awk 'NR >=4 {sum += $8 + $9} END{print sum}')
Mac에서는 vmstat 명령어가 없는 대신 vm_stat 명령어가 있습니다. 사용 방법과 출력 방법도 리눅스와 상당히 다릅니다.
% vm_stat -c 3 1
Mach Virtual MemoryStatistics: (page size of 4096 bytes)
free active specul inactive throttle wired prgable gaults copy 0fill reactive purged file-backed anonymous cmprssed cmprssor dcomprs comprs pageins pageout swapins swapouts
4084 1572367 5307 1652012 0 777742 33468 464576K 9069783 290309K 2467769 1358643 1569998 1668688 943514 182192 477033 195147 43568086 596465 59042 351103
3608 1571444 5321 1652016 0 778499 33118 568 0 214 0 0 1561029 1667752 943514 182192 0 0 0 0 0 0
4420 1573189 4565 1652019 0 776887 33926 3031 3 642 0 2 1560286 1669487 943514 182192 0 0 0 0 0 0
Mac의 vm_stat 명령어는 계측 횟수를 -c옵션으로 지정하고 인터벌은 명령어 첫 번째 인수로 지정합니다. 그리고 -c 옵션은 최신 버전에 생겼으므로 예전 버전에서는 사용할 수 없습니다.
Mac의 vm_stat 명령어는 FreeBSD처럼 페이지 인(pageins)과 페이지 아웃(pageout) 횟수를 취득하면 스왑 발생 횟수를 알 수 있습니다. 단, vm_stat 명령어는 출력 형식도 버전에 따라 다른데 10.9(Mavericks)부터 컬럼 구성이 크게 변했습니다. 따라서 vm_stat 명령어를 직접 실행해보고 pageins와 pageout 위치를 찾아서 2
를 수정하기 바랍니다.
주의사항
-
이런 메모리 감시를 셸 스크립트로 하는 방식은 소규모 환경에서 보조적인 용도롤 사용하는 경우가 많습니다. 대규모 감시 시스템 구성은 자빅스(Zabbix)나 나기오스(Nagios) 사용을 검토해보기 바랍니다.
-
자바 애플리케이션을 실행한다면 메모리 감시에는 스왑뿐만 아니라 가비지 컬렉션(특히 Full GC) 빈도도 중요해집니다. 자바 전문서를 참조해보기 바랍니다.