태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

[시작하면서] Enterprise Java & Oracle 성능 분석의 기초 - Part1

Enterprise Java 2007.08.24 20:29
Enterprise 환경의 성능 분석
Enterprise 환경의 성능 분석에 경험이 있는 사람이라면 시스템의 전체 성능을 정확하게 파악하려면 WAS(Application)과 DB(Persistence)를 통합적으로 보는 통찰력이 필요하다는 것에 공감할 것이다.

WAS와 DB의 성능 문제를 통합적으로 보는 방법론이 있는가?라고 질문하면 "모르겠다"가 답일것이다. 이는 다분히 학술적이고 철학적인 문제일 수 있어서 나의 지식 범위를 벗어날 거 같다.

하지만 다행히!!! 이런 단순한 공식 하나가 있다.

Response Time = Service Time + Wait Time

즉, 사용자가 체감하는 응답 시간은 실제로 일을 하는 시간(Service Time)일을 하지 못하고 대기하는 시간(Wait Time)으로 구분할 수 있다.

만일, 정밀한 성능 분석과 다양한 경험을 통해 Application과 DB단에서의 Service Time과 Wait Time을 측정하고 그 상관 관계를 적절히 추리할 수 있다면 사용자가 겪는 성능 문제를 상당히 직관적이고 정확하게 밝혀낼 수 있다.


응답시간 구간의 구성 요소
아래 그림은 User, WAS(Application), DB(Persistence) 레이어로 이루어진 환경을 단순화한 것으로, User 입장에서의 Response Time이 실제로 어떤 요소로 구성되는지를 표현한 것이다.



위의 그림처럼 [Response Time = Service Time + Wait Time]이라는 사상에 근거하여 보다 구체적으로 응답시간 구간을 나눌 수 있다.
일차적으로 Application단에서의 소요 시간은 다음과 같이 세분화할 수 있다.
  • Network Time: User와의 Network 통신에 소요되는 대기 시간
  • Service Time: Worker Thread가 Active하게 일을 하는 시간
  • DB I/O Time: Database와의 통신(Connection/Execute/Fetch/...)에 소요되는 대기 시간
  • Wait Time: File I/O, Net I/O, Lock waiting(Thread synchronization), GC pause 등, DB I/O를 제외한 기타 대기시간
Application에서의 성능 문제를 정확하게 파악하려면 위의 위의 개별 요소에서의 소요 시간이 적당한지, 적당하지 않다면 왜 그런지를 파악할 수 있어야 한다.

Database 단(Application단 관점에서는 DB I/O Time)에서의 소요 시간은 다음과 같이 세분화할 수 있다.(여기서 Database는 Oracle로 간주한다)
  • Network Time: Application과의 Network 통신에 소요되는 대기 시간
  • Service Time: DB Session/Process가 Active하게 일을 하는 시간
  • Wait Time: Lock Waiting, I/O Wating, Latch free Wating 등 필요 자원을 획득하는데 소요되는 대기 시간
Database에서의 성능 문제 또한 각 성능 요소들이 어느 정도의 비중을 차지하는지, 만일 지나치게 많은 시간을 필요로 한다면 왜 그런지 파악할 수 있어야 세말한 성능 분석을 수행할 수 있다.

성능을 결정하는 각 구성 요소에서 어떤 문제가 발생하고 있는지 정확하게 파악하는 것이 대단히 중요하다. 가령 WAS에서 lock waiting이 어떻게 발생하고 있는지, Garbage Collection에 의한 대기 시간(Pause time)이 얼마나 되는지, 데이터베이스에 작업을 요청하고 대기하는 시간을 얼마인지, 그리고 왜 그 정도의 시간을 대기하는지 등이 정확하게 파악되어야 한다.

DB단에서도 마찬가지이다. Application이 요청한 특정 쿼리가 시간이 얼마나 걸리는지, 왜 그 정도의 시간이 걸리는지, 실제로 일을 하는 것인지 아니면 Lock이나 latch free, I/O 대기 시간은 얼마나 되는지를 정확하게 파악해야 한다.

대기 현상의 중요성
응답 시간 구간의 성능 저하 정도를 파악하는데 가장 직관적인 방법은 "대기"(Wait)가 얼마나 많이 발생하는지를 측정하는 것이다. Service Time은 실제로 일을 하면서 사용한 시간인데 반해, Wait Time은 동기화나 I/O, Garbage Collection등의 이유로 인해 일을 하지 않고 소비한 시간이다.

[Response Time = Service Time + Wait Time]의 공식에서 얻을 수 있는 가장 단순한 진실은 Service Time이나 Wait Time, 혹은 둘다를 줄일 수 있다면 Response Time을 줄일 수 있다는 것이다.

특히 Wait Time의 경우, 불필요한(반드시 그런 것은 아니지만) 시간일 확률이 높다. 따라서 효율적인 진단과 튜닝을 통해 Wait Time을 적절히 줄이는 것이 가능하다. 만일 사용자가 작성한 소스를 수정하지 않고도 Wait Time을 줄일 수 있다면 그 효과는 대단히 긍정적이고 바람직한 것이 된다.

