Post

성능 테스트 패턴 및 안티패턴

4. 성능 테스트 패턴 및 안티패턴

4.1 성능 테스트 유형

좋은 성능 테스트는 정량적(quantitative)

테스트로 확인하고 싶은 정량적 질문 리스트와 그 테스트가 대상 애플리케이션 입장에서 중요한 이유

4.1.1 지연 테스트(latency test)

‘고객이 트랜잭션(또는 페이지 로딩)을 얼마나 오래 참고 기다려야 하는지’

단순 평균값은 애플리케이션의 요청 응답성을 측정하는 지표로 별로 소용이 없음

4.1.2 처리율 테스트(throughput test)

지연을 모니터링하면서 테스트

지연 분포가 갑자기 변하는 시점, 즉 사실상 한계점이 최대 처리율

처리율 테스트는 시스템 성능이 급락하기 직전, 최대 처리율 수치를 측정하는 것이 목표

4.1.3 부하 테스트(load test)

‘시스템이 이 정도 부하는 견딜 수 있을까, 없을까?’

4.1.4 스트레스 테스트(stress test)

시스템 여력이 어느정도인지 알아보는 수단

보통 일정한 수준의 트랜잭션, 즉 특정 처리율을 시스템에 계속 걸어놓음

측정값이 나빠지기 시작하기 직전의 값이 바로 최대 처리율

4.1.5 내구 테스트(endurance test)

메모리 누수, 캐시 오염, 메모리 단편화 등 한참 시간이 지나고 나서야 드러나는 문제점이 있음

대개 이런 종류의 문제는 내구 테스트로 감지

평균 사용률로 시스템에 일정 부하를 계속 주며 모니터링하다가 갑자기 리소스가 고갈되거나 시스템이 깨지는 지점을 찾음

4.1.6 용량 계획 테스트(capacity planning test)

스트레스 테스트는 현재 시스템이 어느 정도 부하를 버틸 수 있는지 알아보는 반면, 용량 계획 테스트는 업그레이드한 시스템이 어느 정도 부하를 감당할 수 있을지 미리 내다보는 것

따라서 어떤 이벤트가 위협 요소에 대응하는 것이 아니라, 예정된 계획의 일부분으로 실행하는 경우가 많음

4.1.7 저하 테스트(degradation test)

저하 테스트는 평상시 운영 환경과 동등한 수준의 부하를 시스템에 가하는 도중, 어떤 컴포넌트나 전체 서브시스템이 갑자기 능력을 상실하는 시점에 벌어지는 일들을 확인

예를 들어, 애플리케이션 서버 클러스터에서 순간적으로 멤버가 사라지거나, DB 서버에서 RAID 디스트가 빠져버리든지, 네트워크 대역폭이 갑자기 줄어드는 경우

카오스 멍키(chaos monkey)라는 하위 유형이 잇다.

카오스 멍키의 요지는 진짜 복원성 있는 아키텍처에서는 어느 한 컴포넌트가 잘못돼도 다른 컴포넌트까지 연쇄적으로 무너뜨리면서 전체 시스템에 부정적 영향을 끼치는 일은 없어야 함

4.2 기본 베스트 프랙티스

  • 나의 관심사가 무엇인지 식별하고 그 측정 방법을 고민한다
  • 최적화하기 용이한 부분이 아니라, 중요한 부분을 최적화
  • 중요한 관심사를 먼저 다룬다

4.2.1 하향식 성능

자바 애플리케이션을 대규모 벤치마킹하는 일이 작은 코드 섹션별로 정확하게 수치를 얻는 것보다 쉽다

하향식 성능이란 전체 애플리케이션의 성능 양상부터 먼저 알아보는 접근 방식

하향식 성능 접근 방식으로 성과를 극대화하려면, 먼저 테스트팀이 테스트 환경을 구축한 다음, 무엇을 측정하고 무엇을 최적화해야 하는지, 또 성능 활동을 전체 소프트웨어 개발 주기에서 어떻게 병행해야 하는지, 전 팀원이 명확하게 이해해야 함

4.2.2 테스트 환경 구축

