본문으로 건너뛰기

20.1 왜 성능 튜닝을 해야 하는가?

응답속도가 느린 웹 사이트는 고객들의 불만이 쌓이고 결국에는 다른 웹 사이트로 이동해 버리게 된다. 수익을 목적으로 하는 웹 사이트를 운영하는 기업이라면 고객의 관심뿐만 아니라, 비즈니스 기회도 잃어버릴 수 있다. 고객이 어쩔 수 없이 성능이 낮은 애플리케이션을 계속 사용해야 한다면 결국에는 비즈니스 트랜잭션이 줄어 버리거나, 서비스 사용을 포기하고 떠나가 버릴지도 모른다.

기업에서 임직원이 사용하는 애플리케이션이라도 예기치 못한 대기 시간이 발생하거나, 낮은 성능은 기업의 생산성에 영향을 미치게 된다. 이러한 상황에서 사용자는 시스템에 대한 불만이 생기고, 업무시간을 낭비하게 되어 IT부서에 대해서 부정적인 인식이 생기게 된다.

성능이 높은 애플리케이션의 특징은 하드웨어나 소프트웨어 자원을 보다 효율적으로 사용하는 것이다. 튜닝을 통해 최적화된 애플리케이션은 노후화된 시스템을 더욱 오랫동안 사용할 수 있게 되며, 신규 시스템 경우에는 도입 규모를 축소하더라도 기대한 성능을 제공하여 더 적은 투자비용으로 운영할 수 있다.

기업은 튜닝을 통하여 하드웨어 투자를 최적화할 수 있다. 소프트웨어 측면에서 보더라도 애플리케이션이 잘 튜닝되어 성능이 좋으면 더 작은 수의CPU를 사용하게 되고, 이에 따라 소프트웨어 라이선스 비용도 절감할 수 있다. 튜닝의 효과로 인해 기업은 시스템을 구축/운영/유지보수 하는 전 단계를 거쳐 비용을 절감하게 된다.

성능 튜닝 목표

성능에 대한 튜닝을 어느 수준까지 할지를 결정하는 것은 어려운 문제이다. 시스템 운영 초기의 성능은 주로 애플리케이션의 성능 최적화에 크게 의존하며, 이후에는 하드웨어, 데이터베이스, 애플리케이션 서버의 성능에 의해 결정된다. 많은 경험을 가진 엔지니어라 하더라도 하드웨어 사양이나 애플리케이션 서버의 종류에 따라 예상되는 성능을 추측하는 것은 불가능하다. 시스템 성능을 예측하기 위한 가장 현실적인 방법은 부하테스트를 진행하여 주어진 애플리케이션, 하드웨어, 소프트웨어에서 최적화된 성능 기준을 확인하고 이를 바탕으로 추론하는 것이다.

튜닝된 시스템을 대상으로 부하를 발생시키면 애플리케이션 서버의 부하가 가장 높아진다. 만약 애플리케이션 서버의 CPU 사용률이 80%가 넘을 경우, 미들웨어 측면에서 리소스에 의한 병목이 없어서 해당 하드웨어와 애플리케이션 서버에서 성능의 한계 값에 가깝다고 할 수 있다.

성능 튜닝은 병목 구간을 발견하고 이에 대해 대처해야 하는 수준 높은 기술을 요구한다. 튜닝 작업은 애플리케이션 서버 공급 업체 컨설팅 또는 경험이 풍부한 엔지니어를 찾는 등 외부와 내부의 지식을 효율적으로 사용하여 수행하는 것을 권장한다.

성능 튜닝의 기본 원칙

많은 기업이 IT 업계에서 일반적으로 사용하는 성능 벤치마크를 기준으로 미들웨어를 선택한다. 제품 공급 벤더에서 벤치마크는 판매를 위한 좋은 기준이 되지만 벤치마크 애플리케이션은 일반적인 기업의 운영환경 애플리케이션과는 달라서 고객에게 잘못된 정보를 전달하는 경우가 있다.

공식적인 성능 테스트 결과와 그 구성환경에 대해서 이해하더라도 기업마다 다르게 구축되는 시스템 환경으로 인하여 성능에 대한 지표를 참조할 수 있는 경우는 많지 않다. 현명한 판단을 위해서는 벤치마크 결과 전체를 받아들이기보다는 거기서 사용된 소프트웨어와 하드웨어의 구성, 서버와 네트워크의 구성, 각종 설정 상태, 애플리케이션 아키텍처를 조사하고 그것이 기업의 애플리케이션 환경과 비교하는 것이 중요하다.

