이번 시간에는 성능과 용량을 측정하고 개선하는 절차에 대해서 알아보도록 하자
목표와 모델의 정의
주요 업무 패턴이나 튜닝의 대상이 되는 시나리오의 개별 성능 목표를 정의해보자
예를 들면 전체 성능 목표가 동시 사용자 1,000명에 대해서 응답 시간 1초 내의 시스템이 전체 성능 목표라고 가정하고 전체 성능 목표를 대략 1,000 TPS라고 하자 1000 TPS가 바로 성능 목표가 된다.
다음은 성능 모델의 정의해야 한다. 해당 시스템의 주요 사용자 시나리오가 여러 개 있을 때 각 시나리오의 사용 비중을 정의해야 한다. 예를 들면 사진을 저장하는 클라우드 서비스 시나리오가 있다고 하면 이 서비스의 주요 사용자 시나 오리는 다음과 같을 수 있다.
- 로그인
- 사진 리스트
- 사진 업로드
- 사진 보기
- 사진 다운로드
- 로그 아웃
이 중에서 한 사용자가 실행하는 비율을 따져야 한다. 즉 사용자가 로그인한 후 리스트 보기를 열 번, 업로드를 두 번, 보기를 다섯 번, 다운로드를 한 번한 후에 로그아웃한다고 가정을 해보면 비율은 다음과 같다
성능 모델: 로그인 5%, 리스트 보기 50%, 업로드 10%, 보기 25%, 다운로드 5%, 로그 아웃 5%
이 비율을 기준으로 복합 시나리오 부하 테스트를 수행하였을 때 1,000 TPS가 나와야 하고 각 시나리오의 최소 로그인의 경우 1,000 TPS의 5%인 50 TPS, 리스트 보기는 500 TPS를 웃돌아야 한다.
부하 생성
성능 모델이 정의되었으면 모델에 따라서 부하를 생성해야 한다.
부하를 생성하는 도구에는 여러 가지가 있다. 간단하게 쓸 수 있는 도구로는 Apache AB라는 명령어 기반의 도구가 있으며, 복잡한 스크립트를 지원할 수 있는 도구로는 Grinder나 Apache JMeter 등 그리고 Grinder를 GUI가 지원되도록 확장한 nGrinder라는 도구가 있다.
부하 생성에 사용되는 스크립트는 복잡도가 생각보다 높고, 이후 회귀 테스트에도 재사용하기 때문에 반드시 형상 관리 시스템(VCS)을 통해서 관리할 것을 권장한다.
테스트와 모니터링
부하 테스트가 준비가 되면 테스트를 진행하면 주요 성능 요인을 지속적으로 모니터링하고 기록해야 한다.
주로 모니터링해야 하는 요인들은 다음과 같다
- 애플리케이션 관점
- 미들웨어 관점
- 인프라 관점
애플리케이션 관점
시스템의 성능을 측정해야한다. 주요 모니터링 내용은 다음과 같다.
- Response Time : 요청(Request)별 응답 시간
- TPS(Throughput Per Second) : 초당 요청(Request) 처리량
위의 요인들이 성능의 궁극적인 최종 목표값이 되기 때문에 가장 중요한 성능 요인이 되며 부하 생성 도구를 통해서
측정할 수 있다.
미들웨어 관점
미들웨어는 애플리케이션이 작동하기 위한 기본적인 솔류션이다.
- 아파치와 같은 웹 서버
- 톰캣과 같은 웹 애플리케이션 서버
- RabbitMQ와 같은 메세지 큐
- MySQL과 같은 데이터베이스
등이 해당한다. 각 성능 시나리오별로 거쳐 가는 모든 미들웨어를 모니터링해야 하는데, 이를 위해서 각 솔루션에 대한 깊은 이해가 필요하다.
웹 서버는 성능이 문제가 되는 부분은 거의 없다. 성능 문제는 대부분 네트워크 아웃바운드 IO(대역폭) 쪽에서 발생할 때가 많다. 웹 서버가 설치된 하드웨어의 네트워크 아웃바운드 IO의 대역폭을 모니터링하는 것이 좋다
대부분 성능 문제는 톰캣과 같은 애플리케이션 서버와 DB 단에서 많이 발생한다.
애플리케이션 서버는 스레드의 수와 큐의 길이가 1차 모니터링 대상이 된다. 서버가 용량을 초과하게 되면 유휴 스레드 수가 떨어지게 되고 유휴 스레드가 0이 되면 요청 메세지가 앞단의 큐에 저장된다. 그래서 이 두 개를 모니터링하면 시스템의 병목 상태인지 아닌지 판단 할 수 있다. 이 값들은 JMX(Java Management Extension) API를 이용하면 모니터링 하면 된다.
DB의 경우에는 슬로우 쿼리를 모니터링하면 특히 느리게 수행되는 쿼리들을 잡아서 튜닝할 수 있다.
인프라 관점 : cpu, 메모리, 네트워크 IO, 디스크 IO
하드웨어 인프라에 대한 부분을 지속적으로 모니터링해줘야 한다. 이는 하드웨어가 해당 성능을 내기에 용량이 충분한지,
하드웨어 구간에서 병목이 생기지는 않는지, 생긴다면 어느 구간에서 생기는지를 모니터링하여 해당 병목 구간에 대한 문제 해결을 하기 위함이다.
인프라에 대한 모니터링은 Ganglia 나 Cacti와 같은 전문화된 인프라 모니터링 도구를 사용하거나 top이나 glance, sar와 같은 유닉스 / 리눅스 명령어를 사용해도 된다.
cpu
일반적으로 cpu는 모니터링한다. 목표 성능을 달성할 시에는 보통 70~80% 정도의 cpu를 사용하는 것이 좋고 항상 20~30% 여유를 두는 것이 좋다
메모리
피크 타임 시에 메모리가 얼마나 사용되느냐가 중요한데, 자바 애플리케이션은 특성상 전체 JVM 프로세스가 사용할 메모리 양을 미리 정해놓기 때문에 부하 테스트 중에도 메모리 사용량 자체는 크게 변화하지 않는다만 스와핑 상태(Swapping Statue)를 자주 놓치게 된다.
리눅스 / 유닉스는 시스템의 특성상 물리 메모리 이상의 메모리를 제공하기 위해서 가상 메모리라는 개념을 사용한다. 스와핑 공간이라는 디스크 공간에 자주 사용하지 않는 메모리의 내용을 덤프 해 저장하여 다시 사용할 때 메모리에 로딩하는 방식을 사용한다. 이 메모리의 내용을 디스크에 저장 및 로드하는 과정을 스와핑이라고 한다.
스와핑 과정이 실제 디스크 IO 발생시키기 때문에 실제 메모리 액세스 성능이 매우 급격하게 떨어진다. 그래서 시스템에서 스와핑이 발생하면 시스템의 성능이 장애 수준으로 매우 급격하게 떨어진다.
디스크 IO
파일 시스템에 파일을 저장하는 시나리오나 로그를 저장하는 모듈, 그리고 데이터 베이스와 같이 뒷단에 파일 시스템을 요구하는 모듈에서 많이 발생한다.
Ganglia와 같은 도구를 사용하면 IOPS(Input Out Per Second : 초당 읽기/쓰기 등의 IO 발생 횟수)를 통해서 모니터링할 수 있다. 또는 iostat나 sar와 같은 명령어를 이용하면 iowait를 통해서 디스크 IO의 지연이 발생하면 디스크 병목이 있는지 없는지 확인할 수 있다.
디스크 IO에 대한 병목은 여러 가지 해결 방법이 있다.
-
하드웨어 인프라 자체에서 접근하는 방식
-
디스크 자체를 SSD로 변경
-
버퍼가 크거나 RPM이 높은 디스크로 변경
-
인터페이스를 STAT에서 SAS나 SSD와 같은 높은 IO를 제공하는 디스크 인터페이스로 변경
-
-
디스크 컨트롤러
-
iSCSI에서 FC/HBA와 같은 광케이블 기반의 고속 컨트롤러 사용
-
RAID 구성을 스트리핑 방식으로 변경해서 IO를 여러 디스크로 분산시키는 방식
-
-
애플리케이션
-
DB앞에 Memcache와 같은 캐싱을 사용
-
로깅의 경우 중간에 MQ를 써서 로그를 다른 서버에서 쓰도록 하여 IO를 분산할 수 있다.
-
백 라이트 같은 방식으로 로그 메세지가 발생할 때마다 디스크에 쓰는 것이 아니라 20~30개씩 한꺼번에 디스크로 플러싱 하는 방식
-
조금 더 높은 아키텍처 수준으로는 디스크 IO가 많이 발생하는 로직은 동기 처리에서 메세지 큐를 사용하는 비동기 방식으로 시스템의 설계를 변경하는 방법을 고민할 수 있다.
네트워크 IO
네트워크 IO는 특히 고용량의 파일이나 이미지 전송에서 병목이 자주 발생한다.
- Reverse Proxy
- NAT (Network Address Translator)
- 라우터
- 로드 밸런서
등에서 많이 발생한다. 여러 가지 지점과 장비에 대해서 모니터링해야 하기 때문에 일반적인 유닉스 / 리눅스 명령어를 사용하는 방법보다는 Cacti나 Ganglia와 같은 RRD 도구나 OpenNMS와 같은 NMS(Network Management System)을 사용하는 것이 좋다.
다음 시간에는 성능 튜닝에 대해서 알아보자
이전글
[조대협 대용량 아키텍처]성능 엔지니어링
성능 엔지니어링(Performance Engineering) : 시스템의 목표 성능(응답 시간과 동시 접속자 수)을 정의하고 이를 달성하기 위해서 시스템의 구조를 반복적으로 개선하는 작업 성능 엔지니어링은 언제 해야 하는가?..
alsyean.tistory.com
다음 글
[조대협 대용량 아키텍처]성능 튜닝
지난 시간에 성능에 대한 병목을 찾았다. 이제 해당 병목 문제를 해결 및 반영해야한다. 튜닝은 병목 구간이 발생한 부분에 대한 전문적인 지식이 필요하지만, 기본적인 접근 방법은 거의 같다고 보면 된다. 문제..
alsyean.tistory.com
이 글은 조대협의 서버사이드 대용량 아키텍처와 성능 튜닝 책을 참고하여 작성되었습니다.
이 글은 코드 프레소 DevOps Roasting 코스를 수강하면서 작성한 글입니다.
'아키텍처' 카테고리의 다른 글
[조대협 대용량 아키텍처]성능 엔지니어링이 필요한것들 (0) | 2020.02.16 |
---|---|
[조대협 대용량 아키텍처]성능 튜닝 (0) | 2020.02.16 |
[조대협 대용량 아키텍처]성능 엔지니어링 (0) | 2020.02.15 |
[조대협 대용량 아키텍처]아키텍트 (0) | 2020.02.10 |
[조대협 대용량 아키텍처]글로벌 서비스 아키텍처 (0) | 2020.02.10 |