1. 1.1 성능 계획의 필요성
    1. 1.1.1 요구사항 분석
    2. 1.1.2 분석과 설계
    3. 1.1.3 코딩과 단위 테스트
    4. 1.1.4 통합 및 인수 테스트
  2. 1.2 성능을 고려한 설계
    1. 1.2.1 취약한 논리 데이터베이스 설계
    2. 1.2.2 지나친 범용 테이블 사용
    3. 1.2.3 데이터 무결성을 위한 제약조건 미사용
    4. 1.2.4 취약한 물리데이터베이스 설계
    5. 1.2.5 적합하지 못한 데이터타입 선택
    6. 1.2.6 바인드 변수 미사용
    7. 1.2.7 고급 데이터베이스 기능 미사용
    8. 1.2.8 데이터 중심적인 처리에 PL/SQL 미사용
    9. 1.2.9 불필요한 커밋 수행
    10. 1.2.10 데이터베이스 커넥션을 반복적으로 열고 닫음
  3. 1.3 성능 문제 확인 방법
    1. 1.3.1 시스템 모니터링
    2. 1.3.2 응답시간 모니터링
    3. 1.3.3 튜닝 강박증
  4. 1.4 성능 문제 접근 방법
    1. 1.4.1 비즈니스 관점 vs. 시스템 관점
    2. 1.4.2 문제 분류
    3. 1.4.3 문제 해결

성능

애플리케이션의 핵심 속성

  • 사용자의 씽크 타임 및 오류가 비례 감소
  • S/W, H/W, 유지보수 비용 감소

1.1 성능 계획의 필요성

  • 애플리케이션 개발 필수 단계 (각 단계에서 성능 검토 필요)
    • 요구사항 분석 > 분석 설계 > 코딩 단위 테스트 > 통합 인수 테스트

1.1.1 요구사항 분석

  • 요구 되는 성능 수치 정의 필수
    • 기능별 사용자 규모, 사용 빈도, 사용 방법
      {tip:title=응답시간}
  • 시스템(기능) 요청이 접수된 시점에서 반환한 시점 간격
  • 응답시간(Response Time) = 서비스 시간(Service Time) + 대기 시간(Wait Time)
  • 사용자 응답시간(User Response Time) = 시스템 응답시간(System Response Time) + 외부 구간 소요 시간 (예: ISP)
    {tip}
  • JPetStore 성능 요구 사항 (p.6)
    • 최대 응답 시간 구분 : 90%, 99.99%
      • 모든 요청(100%)의 성능 보장은 불가능(지나친 비용 발생)
    • 분당 최대 트랜잭션 구분 : 00시~07시, 08시~23시
      • 시스템 부하는 시간대에 따라 다름
        {tip:title=SLA(Service Level Agreements)}
  • 서비스 제공자/사용자 간의 관계를 명확히 하는 계약
    • 서비스 항목, 가용성, 응답시간, 고객지원 레벨, 계약 위반시 불이익 등이 정의 됨
  • KPI(Key Performance Indicators) : 위의 목표와 관련된 측정 가능한 성능 수치
    • 목표 충족 여부의 기준, 용량 계획의 근거
  • 성능 수치 측정
    • 계측 값 기록 코드를 어플리케이션에 삽입
    • 응답 시간 모니터링 도구 사용
      {tip}

1.1.2 분석과 설계

  • 높은 부하 처리용 애플리케이션은 요구사항을 만족할 수 있는 설계 필요
    • 병렬 처리, 분산 처리, 결과 재활용 기법 고려
    • 병목 발생 지점 예측 및 해결책 고려 (필요시 프로토타입 개발)
  • 명확한 요구사항(성능수치)이 합리적인 의사 결정 도출 (최소 투자로 요구사항 지원)