테스트 환경 구축은 성능 테스트팀이 가장 먼저 할 일

테스트 환경은 가급적 모든 면에서 운영 환경과 똑같이 복제해야 함

운영 환경과 많이 차이 나는 성능 테스트 환경에서는 실제 환경에서 어떤 일들이 일어나지 예측하기 어렵고 쓸모있는 결과를 얻지 못할 가능성이 큼

4.2.3 성능 요건 식별

최적화하려는 핵심 지표: 성능 비기능 요건(NonFunctional Requirement, NFR)

4.2.4 자바에 특정한 이슈

메모리 영역의 동적 튜닝 등 JVM 특유의 다이내믹한 자기 관리 기능

특히, JIT 컴파일

4.2.5 SDLC 일부로 성능 테스트 수행하기

일류 회사, 수준 높은 팀일수록 성능 테스트를 전체 SDLC(Software Development LifeCycle, 소프트웨어 개발 수명주기)의 일부로서 수행하며, 특히 성능 회귀 테스트를 상시 수행하는 편

4.3 성능 안티패턴 개요

안티패턴은 사람들이 수많은 프로젝트를 수행하면서 밝혀낸, 소프트웨어 프로젝트 또는 팀의 좋지 않은 패턴

4.3.1 지루함

지루함으로 인해 억지로 기술을 욱여넣음

4.3.2 이력서 부풀리기

이력서를 과대 포장할 구실을 찾음

4.3.3 또래 압박

기술을 결정할 때 관심사를 분명히 밝히지 않고, 서로 충분한 논의가 없다면 쓰디쓴 결과를 맛보기 쉬임

4.3.4 이해 부족

무턱대고 새로운 툴로 문제를 해결하려고 함

4.3.5 오해와 있지도 않은 문제

문제 자체가 무엇인지 제대로 이해하지 못한 채 오로지 기술을 이용해서 문제를 해결하려고 함

성능 지표를 수집/분석해야만 비로소 문제의 본질을 정확히 이해 가능

4.4 성능 안티패턴 카탈로그

4.4.1 화려함에 사로잡히다

증상

일단 최신의 멋진 기술을 튜닝 타깃으로 정함

흔히 하는 말

처음이라 말썽이 많군

현실

  • 애플리케이션을 측정하고 튜닝하려고 하지 않고 그냥 어떻게 해보면 되겠지, 하고 생각
  • 신기술을 제대로 알지 못한 상태에서 문서도 보지 않고 어설프게 지레짐작만 하는데 실제로 다른 문제가 불거지기 일쑤임
  • 신기술에 관한 온라인 예제는 보통 작은 규모의 전형적인 데이터셋을 다룸

진단

신생팀이나 숙련도가 떨어지는 팀에서 흔함

처방

  • 측정을 해보고 진짜 성능 병목점을 찾으세요
  • 새 컴포넌트는 전후로 충분한 로그를 남기세요
  • 베스트 프랙티스 및 단순화한 데모를 참조하세요
  • 팀원들이 새 기술을 이해하도록 독려하고 팀 차원의 베스트 프랙티스 수준을 정하세요

4.4.2 단순함에 사로잡히다

증상

객관적으로 아픈 부위를 들추려 하지 않고 무작정 시스템에서 제일 간단한 부분만 파고든다

흔히 하는 말

우리가 알고 있는 부분부터 한번 파봅시다

현실

  • 원개발자는 그 시스템 파트를 어떻게 튜닝해야 할지 압니다
  • 다양한 시스템 컴포넌트에 대해 지식 공유를 하지 않고 짝 프로그래밍을 안 한 결과, 독보적인 전문가만 양산됨
  • 신기술에 관한 온라인 예제는 보통 작은 규모의 전형적인 데이터셋을 다룸

진단

시스템을 정상 가동시키는 일이 주임무인, 체계가 잘 잡힌 유지보수 팀에서 흔히 나타나는 안티패턴

처방

  • 측정을 해보고 진짜 성능 병목점을 찾으세요
  • 본인이 익숙지 않은 컴포넌트에 문제가 생기면 잘 아는 전문가에게 도움을 청하세요
  • 개발자가 전체 시스템 컴포넌트를 고루 이해하도록 독려하세요