OWI - Oracle Wait Interface
오라클에서는 대기 현상을 분석하는 방법론이 대단히 정교하게 발전되어 왔다. 이 방법론을 흔히 OWI-Oracle Wait Interface-라고 부른다.

오라클 대기 이벤트에 대한 보고는 오라클 커널 개발자들에 의해 디버깅 용도로 추가된 것으로 보이는데, 이후 그 용도가 확대되고 다양한 툴과 API가 추가되면서 이제는 오라클 성능 문제를 파악하는 가장 중요한 방법론으로 발전되었다.

좀 과장해서 말하면 OWI에 대한 지식이 없이 오라클의 성능 문제를 분석한다는 것이 이제는 불가능하다고 할 정도이다.

Java/WAS에서의 대기 현상 분석
애석하게도 Java/WAS 환경에서는 OWI와 같은 체계적인 방법론이 존재하지 않는다. 하지만 Thread Dump, GC Dump와 같은 기본적인 툴들을 통해 대기 현상을 어느 정도 분석할 수 있다. 또한 BCI(Byte Code Instrumentation)이나 JVMPI/JVMTI 등을 통해 자신만의 프로파일을 수행할 수도 있다. 대부분의 Java Profiler 툴들이 이러한 방법들을 사용해서 성능 분석 데이터를 제공한다.
(욱짜의 블로그 http://blog.naver.com/ukja/120040782799 에서 BCI에 대한 간략하게 소개한 바 있다)

Java 5에서 공식적인 표준으로 채택된 JMX의 Platform MXBean은 성능 문제를 분석하는 또 다른 표준을 제공한다. Platform MXBean을 이용하면 JVMPI/JVMTI등의 C Interface를 통해서만 얻을 수 있었던 유용한 정보들을 매우 쉽게 얻을 수 있다. 하지만 성능 문제를 본격적으로 분석하기에는 부족한 면이 많으며 앞으로 API의 개선을 통해 실질적인 성능 정보를 제공해줄 것을 기대해본다.

이런 기본적인 툴들이나 API 이외에 WAS가 제공하는 정보들 또한 중요하다. 대부분의 WAS들이 사용자 Request를 효과적으로 처리하기 위해 Thread Pool, Connection Pool, EJB Pool/Cache와 같은 개념들을 구현하고 있다. 이런 Pool과 Cache들에서 대기 현상(Queuing)이 얼마나 발생하는지를 파악하는 것 또한 중요한 대기 현상 분석 기법이 된다.

(Steven Haines가 지은 Pro Java EE 5 Performance Management and Optimization의 159페이지 ~ 172페이지를 보면 대기현상에 기반한 성능 최적화 튜닝 기법에 대한 실사례가 소개되고 있다. 반드시 읽어보기 바란다)

한가지 고무적인 것은 대부분의 WAS가 이런 류의 성능 정보(Pool/Cache 등의 사용량)를 JMX API를 통해 제공(Expose)하기 때문에 마음만 먹으면 자신만의 성능 Repository를 만들 수 있다는 것이다. (하지만 불행하게도 이런 기능을 제공하는 툴들은 매우 드물다. 적어도 국내 Java 성능 관리 툴들은 JMX에 대해서는 무관심한거같다)

Enteprise Java 성능 분석의 문제점과 필요성
Enterprise Java 환경의 성능 분석에 있어서는 다다익선의 원칙이 적용될 수 있다. 즉, 많이 알 수록 좋다. 되도록이면 많은 종류의 툴을 적용할 수 있고, 많은 프로그래밍 기법을 이해하고, 데이터베이스와의 연동 문제, 그리고 데이터베이스 고유의 문제 등을 이해할 수 있으면 더 좋다.

애석하게도 Java/WAS와 데이터베이스(Oracle) 모두의 성능 문제에 대해 통찰력을 지닌 사람은 국내에서 그리 많지 않은 것 같다. 아니 거의 전무하다고 해도 무방할 것이다. 서로가 서로에 대해서 무지하거나 애써 무시하려고 하는 것이 현실이다.

현실적으로 불가피한 면도 있겠지만, 엔지니어들간의 의사 소통과 지식 공유에 대한 노력이 없었다는 점은 피할 수 없는 비평일 것이다.

이런 의미에서 앞으로 이 블로그를 통해서 Enterprise Java와 Oracle을 아우르는 다양한 성능 문제에 대해 논의할 수 있는 시간이 있었으면 하는 개인적인 바램이다.

하지만 이렇게 심플한가?
앞서 [Response Time = Service Time + Wait Time]이라는 간단한 등식을 소개했다. 이 공식만 보면 모든게 단순하고 명확해보인다. Service Time이나 Wait Time만 줄이면 만사 OK 아닌가??!!

음... 하지만 필자의 경험은 그렇게 단순하지 않다는 것이다.

한 가지 예를 들어보자. Application이 Loop를 돌면서 DML을 수행하는 구조로 구현되어 있다. 그리고 이런 작업을 여러 Thread가 동시에 수행한다. 오라클 튜너가 이를 파악하고 모든 Application을 Batch Execution으로 변환하게끔(즉, PreparedStatement.addBatch, executeBatch를 사용하게끔) 유도했다. 상식적으로 생각해보아도 DB와의 통신이 획기적으로 줄고, DB 작업 자체의 일량도 줄어든다.(그 이유는 오라클의 작동 방식과 관련이 있는데 다음 기회에 소개하기로 한다)

즉, Application 입장에서 보면 Wait Time(DB I/O Time)이 줄어들기 때문에 당연히 사용자의 Response Time은 감소해야 한다.

하지만 결과는? Application에서 극단적인 성능 저하가 발생하고 말았다. 그 이유는 다음 두가지...
  1. Batch Execution은 Application에서 더 많은 메모리를 요구한다. 이로 인해 Garbage Collection이 왕성하게 발생한다.
  2. Batch Execution은 한번의 Operation에 Connection을 보유하는 시간이 좀 더길다. 이런 이유로 이전에 비해 더 많은 Connection이 필요해졌지만, Connection Pool의 설정값이 이전 버전에 최적화되어 있어 Connection Pool이 금방 소진되어 버렸다.
즉 Wait Time을 줄이려는 시도가 다른 Side Effect를 불러 오고 이로 인해 다른 종류의 Wait Time-위의 예에서는 GC Pause Time과 Connection Pool 대기 시간-이 증가하는 현상을 초래하고 만 것이다.

이런 사례는 비일비재하다. 마치 부동산 거품을 이야기할 때마다 거론되는 풍선 효과 같은 것이 실제로 Enterprise Java 환경의 성능 문제에서도 발견된다. 이런 풍선 효과를 최소화하려면 시스템 전체를 아우르는 통찰력과 더불어 정밀한 성능 측정과 분석 능력이 필요하다.


앞으로 볼 것들...
서론이 대단히 거창해져버렸다.
(마치 한국 영화처럼 앞은 거창한데 뒤로 갈 수록 힘을 잃게 되지 않을까 걱정...)

앞으로 시리즈글을 통해 Enterprise Java 환경에서의 성능 분석에 필요한 기본적인 툴들과 API, 데이터베이스와의 연동 문제, 그리고 데이터베이스 본연의 문제 등에 대해 논의하는 시간을 가질려고 한다.

여기에는 Java Thread의 동기화, Heap 관리 및 Garbage Collection, JDBC 연동 문제, 오라클 대기 현상과의 관계 등이 포함될 것이다. 그리고
Enterprise Java 환경의 성능 문제에 대해 입문을 하고자 하는 사람들에게 도움이 될 만한 수준이 될 것이다.

너무 거창하고 폭넓은 주제라...
용두 사미가 되지 않도록 기도할 뿐이다.














신고
Trackback 0 : Comments 3
  1. 멀더엄마 2007.08.24 22:02 신고 Modify/Delete Reply

    우리의 경우, 네트워크/웹서버(트래픽확인)> WAS(메모리/CPU) > DB(메모리/CPU 등...모니터링툴) > Application 대략 이런 순서로 성능 문제가 야기된 원인을 찾아감.
    WAS 프로세스가 죽었을 경우, Thread dump 를 떠서 원인을 찾으려고는 하지만 아직 한번도 정확한 원인을 찾은적이 없는듯.

    내가 본 성능문제 발생 유형 몇가지.

    1. Java App 소스 중 매우 자주 쓰는 메쏘드(XML Doc에서 메뉴를 읽어오는)가 synchronized 로 되어 있었음.
    2. WAS 인스턴스의 GC 옵션이 잘못되어(-client 였나?)있어서 GC하는 동안 쌓인 request가 동시에 DB에 몰리면서 DB CPU가 100% 까지 올라감
    3. WAS 버그로 인한(버그 패치를 제때 안함) memory leak 발생

    그리고 솔루션말고 장비의 HW적인 결함때문에 알수없이 응답이 늦어지기도 하고......

    리플쓰기 매우 조심스러움.(내가 리플달면 블로그 수준이 확 떨어진다그래서리.. )

  2. 멀더엄마 2007.08.24 22:20 신고 Modify/Delete Reply

    위에서 두번째 꺼는 .. 이런 케이스.
    메모리를 매우 많이 쓰는 App => GC를 자주 발생시킴(게다가 GC옵션 및 메모리 할당이 잘못되어있음) => DB에 request가 몰려 정상 응답못함. 근데 계속 DB가 응답 늦다고 DB쪽에서만 문제를 찾고 있었음.

    아 졸려. 집에 가고파. (불쌍한 저급 개발자 나부랭이)

  3. 욱짜 2007.08.24 23:10 신고 Modify/Delete Reply

    와 수준높은 리플 감사. 특히 두번째 케이스는 WAS와 Oracle 간의 상관 관계가 잘 설명되는 좋은 사례!!! Thread dump의 경우 Thread간의 Locking 문제를 찾는데는 유용하지만... 몇몇 명확한 케이스를 제외하고는 이걸 이용해서 WAS가 터무니없이 죽는 현상의 원인을 밝히기는 어려울 듯 함...

Write a comment

티스토리 툴바