1.1.3 코딩과 단위 테스트

  • 코드 요구 사항 (우선 순위를 정하고, 예산 내에서 합리적 선택)
    • 견고성(Robustness) : 예측치 못한 상황에 대처 - 단위 테스트 필수 (범위를 벗어난 파라미터 처리 등)
    • 유지보수성(Maintainability) : 구조화, 문서화 및 높은 가독성 (유지보수 비용 감소)
    • 속도(Speed) : 빠른 수행을 위한 최적화, 트랜젝션 증가를 고려한 확장성
    • 적절한 자원 사용(Shrewd resource utilization) : 가용 자원의 적절한 사용 (필요시 병렬 처리)
    • 보안(Security) : 데이터 기밀성/무결성, 사용자 인증/권한, 부인 방지용 전자 서명
    • 계측(Instrumented) : 기능/성능 문제의 쉬운 분석, 성능 정보 코드 추가
      {tip:title=성급한 최적화(Premature Optimization)}
  • "성급한 최적화는 모든 악의 근원이다" (Donald Knuth)
    • 사소한(지엽적인) 97%는 잊고, 중요한(전역적인) 3% 핵심 코드를 최적화 해야 한다. (O)
    • 코드 작성 시 최적화 신경 쓸 필요 없다. (X)
      {tip}

1.1.4 통합 및 인수 테스트

  • 통합 및 인수 테스트 목적
    • 애플리케이션의 안정성, 기능 요구사항, 성능 요구사항 확인
  • 명확한 성능 요구사항 정의의 부재
    • 체계적 부하 테스트 불가 → 예상 부하 처리 가능 여부 미확인 상태로 운영 시작
    • 인수 가/부 결정(합의) 어려움
  • 통합 및 인수 테스트 수행 과제
    • 실제 상황과 가장 유사한 부하 테스트
    • 실제와 최대한 비슷한 데이터 확보
    • 실제 환경과 동일한 테스트 환경
  • 순차적 생명주기 모델 에서도 코딩 및 단위 테스트 단계에서도 성능 검증 필요 (리스크의 빠른 식별)

1.2 성능을 고려한 설계

  • 데이터베이스 관련 설계 문제 10개만 논의

1.2.1 취약한 논리 데이터베이스 설계

  • "예전에는" 모든 개발 프로젝트에 DA가 참여 (무결성, 성능 보장을 위한 DB 설계)
  • "오늘날은" DB 설계 없는 프로젝트 존재 (개발자가 Persistence Framework 활용하여 DB 생성)
    • DB는 데이터 저장을 위한 바보상자가 아님
      {tip:title=Persistence Framework}
  • O-R 매핑(Object-Relational Mapping) 도구
  • Hibernate, iBatis SQL Maps, Slick, Java Ultra-Lite Persistence
    {tip}

1.2.2 지나친 범용 테이블 사용

  • 유연성 : 변경된 요구사항에 쉽게 대응 → 범용 DB 설계 적용 (객체 변경 불필요)
    • 엔티티-속성-값(Entity - Attribute - Value, EAV) 모델
    • XML 기반 설계 : 식별 키 + XML 컬럼 + 메타 컬럼
  • 성능 관점에서 위의 설계는 잘해야 차선 (성능과 유연성은 대립 관계)
    • 성능 요구 사항 만족 시 적용 가능

1.2.3 데이터 무결성을 위한 제약조건 미사용

  • 제약조건(Constraints)은 데이터 무결성 보장, 실행 계획 생성 시 활용(옵티마이저)
  • 어플리케이션 레벨 제약조건 검사 → 데이터베이스 제약조건 설정
  • 어플리케이션 레벨 검사 단점
    • 더 많은 코드 와 테스트 수반
    • DB 레벨에서 데이터 직접 수정 시 무결성 손실
    • 무결성 유지를 위해 더 많은 리소스 사용 및 확장성 저하