원칙1 : 현재 운영 시스템의 성능을 파악한다.

성능 튜닝의 첫 번째 단계는 현재 운영 중인 시스템의 상황과 성능을 정확하게 객관적인 수치로 파악하는 것이다. 만약 운영 중인 시스템을 대체하는 경우라면 운영자들은 그동안 여러 가지 운영 경험이 있을 것이다. 접속 사용자 수, 1일 트랜잭션 수 , 1주/1달/1년 주기의 트랜잭션 수, 부하의 종류나 변화 등의 지표를 이미 알고 있을 것이다.

이전 시스템이 어떻게 운영되는지를 더 깊게 이해하면 더 뛰어난 성능 튜닝 결과를 이끌어 낼 수 있다.

원칙2 - 성능 기준은 평균이 아닌 피크 시간으로 한다.

성능 요건을 분석할 때는 피크 시간의 부하에 주의를 기울이면서 애플리케이션을 프로파일링하는 것이 중요하다. 일반적인 비즈니스 애플리케이션 경우 피크시간은 출근 직후 나 점심식사 시간 이후 오전과 오후에 발생한다. 애플리케이션에 따라 월말이나 마지막 분기 말마다 피크가 발생하는 경우도 있다. 운영자나 개발자 모두 피크 시간의 부하 상황에 대해서 항상 주의를 기울여야 한다.

개발자들이 많이 하는 성능과 관련된 오해 중 하나는 하루의 평균 워크로드를 기준으로 삼는 것이다. 평균값을 기초로 개발된 애플리케이션은 피크시의 부하에 충분히 대응할 수 있는 성능을 제공할 수 없다.

원칙 3 : 성능은 항상 모니터링 해야 한다.

모든 애플리케이션은 성능을 분석하기 위한 정보를 제공하고 있다. 고객의 사용패턴이나 부하는 시간에 따라 변화하여 아무리 성능이 뛰어난 애플리케이션이라도 상황에 따라서 좋은 성능을 보장하기 어렵다. 애플리케이션 성능이 측정되지 않는 상황에서 장애가 발생하면 그 원인을 밝히는 것은 더욱 어렵다.

애플리케이션을 모니터링 하면 사전에 비즈니스 상태의 변화를 감지하여 문제가 발생하기 전에 시스템 운영 환경을 그에 맞게 구성하는 것이 가능하다.

성능에 관련된 지표들을 어느 정도 수준으로 모니터링 할지를 결정하는 것은 튜닝에 대한 전문 지식과 시간 그리고 목적에 따라 결정해야 한다.

원칙 4 : 병목구간을 파악한다

애플리케이션을 모니터링하는 큰 이유 중에 하나는 처리 시간이 많이 소모되는 병목 구간을 찾아내는 것이다. 시스템을 구성하는 전체 스택 중 각각의 계층별로 걸리는 시간을 파악하고 싶다고 해도 애플리케이션 서버에 포함된 도구들은 애플리케이션 서버의 일부 정보만을 제공한다.

만약 애플리케이션이 사용자 응답시간 대부분을 데이터베이스에서 소비한다면, 문제의 원인을 밝혀내기 위해서는 데이터베이스가 제공하는 통계정보를 살펴봐야 한다.

애플리케이션에서 어느 구간에 시간이 많이 소요되는지를 객관적으로 파악하는 것이 성능문제를 해결하기 위한 지름길이다.

원칙 5 : 운영환경과 같은 환경을 구성한다.

운영환경에서 시스템이 어느 정도 성능이 제공되는지 정확하게 파악하기 위해서는 테스트 환경에서 성능을 확인해 봐야 한다. 기업에 따라서는 운영환경과 동일한 테스트 환경을 갖추는 것을 표준으로 하는 곳도 있다. 대규모 시스템을 운영하는 환경에서 애플리케이션이 어떻게 확장해 나가는지를 여러 가지 관점에서 살펴볼 수 있는 환경을 구성해 놓는 것이 이상적인 방법이다.

그러나 기업에서 운영 환경과 동일하게 갖추기 위해서 비용이 많이 들기 때문에 테스트 환경은 소규모로 구성한다. 테스트 환경에서 성능과 운영환경에서 성능의 관련성을 찾기 위한 모델이 필요하다. 이것이 시스템을 확장하는데 필요한 모델이다.

성능 병목 구간 찾기

성능 튜닝은 우선 병목 구간을 찾는 것부터 시작한다. 병목 구간을 찾은 후 어떤 상황에서 성능이 감소 되는지를 파악하는 것이 중요하다. 시스템의 성능 분석은 부하 테스트와 애플리케이션 프로파일링을 동시에 수행한다.