4.4.3 성능 튜닝 도사

증상

전문가를 채용하고, 사내 모든 성능 이슈를 바로잡으려고 함

흔히 하는 말

나도 문제가 …라는 건 알고 있어

현실

  • 간단한 일에만 도전 함

진단

실력이 부족하다고 여기는 개발 팀원들이 소외감을 느끼게 함

초인을 지향하는 팀원은 매우 반생산적

처방

  • 측정을 해보고 진짜 성능 병목점을 찾으세요
  • 새로 채용된 팀내 전문가가 다른 팀원들과 지식을 공유하고 팀워크를 유지할 수 있게 리드하세요

4.4.4 민간 튜닝

증상

인터넷에 있는 것을 그대로 적용

흔히 하는 말

스택 오버플로에 이런 멋진 팁이 있더라고, 이제 다 끝났어

현실

  • 개발자는 성능 팁의 전후 맥락이나 기초를 모르고 그 팁이 진짜 어떤 영향을 미칠지 모름
  • 어떤 시스템에선 통했을지 모르지만 다른 시스템에 적용해도 효험이 있을지는 모르는 일

진단

성능 팁은 잘 알려준 문제의 해결 방법을 찾는 과정

유통기한이 짧아 금세 낡은 유물이 되기 쉬움

처방

  • 기술을 충분히 파악하고 충분히 검증된 것들만 적용
  • 매개변수를 UAT에서 시험
  • 다른 개발자나 운영 요원, 데브옵스팀과 함께 설정 문제를 리뷰하고 토의함

4.4.5 안되면 조상 탓

증상

정작 이슈와는 아무 상관도 없는 특정 컴포넌트를 문제 삼음

흔히 하는 말

그 머시기 라이브러리가 항상 문제!

현실

  • 충분히 분석도 안 해보고 성급한 결론을 내림
  • 진짜 원인을 밝히려면 숲을 봐야 하는데 팀원들은 그럴 마음이 없음

진단

새로 조사하는 것보다는 보통 문제를 많이 일으키는 곳을 지목하는 게 속 편함 -> 매너리즘에 빠짐

처방

  • 성급한 결론을 내리고픈 욕망에 굴하지 마세요
  • 정상적으로 분석하세요
  • 분석 결과를 모든 이해관계자와 의논하세요

4.4.6 숲을 못 보고 나무만 보다

증상

전체적인 변경 영향도를 완전히 파악하지 않은 채 일단 그냥 변경을 해보거나 애플리케이션의 국소적인 부분만 프로파일링함

흔히 하는 말

이 설정만 바꾸면 성능이 좀 나아질 거야

현실

  • 변경 영향도를 완전히 이해한 사람이 아무도 없다
  • 완전히 프로파일링하지 않음
  • 전체 시스템 영향도를 파악하지 않음

진단

인간의 선입관과 맞물려 실제 있지도 않은 패턴을 존재하는 것처럼 바라보는 일이 반복됨

결국, 성능 엔지니어는 그릇된 통계치와 부실하게 제어한 결과에 현혹된 나머지, 다른 동료들이 반박하지 못하게 사력을 다해 자신의 성능 벤치마크/효과를 방어하는 광경이 펼쳐짐

  • 운영계를 그대로 모사한 UAT 환경 없이 최적화의 효용성을 판단하기는 어려움
  • 부하가 높을 때만 도움이 되고 평소에는 외려 성능을 떨어뜨리는 최적화는 아무 의미가 없음

처방

4.4.7 내 데스크톱이 UAT

증상

UAT 환경이 운영계 환경과 전혀 다른 경우가 많음

흔히 하는 말

UAT 환경을 완벽히 갖추려면 돈이 너무 많이 들어

현실

  • UAT 환경이 운영계와 달라서 서비스가 중단되는 사태가 벌어지면 장비 몇 대 더 추가하는 비용보다 훨씬 더 값비싼 대가를 치르게 됨

진단

어떤 식으로든 유의미한 추정을 하려면 UAT 환경을 운영계와 반드시 동기화해야 함

