성능테스트 진행시 서버 자원 상태에 대해 모니터링이 필요한데,
이에 대한 기본적인 내용을 정리해봤다.
참고 : (도서) 실무로 배우는 시스템 성능 최적화 : 시스템 동작 분석부터 성능 개선까지 (권문수)
기본 방향
CPU | - CPU 자원은 부족한가?
- 실행큐에 얼마나 쌓였는가?
- CPU 사용 유형 중 System이나 IO wait의 사용률이 높은가?
- 프로세스별 CPU 사용률 분포는 균등한가?
|
---|
메모리 | - 메모리가 부족한가? (swap이 발생하고 있는가?)
- 서버 전체 또는 개별 프로세스 단위로 메모리 사용량이 지속적으로 증가하는가?
- 파일 캐시 영역으로 사용하는 메모리량은 얼마인가?
|
---|
디스크 | - 디스크의 서비스 시간은 디스크 대기시간을 포함해서 얼마인가?
- 특정 디스크로 입출력이 집중됐는가?
- 파일시스템 중 공간이 부족한 곳은 있는가?
- 디스크 스프라이트가 잘 구성돼 있는가?
- 스토리지 채널 병목이 있는가?
|
---|
네트워크 | - 네트워크 데이터 전송량은 얼마인가?
- 네트워크 재전송량이 많은가
- RTT (Round-Trip time) 시간이 높은가?
|
---|
- 일반적으로 CPU > 메모리 > 디스크 > 네트워크 순으로 부족 여부를 확인한다.
- 자원 모니터링은 5초나 10초 간격으로 한다.
- 자원 사용률 분석은 그래프를 통해 분석하는 것이 효과적이다.
- 자원 사용률은 프로세스와 연관시켜 분석하는 것이 좋다.
주요 모니터링 도구
netstat
- 네트워크 connection 상태, 라우팅테이블, 인터페이스 통계 정보 등을 출력
- 사용 예
- netstat -anp : 열려있는 모든 포트 출력
- netstat -anp | grep LISTEN : listen 되는 모든 포트 출력
- 옵션
- -a : 모든 listening, nonlistening 상태 소켓들을 출력
- -n : ip 주소 형태로 표시
- -p : 소켓 소유하고 있는 pid와 프로그램 이름을 출력
- -t : TCP 소켓 리스트 출력
- -u : UDP 소켓 리스트 출력
- -c : 1 초 단위로 연속해서 출력
- -r : 라우팅 테이블 정보 출력
vmstat
- 프로세스/메모리/입출력/시스템/CPU 활동상황에 대한 정보 확인
- vmstat <delay> <count>
- vmstat 모니터링
프로세스 관련 항목
- r : CPU 접근 대기 중인 실행 가능 프로세스의 수
- b : 인터럽트 불가능한 sleep 상태에 있는 프로세스의 수
- memory 관련 항목
- swpd : 사용된 가상 메모리 용량
- free : 여유 메모리 용량
- buff : 버퍼에 사용된 메모리 용량
- cache : 페이지 캐시에 사용된 메모리 용량
- swap 관련 항목
- si ( swap in ) : 디스크에서 스왑된 메모리 용량
- so ( swap out ) : 물리적 메모리가 부족할 경우 디스크로부터 사용되는 메모리 양. swap out이 지속된다면 메모리 부족을 의심할 수 있음.
- io 관련 항목
- bi : block device에서 받은 블록 수 (blocks/s)
- bo : block device에서 보낸 블록 수
- system 관련 항목
- in : 초당 발생한 interrupts 수
- cs : 초당 발생한 context switches 수
- cpu 관련 항목
- us : cpu 가 사용자 수준 코드를 실행한 시간
- sy : cpu 가 시스템 수준 코드를 실행한 시간
- id : cpu가 아무런 작업을 수행하지 않은 시간
- wa : 입출력 대기
- st : 가상화를 사용할 경우 가상머신 cpu의 계산으로 대기된 시간
- vmstat 옵션
- -a : buff와 cache대신 active/inactive로 출력
- -n : 주기적으로 헤더를 출력하지 않도록 지정
- -S : 출력되는 데이터 단위 지정 (k, K, m, M 지정 가능 = 1000, 1024, 1000000, 1048576으로 나눈값 출력)
top
- linux kernel을 통해 관리되는 프로세스의 태스크 리스크들의 정보 (메모리, cpu, 상태정보) 등을 확인할 수 있는 명령어
- 사용법
- 옵션
- -d : delay
- -n : interactions
- -p : pid
sar
- top와 마찬가지로 cpu/memory/hdd 사용량 통계치 등을 모니터링할 수 있지만, sar는 history 및 최종 통계치를 볼 수 있다.
- sar 명령을 사용하려면 sysstat package가 설치 되어 있어야 한다.
- sar <option> <interval> <count>
- 옵션
- -u : cpu activity
- -r : memory activity
- -d : disk i/o activity
- -A : report overall system performance
free
- 현재 시점의 메모리 상태를 쉽게 확인할 수 있음.
- free <-b|-k|-m|-g><option>
- 옵션
- b/k/m/g : 메모리양을 바이트/킬로바이트(기본값)/메가바이트/기가바이트로 표시한다.
- -t : 총계가 포함된 줄을 출력
- -o : 버퍼에 조정된 줄의 출력을 비활성화 한다.
- -s : delay 초마다 계속해서 출력하도록 한다.
ps
- 현재 수행되고 있는 프로세스 확인하는 명령어
- ps -ef | grep httpd (특정 프로세스 확인)
- ps -ef | wc -l (현재 기동중인 프로세스 총 수 확인)
CPU Monitoring
- 안정적인 운영을 위한 CPU 사용율 기준
- CPU 사용률 : CPU 70% 이하
- CPU 실행큐 : CPU core 당 평균 3개 이하
- 전체 CPU 기준으로 성능 평가를 할 때는 이중화 구성 등에 따른 부분 장애시에 대한 변화량/사용량을 맞춰서 판단할 필요가 있다.
- CPU 사용량 상세 분석
- System : 커널모드 시스템 콜 호출에 사용된 CPU 사용량.
- 시스템 콜이라 함은 프로세스 제어, 장치 관리, 파일과 네트워크 관리, 입출력 처리, 시스템 정보와 시간 관리 등에 관련된 함수
- 일반적으로 전체 사용량 대비 30% 미만인데, system cpu가 높게 나타난다면 어떤 유형의 시스템 콜인지 분석할 필요가 있다
- 시스템 콜 모니터링 도구 : truss / pstack / jstack
- User : 일반 함수를 실행하는데 사용된 CPU 사용량. WAS나 DB 서버 경우 User CPU를 사용한다.
- IO Wait : 프로세스나 스레드가 CPU를 할당받아 사용할 수 있는 상태가 됐으나, 입출력이 완료되기를 기다리고 있어 CPU를 사용할 수 없는 상태의 사용량
- 일반적으로 전체 사용량 대비 20% 미만인데, 높게 나타난다면 입출력이 과다하게 발생하는 것은 아닌지 디스크 사용률 등을 확인하면 된다.
- io wait 모니터링 도구 : netstat / iostat / sar
- Idle : 사용하지 않는 CPU 여유율
- 기타 모니터링 방법
- CPU core 수 확인 방법 (리눅스 기준) : cat /proc/cpuinfo
- 커널 처리 비트 확인 방법 (리눅스 기준) : getconf WORD_BIT
- CPU를 많이 사용하는 스레드 식별하는 방법 : top -H , ps -eLf | grep pid
- 프로세스의 누적 CPU 사용량 확인하는 방법 : ps -ef
Memory Monitoring
- 메모리 사용패턴이 100% 라고 해도 부족하지 않으면 성능저하가 발생하지 않는다.
- 운영체제 측면에서는 페이징스페이스에 대한 스왑 발생 여부로 판단.
- 자바기반 솔루션 (was 등) 등은 설정한 힙메모리 이상을 사용하지 않기 때문에 운영체제 메모리 부족이 발생할 가능성은 적다.
- 메모리 관련 용어
- pagingspace : 메인메모리가 부족할 때 사용하는 디스크 공간, swap space라고도 부름.
- 운영체제가 메인 메모리 크기 이상의 메모리를 사용할 수 있도록 해주는 역할.
- 성능 관점에서보면 디스크에 프로세스 메모리를 쓰고 읽는 스와핑 작업으로 인해 큰 성능 저하가 발생한다.
- pagingspace 크기 확인 방법 : cat /proc/swaps
- paging :
- swapping : 메모리에서 페이지 혹은 세그먼트 단위 데이터를 교환하는 것. 컴퓨터가 메모리보다 큰 프로그램을 실행하거나 메모리보다 큰 데이터 파일을 다룰 수 있게 함.
- page fault : 페이징 방식의 가상 메모리에서 CPU가 사용하려는 페이지가 메인 메모리에 없는 경우.
- page in : 가상 메모리에서 page fault가 발생했을때 디스크에 있는 프로그램이나 데이터를 메모리로 로드하는 것.
- page out : 가상 메모리에서 page fault가 발생했을 때 메모리가 부족하면 기존 메모리를 디스크로 기록하는 것.
- page scan rate : 운영체제는 일정량의 여유 페이지를 확보해서 필요한 경우 즉시 제공하기 위해 page scan이라는 검색을 통해 해제함으로써 여분으로 확보할 페이지를 찾는다.
- 안정적인 운영을 위한 메모리 판단 기준
- 메모리 사용률 : 100% 이하
- 지속적으로 프로세스 스와핑이 발생하지 않는지 확인
- 일반적인 메모리 사용률 산출
- 전체 메모리 total : used + free + buffers + cached
- 실제 free 메모리 : free + buffers + cached
- 실제 메모리 사용량 : total - (free+buffers+cached)
- 메모리 총량 확인 방법 : cat /proc/meminfo
- 프로세스 메모리 사용량 확인 방법 : ps -euf
- 파일 캐시 확인 명령 : /proc/sys/vm/buffermem, free -m, vmstat -v
Disk I/O
- 시스템상 디스크 영향도 확인
- 자원 영향도 : CPU 사용률에서 io wait 가 비정상적으로 높은지?
- 디스크 영향도 : 디스크 대기시간과 서비스 시간이 높은지?
- 어플리케이션 영향도
- pstack/jstack 으로 스택을 반복 수집했을 때 서비스 중인 스레드 가운데 파일 입출력 관련 작업 중인 스레드의 비중이 높은지
- lsof/pfiles로 확인한 로그 파일이나 데이터 파일의 크기가 큰지?
- truss/tusc로 모니터링 했을 때 발생하는 입출력의 양이 많은지?
- 디스크 입출력 모니터링 방법
- sar -d <second> <count>
- iostat <option> <second> <count>
- 파일시스템 여유율 확인 방법
APM Solution
참고)
Java Heap Memory
- JVM 메모리 구조 및 GarbageCollator
메소드 영역
힙 영역
프로그램 상에서 데이터를 저장하기 위해 동적으로(실행시간에)할당하여 쓸 수 있는 메모리 영역
new 연산자를 통하여 개체를 동적으로 생성시
메소드 영역과 같이 모든 프로그램에 의해 공유되는 공간 -> 동기화 기법 이용
GC(GarbageCollection)으로 관리 되는 영역
- 스택영역(Stack area)
- 메소드가 호출되어 실행될 때 멤소드의 매개변수, 메소드 내에 선언된 메소드 지역변수, 반호나 값, 임시 변수 등을 저장하기 위한 공간
- 메소드 호출시 필요로 되는 변수들을 스택에 저장하고, 메소드 실행이 끝나면 스택을 반환하게 된다.
- 네이티브 메소드 스택
- java heap memory 누수
- 원인
- 사용자 세션이나 캐시 데이터의 증가로 인한 메모리 증가
- 로직 오류로 참조 레퍼런스가 끊어져야 되는데 그렇지 못해 GC대상에서 누락
- 대용량 조회나 처리 등에서 발생
- 확인 방법
- Full GC 이후 old 영역 메모리 사용량이 지속적으로 증가하는지 여부로 판단.
- java heap memory monitoring
- gc logging 옵션
- -Xloggc:<path to file><filename>
- -XX:+PrintGCDetails -XX:+PrintGCTimeStamps
- -verbose:gc
- java heap dump
- jmap -dump:format=b,file=12345_dump.hprof 12345 (pid가 12345일때)
- kill -3 or Ctrl + Break
- java -Xrunhprof:heap=all,cpu=samples,thread=y,cutoff=0,format=a,doe=n,com.TestRun
- jvm option
- -XX:+HeapDumpOnOutOfMemoryError
- -XX:+HeapDumpPath=/logs/app/dump
- -XX:+HeapDumpOnCtrlBreak