프로토타입 단계에서 성능이 나오지 않는 경우

아키텍처 설계 단계에서 프로토타입을 만들고 성능 테스트를 하였을 때 성능이 나오지 않는 경우가 있다. 성능상의 문제점을 사전에 파악하는 것이 프로토타입의 목적이기도 하다. 이 단계에서는 성능분석 작업에 아키텍처 설계자와 프로토타입 개발자(한 사람이 두 가지 역할을 하는 경우도 있다.)가 참여하고 있기 때문에 문제점이 발견되면 그것을 수정하는데 많은 시간이 걸리지 않는다. 또한, 프로그램 규모가 작아서 프로파일도 효과적으로 진행할 수 있다.

종합 테스트 단계에서 성능이 나오지 않는 경우

종합 테스트 단계에서 기대한 성능에 도달하지 못한 경우에는 테스트를 진행하여 초기 단계에서 성능에 문제를 발견한 것에 비해 범위는 넓어지지만, 기능별로 성능상의 문제가 되는 것을 비교적 쉽게 찾을 수 있다. 이 시점에서는 아직 서버 설정 변경을 자유롭게 할 수 있으므로 불필요한 요소를 제거하면서 테스트를 수행할 수 있다.

운영 중인 시스템에서 성능이 문제가 되는 경우

운영 중인 시스템에서 사용자가 "응답속도가 느리다."등의 불만이 있을 경우가 있다. 먼저 시스템의 어떤 계층에 문제가 있는지를 분명히 해 두지 않으면 쓸데없는 시간을 낭비하게 될 수 있다. 예를 들어 과부하시 전체적으로 응답이 나빠지는 것과 같은 막연한 상황에서는 운영 환경의 여러 계층을 의심해야 한다.

평상시에 주의 깊게 살펴봐야 할 모니터링 매트릭스를 지정하여 문제 발생할 때 즉시 대응할 수 있도록 운영 환경에서 모니터링을 한다.

성능 튜닝 개요

  • 하드웨어 / 네트워크
  • 운영체제
  • Java VM
  • 애플리케이션 서버
  • J2EE 서비스
  • 애플리케이션

전체 시스템의 성능을 높이기 위해서는 각 계층의 튜닝 포인트를 잘 이해하고 개발 단계의 초기 단계에서부터 성능 데이터를 수집하는 것이 중요하다.

그림 1. 성능 튜닝 요소

부하 테스트 및 프로파일링

부하가 낮은 상태에서는 성능이 느려지는 경우가 없기 때문에 부하 테스트 도구를 사용하여 부하가 높은 상태에서 병목 구간을 찾을 수 있다.

일반적으로 시스템의 성능은 응답 시간과 처리량의 두 가지 측면으로 나타낼 수 있다. 클라이언트 수(병렬 처리 요청 수)가 많아지면 처리량은 증가하지만, 응답 시간은 반대로 감소한다. 클라이언트 수의 증가에 따라 특정 시점을 경계로 처리량 증가가 멈추고(혹은 반대로 감소), 응답 시간이 급격히 감소하게 된다. 이렇게 처리량이 멈추는 시점을 Saturation 포인트라고 한다. 먼저 부하 테스트를 통해서 Saturation 포인트를 찾고, 이 한계점보다 앞의 중간 부하 수준(동시 접속 수)에서 한다.

그림 2. 부하 테스트 시 Saturation 포인트

여러 공급 업체에서 부하 테스트 도구를 제공하고 있지만, 오픈 소스 부하테스트 도구인 Apache JMeter(http://jmeter.apache.org/)을 이용하면 상용 도구에 비하면 기능은 적지만 튜닝의 효과를 확인하는 수준이라면 이것으로 충분하다.

병목이 걸리는 특정 코드는 Java 프로파일링 도구(프로파일러)를 사용하면 된다. 프로파일링 도구를 사용하지 못하는 환경이라면, Java의 스레드 덤프를 이용하여 분석할 수 있다. 스레드 덤프는 kill -3 <pid>를 실행하면 현재 실행 중인 스레드들의 스택 트레이스를 stdout에 출력한다. 마치 JVM에 대해 X-Ray 사진을 찍는 것과 같다. 스레드의 변화하는 상태를 확인하려면 스레드 덤프를 여러 번 연속해서 얻는 것이 좋다. 예를 들어 3초 간격으로 5~10회 얻어 분석한다.