처방

  • 서비스 중단 비용과 고객 이탈로 인한 기회비용을 잘 따져보세요
  • 운영 환경과 동일한 UAT 환경을 구입하세요
  • 소 잃고 외양간 고치는 비용이 더 많이 들 테니, 이따금 관리자들에게 올바른 사례를 제시해야 함

4.4.8 운영 데이터처럼 만들기는 어려워

증상

사람들이 운영계와 유사한 데이터를 나타내고자 할 때 빠지는 함정

UAT에서 데이터셋을 단순화하여 테스트하는 경우가 많은데요, 그만큼 쓸 만한 결과를 얻을 확률은 떨어짐

흔히 하는 말

UAT-운영계 동기화는 너무 어려워요

시스템에 맞게 데이터를 조작하는 건 정말 삽질이지

현실

  • UAT에서 정확한 결과를 얻으려먼 운영계 데이터와 최대한 맞추어야 함

진단

‘뭐라도 해보는 게 아무것도 안 하는 것보다 낫지 않나?’ 싶은 덫에 빠지게 함

처방

  • 운영 데이터를 UAT로 다시 이전하는 프로세스에 시간과 노력을 투자
  • 철저히 준비

인지 편향과 성능 테스트

인지 편향은 인간의 두뇌가 부정확한 결론을 내리게 이끄는 심리 작용

안티패턴도 대부분, 전체/부분적으로는 하나 이상의 인지 편향으로 비롯된 것들

각 편향은 이중적 또는 상보적

모든 문제의 원인은 소프트웨어

4.5.1 환원주의

시스템을 아주 작은 조각으로 나누어 그 구성 파트를 이해하면 전체 시스템도 다 이해할 수 있다는 분석주의적 사고방식

각 파트를 이해하면 그릇된 가정을 내릴 가능성도 작을 거라는 편향된 논리

단순히 구성 파트를 합한 것보다 시스템을 전체로서 바라봐야 문제의 원인을 찾을 수 있다.

4.5.2 확증 편향

성능 면에서 중대한 문제를 초래하거나, 애플리케이션을 주관적으로 바라보게 함

테스트 세트를 부실하게 선택하거나 테스트 결과를 통계적으로 건전하게 분석하지 않으면 확증 편향의 포로가 되기 쉬움

4.5.3 전운의 그림자(행동 편향)

시스템이 예상대로 작동하지 않는 상황, 또는 아예 중단된 시간 중에 발현되는 편향

  • 영향도를 분석해보지도 않고, 또 다른 사람에게 연략도 안 하고 시스템 인프라를 변경
  • 시스템이 의존하는 라이브러리를 변경
  • 연중 가장 업무가 빠듯한 날에 처음 보는 버그나 경합 조건이 발생

평소 로깅, 모니터링을 꾸준히 하면서 잘 가꾸어 온 애플리케이션은 오류가 발생해도 명확한 에러 메시지가 생성되므로 지원팀이 금세 원인을 찾아낼 수 있음

업무 담당자 모두 체계적으로 문제에 접근하는 태도를 길들이지 않으면 지금까지 이 장에서 살펴본, 사람이기 때문에 벌어지는 문제들이 언제든 발생 가능

4.5.4 위험 편향

누구나 예전에 뭔가 바꿨더니 잘못됐던 경험을 한두 가지 갖고 있어서 가급적 위험을 감수하지 않으려고 함

보통 애플리케이션 문제가 생겼을 때 제대로 학습하고 적절한 조치를 하지 못한 까닭에 더 고착화됨

4.5.5 엘스버그 역설

인간이 확률을 이해하는 데 얼마나 서투른지 잘 보여주는 사례

알려지지 않은 미지의 것 보다 알려진 기지의 것을 추가하는 인간 본연의 욕구에 관한 역설을 주장

4.6 마치며

성능 결과를 평가할 때에는 데이터를 적절한 방법으로 처리하고 비과학적인, 주관적인 사고에 빠지지 않도록 조심해야 함

참조

  1. Optimizing Java(자바 최적화)
This post is licensed under CC BY 4.0 by the author.