1.2.4 취약한 물리데이터베이스 설계

  • 취약 : 논리 설계 →(곧바로 변환)→ 물리 설계
    • 모든 릴레이션(Relation)을 오라클 기능 활용 없이 힙(Heap) 테이블로 매핑
  • 위는 성능 관점에서 최적 접근법 아님
    • IOT, Indexed Cluster, Hash Cluster 적용 가능
    • B-트리, Bitmap 인덱스 외 기능 제공
      • Compressed, Reverse-Key, Function-Based, Linguistic, Text 인덱스
    • 파티셔닝
    • 데이터 아카이빙 정책 정의, 구현

1.2.5 적합하지 못한 데이터타입 선택

  • 적절치 못한 데이터타입 선택 : DATE 대신 VARCHAR2 에 날짜 저장 케이스
  • 문제점
    • 취약한 데이터 유효성 검증 : DB 외부에서 검증은 1.2.3 과 같은 문제점 야기
    • 정보의 손실 : DATE 타입에 TIMESTAMP 저장시 밀리세컨드 정보 손실
    • 예상대로 동작하지 않음 : 다른 타입 끼리 비교 연산시 다른 의미로 해석될 수 있음 (ORDER BY)
    • 쿼리 옵티마이저 이상 현상 : 옵티마이저가 잘못된 추정 → 잘못된 실행 계획 작성

1.2.6 바인드 변수 미사용

  • 바인드 변수 사용
    • 장점 : LC 에서 커서 공유(하드파싱 감소), SQL Injection 방지
    • 단점 : 옵티마이저에 변수 값 정보 미전달

1.2.7 고급 데이터베이스 기능 미사용

  • 오라클 고급 기능 활용 하여 ROI 극대화
    • 성능 강화, 디버깅/개발 비용 감소 등
  • 이미 DBMS 에서 제공하는 기능 다시 개발 지양
  • 포팅을 고려할 수 있으나 가능성이 낮음

1.2.8 데이터 중심적인 처리에 PL/SQL 미사용

  • 대량 데이터 처리는 SQL 및 PL/SQL 엔진 활용이 유리 함 (소스 타겟이 같은 DB 일 때)
    • ETL(Extract - Transform - Load) : DB 외부에서 변환 수행
    • ELT(Extract - Load - Transform) : DB 내부에서 변환 수행
      • 데이터 중심의 처리는 가능한 데이터와 가까운 곳에서 수행 권장

1.2.9 불필요한 커밋 수행

  • 커밋 : 직렬화 필요 오퍼레이션 (LGWR 프로세스 1개)
    • 확장성을 위해 직렬화는 최소화 필요
    • 여러개의 트랜잭션을 하나로 묶기 (예: 배치 작업)

1.2.10 데이터베이스 커넥션을 반복적으로 열고 닫음

  • 커넥션 열기 : 서버에 전용 프로세스(Dedicated Process) 생성(Fork)
  • 권장 : Connection Pool 사용 (전용 프로세스 재활용)

1.3 성능 문제 확인 방법

  • 성능 요구사항이 잘 정의 되어 있다면, 문제 여부를 쉽게 판단 가능
    • 사용자가 어플리케이션 성능에 불만족
    • 시간초과/비정상부하 가 탐지
    • 응답시간의 SLA 불충족 탐지

1.3.1 시스템 모니터링

  • 일반적인 시스템 통계에 기초하여 헬스 체크 수행
    • 비정상적인 부하 패턴, 장애 발생 감지
  • 전체 인프라스트럭처 각각 모니터링 가능
    • 특정 요소 문제시 전체 영향도 파악 불가 (구성 요소간 상호작용 고려 안됨)
      • False Positive : 특정 요소 문제 발생, 사용자 성능 문제 없음 (QC CPU * 4EA / 사용률 75% / 태스크 수 많음 - 안정)
      • False Negative : 사용자 성능 문제 호소, 개별 요소 문제 없음 (QC CPU * 4EA / 사용률 08% / 태스크 1개 - 병목)

1.3.2 응답시간 모니터링

  • 가상/실제 트랜잭션에 기초해서 헬스 체크 수행
  • 트랜잭션을 수행하는 어플리케이션의 소비 시간 측정 및 임계치 초과시 통보 (SLA 준수 모니터링)
    • 단일 구성 요소 뿐 아니라, 전체 어플리케이션의 인프라스트럭처 검사

1.3.3 튜닝 강박증

  • 한때 대부분 DBA 는 튜닝 강박증(Compulsive Tuning Disorder)을 앓음
    • 단순한 몇가지 규칙으로 DB 튜닝이 가능하다고 생각
    • 비율에 기반을 둔 여러 성능 관련 통계의 지나친 검사 하고 중요한 사용자 경험은 놓침
      • False Negative, False Positive 예외 미 고려

1.4 성능 문제 접근 방법

  • 어플리케이션 성능 최적화 → 이익 극대화
    • 비용과 성능 사이에 최적의 균형점 확보
    • 성능 최적화 작업이 항상 유의미한 것은 아님

1.4.1 비즈니스 관점 vs. 시스템 관점

  • 비즈니스상 문제와 요구사항 먼저 파악
    • 그림 1-2 (p.20)
  • 결과는 비즈니스 관점에서 인식, 원인은 시스템 관점에서 확인
    • 관련 없는 문제(튜닝 강박증)나 없는 문제로 인한 헛수고 감소

1.4.2 문제 분류

  • 문제 분류를 위한 작업
    1. 비즈니스 관점에서 문제 식별
      • 비즈니스 문제는 비즈니스 관점에서 확인
      • SLA 모니터링이 있다면 성능 문제 명백하게 확인 가능, 없다면 애플리케이션 담당자와 대화로 확인
    2. 문제 우선순위 정의
      • 제한된 시간과 예산, 비지니스 요건 고려
      • 문제 해결에 필요한 측정 값이 상충되는 경우 고려
    3. 문제 목표 정의
      • 계량화 할 수 있는 최적화 목표 설정 (예: 최대 2초내 처리)
      • SLA 의 성능 레벨 활용

1.4.3 문제 해결

  • 성능 문제 해결을 위한 질문
    1. 시간을 소모하는 곳이 어디인가?
      • 시간을 대부분 사용하는 모듈이나 컴퍼넌트 찾기
    2. 시간이 어떻게 소모되는가?
      • CPU, DISK I/O, 통신 등으로 구분
    3. 어떻게 하면 소모되는 시간을 줄일 수 있을까?
      • 시간을 많이 소모한 부분에 집중
  • 가장 먼저 해야 할일
    • End - To - End 성능 데이터 수집
      • 오라클 환경 에서는 다중 계층 아키텍처가 사실상 표준
      • 요청을 처리하기 위해 항상 모든 구성요소를 거쳐야 하는 것은 아님
  • 성능 문제 완벽 분석
    • 요청 처리와 관련 있는 모든 구성요소 상세 정보 수집
    • 분할 정복(Divide And Conquer) 방식이 유일하게 효율적인 방법
    • 관련 구성 요소 파악 및 각각 소요 시간 파악
      • 시간을 가장 많이 소모한 구성요소에 대해 추가 정보 수집 (p.24)
  • 성능 데이터 수집
    • 계측 : 어플리케이션 내 계측 기능 활용 (예: SQL Trace)
      • 장점 : 새로운 코드를 배포하지 않고 동적으로 활성화 가능
      • 개발자가 직접 코드를 만들어야 하고, 포멧도 개발자 마다 다름
    • 프로파일링 : 실행 중인 애플리케이션에서 수행한 오프레이션 및 소요 시간, 자원 사용량을 기록하는 성능 분석 도구
      • 장점 : 전체 어플리케이션 범위 대상으로 측정
      • 단점 : 도입 비용 높음
  • 실제 상황에서 프로파일링 분석이 많이 이뤄짐
  • 문제 해결을 위한 조치는 다른 문제 까지 해결 하거나 문제를 만든다. (부작용)