Connection Pool 크기와 타임아웃 설정

connection pool

기본개념

1. Connection Pool의 역할

  • Connection Pool은 애플리케이션이 데이터 베이스와 통신하기 위해 미리 연결을 생성 해 두는 저장소.
  • 연결을 매번 생성/해제 하면 성능이 저하되므로 재사용 가능한 연결 풀을 통해 성능을 최적화한다.

2. 주요 파라미터

  • Maximum Pool Size: 동시에 사용할 수 있는 최대 연결 수.
  • Minium Idle Connections: 사용되지 않을 때 유지할 최소 연결 수.
  • Connection Timeout: 연결 요청 시 대기 할 최대 시간.

Connection Pool 크기 설정

왜 중요하가?

  • 연결 풀 크기가 너무 작으면 요청이 대기 상태가 되어 처리 속도가 느려짐.
  • 연결 풀 크기가 너무 크면 DB서버에 과부하가 발생하여 성능이 저하된다.

단계별 설정

  1. 트래픽 분석
    • 애플리케이션의 동시 사용자 수와 요청 패턴을 분석.
    • ex: 애플리케이션 초당 평균 100개의 요청이 발생하고 각 요청이 50ms동안 연결을 유지한다
      = 100 * 0.05
      = 5(최소 연결 필요) 
  2. DB서버의 제한 확인
    • DB서버가 지원할 수 있는 최대 연결 수를 확인.
    • ex: MySQL SHOW VARIABLES LIKE 'max_connections' ;
  3. 기본 설정
    • 최소 연결 수는 트래픽 분석 결과의 80%로 설정
    • 최대 연결 수는 DB 서버의 최대 연결 수의 80%를 넘지 않도록 설정.
  4. 로드 테스트
    • JMeter, Gating 등의 도구로 예상 트래픽을 시뮬레이션 하여 성능 확인.
    • 연결 풀 부족 시 대기시간이 늘어나는지 확인.

Connection Timeout 설정

  1. 왜 중요한가?
    • 타임아웃을 짧게 설정하면 불필요한 대기 없이 오류를 빠르게 감지할 수 있다.
    • 너무 길게 설정하면 장애 원인 파악이 어려워진다.
    • 너무 짧게 설정하면
      • 네트워크가 느리거나 서버가 과부하일 경우 요청이 처리되기 전 연결이 끊어질 수 있다.
      • 재시도 과정에서 네트워크 대역폭과 서버리소스가 불필요하게 소비된다.
  2. 설정 단계
    1. 요청 응답시간 확인
      • 평균적 DB응답 시간은 수십ms에서 수백ms 수준.
      • ex: 쿼리가 200ms 내외로 완료된다면 타임아웃을 500ms ~ 5000ms 로 설정
    2. Connection Timeout 설정
      • HicariCP의 connection-timeout은 견결을 기다릴 최대 시간이다. (default: 3000ms)
      • 실무에서는 보통 2000~10000ms 사이로 설정한다.
    3. Validation Timeout 추가.
      • 연결 유효성을 검사하는 시간. 일반적으로 1000~5000ms 설정
    4. 실패시 재시도정책
      • 타임아웃 발생 시 재시도를 설정하거나 Circuit Breaker를 사용한다.

성능 최적화

  1. 모니터링 도구를 활용한다.
    • Actuator의 /metrics 엔드포인트에서 hicaricp.connections.*지표를 확인.
    • 그라파나, 프로메테우스와 통합하여 커넥션 풀 상태 모니터링
  2. 쿼리 효율성 확인.
    • 슬로우쿼리가 풀을 점유하지 않도록 주기적으로 쿼리 성능 분석.
    • mysql의 경우 slow_query_log 활성화
  3. 스케일링 전략
    • 트래픽이 지속적으로 증가할 경우 DB와 애플리케이션 인스턴스 수를 증가시킨다.
반응형

 

JVM의 Garbage Collection(GC)

  • Garbage Collection(GC)은 JVM(Java Virtual Machine)에서 동정으로 생성된 객체의 메모리를 자동으로 관리하는 메커니즘. GC는 애플리케이션의 메모리 누수를 방지하고, 더 이상 사용되지 않는 객체를 제거해 메모리를 효율적으로 사용하도록한다.

기본개념

1. GC의 역할

  • JVM이 힙 메모리(Heap Memory)에 생성된 객체 중 더 이상 사용되지 않는 객체를 식별하고 제거한다.
  • 이를 통해 애플리케이션의 메모리 누수를 방지하고, 수동 메모리 관리의 필요성을 제거한다.

2. GC가 관리하는 영역

  • Heap Memory
    • Youg Generation (Eden, Survivor Space)
    • Old Generation (Tenured)
  • Metaspace
    • 클래스 메타데이터를 저장하는 공간.

JVM Heap Memory 구조

1. Young Generation

  • 새로 생성된 객체가 저장됨.
  • 크기가 작고, 객체의 생존 시간이 짧은 경우가 대부분.
  • 구성요소
    • Eden Space: 새로운 객체가 처음 생성되는 공간.
    • Survivor Space: Eden에서 살아남은 객체가 복사되는 공간.

2. Old Generation

  • Young Generation에서 오래 살아남은 객체가 이동.
  • 크기가 크거나 생존 시간이 긴 객체가 저장됨.

3. Metaspace

  • 클레스 로더와 메타데이터 정보를 저장.

GC 동작 과정

1. Minor GC

  • Young Generation에서 발생.
  • 동작 원리
    1. Eden에서 객체가 생성.
    2. Eden이 가득차면 Minor GC가 실행
    3. Eden에서 살아남은 객체가 Survivor Space로 이동.
    4. 여러번의 Minor Gc를 통해 Survivor Space에서 생존한 객체가 Old Generation으로 이동.
  • 특징
    • 실행 속도가 빠르며, Young Generation 크기에 다라 성능이 좌우됨.
    • Stop-The-World qkftod

2. Major GC(Full GC)

  • Old Generation에서 발생
  • 동작 원리
    1. Old Generation이 가득 차면 실행
    2. 사용되지 않는 객체를 제거하고 힙 메모리를 정리
  • 특징
    • 실행 시간이 길고 Stop-The-Wold가 발생
    • Minor GC보다 성능에 더 큰 영향을 미침.

3. GC의 실행 과정(가비지 식별, 처리 과정)

  • Mark: GC는 모든 객체를 순회하며 현재 참조되고 있는 객체를 식별하고 마크
  • Sweep: 마크되지 않은, 즉 참조되지 않는 객체를 메모리에서 제거함.
  • Compact(압축): 객체를 제거하고 남은 메모리 조각들을 모아 연속된 공간을 확보함. 힙메모리 단편화를 해소하는데 도움을 줌.

GC의 종류

JVM은 다양한 GC 알고리즘을 제공한다. 각각의 알고리즘은 GC성능과 애플리케이션 요구사항에 따라 다르다.

1. Serial GC

  • 단일 스레드에서 작동
  • 특징
    • 작은 애플리케이션(싱글 스레드)에 적합.
    • Full GC중 애플리케이션이 멈추는 "Stop-The-Wold"시간이 길다.

2. Parallel Gc(Throughput GC)

  • 여러 스레드를 사용해 GC를 수행
  • 특징
    • 처리량(Throughput) 지향.
    • 적절한 애플리케이션 성능과 낮은 GC비용을 제공.

3.G1 GC

  • Java 9 이후의 기본 GC
  • 특징
    • 힙을 Region으로 나누어 관리.
    • Yong/Old Generation을 따로 구분하지 않고 필요에 따라 Region을 재배치.
    • 짧은 응답 시간과 적은 Stop-The-World 시간을 제공.

4. ZGC

  • 매우 낮은 지연시간을 목표로 설계
  • 특징
    • 대규모 힙을 지원 (최대 16TB)
    • 애플리케이션 중단 시간이 10ms 이내

5. Shenandoah GC

  • 낮은 지연시간을 제공.
  • 특징
    • GC 작업과 애플리케이션 작업을 병렬로 수행.
    • ZGC 보다 짧은 지연시간 제공.

GC 튜닝과 모니터링

1. JVM옵선을 통한 설정

  1. GC 종류 선택
    • -XX:+Use{GCNAME}
    • ex: G1GC -XX:+UseG1GC
  2. Heap 크기 설정
    • Xms: 초기 힙 크기 (ex: Xms512m)
    • Xmx: 최대 힙 크기 (ex: Xmx1024m)
  3. GC로그 활성화
    • -Xlog:gc

2. 주요 GC메트릭 모니터링

  • GC 횟수와 시간: 애플리케이션 성능에 얼마나 영향을 주는지 확인.
  • 힙 사용량: Minor GC및 Major GC 후의 메모리 상태
  • 툴 사용: VisualVM, JConsole, Prometheus && Grafana

3.최적화를 위한 설정

  1. 적절한 Heap크기 설정
    • 너무 작은 힙 크기는 잦은 GC유발
    • 너무 큰 힙 크기는 GC시간이 오래걸림
  2. 객체 생명 주기 관리
    • 불필요한 객체 생성 줄이기
    • 전역 변수 사용 최소화
  3. GC 로그를 통한 분석
    • GC로그를 주기적으로 분석 하여 병목현상을 파악.
    • 애플리케이션 패턴에 따라 GC알고리즘 선택
  4. 메모리 누수 감지
    • 정적 코드 분석 툴을 사용하여 메모리 누수 방지.
반응형

JVM 메모리 구조에 대해 설명해보자

이미지는 JVM Memory 구조와 관련이 없습니다.

  • JVM 메모리 구조는 JVM에서 프로그램이 실행될 때 데이터를 효율적으로 관리하기 위해 나누어진 영억이다. 각 영역은 특정한 역할과 특징을 가지마 애플리케이션의 안정적 실행을 보장한다.

1. Method Area

  • 메소드 영역은 클래스와 관련된 메타데이터, 즉 프로그램의 구조적 정보를 저장하는 영역이다.
  • JVM이 실행되는 동안 공유 메모리 영역으로 사용된다.
  • 저장 내용
    • 클래스 메타데이터: 클래스 이름, 부모 클래스 정보, 인터페이스, 메소드, 필드 등.
    • Static 변수: 클래스 로드 시 초기화되는 정적 변수.
    • Constant Pool(상수 풀): 문자열 상수나 메소드/필드 참조와 같은 상수 정보를 저장.
    • 바이트코드: 각 메소드의 실제 실행 코드.
  • 특징
    • 모든 Thread에서 공유함.
    • JVM이 시작될 때 초기화되고, 종료될 때까지 유지된다.

2. Heap Area

  • 객체와 배열이 동적으로 생성되고 저장되는 메모리 영역.
  • JVM에서 가장 큰 메모리 영역. Garbage Collector에 의해 관리됨.
  • 저장 내용
    • 객체: new 키워드로 생성된 객체.
    • 인스턴스 변수: 객체가 가지고 있는 멤버 변수.
    • 클래스읜 런타임 데이터
  • 구조
    • 힙은 크게 Young GenerationOld Generation 으로 나뉜다.
      1. Young Generation
        • 새로 생성된 객체가 저장되는 영역.
      2. Old Generation
        • Young Generation에서 오래 살아남은 객체가 이동됨.
        • 메모리에서 가장 크고, 주로 긴 생명주기를 가진 객체가 저장됨.
      3. Metaspace(Optional)
        • Java 8 이후 부터 클래스 메타데이터를 관리하는 메모리 공간.
  • 특징
    • 모든 Thread에서 공유함.
    • 메모리가 부족하면 Garbage Collection이 실행됨

3.Stack Area

  • 각 쓰레드마다 독립적으로 생성되는 메모리 영역, 메소드 호출과 관련된 데이터를 관리함.
  • 저장 내용
    • Stack Frame: 메소드 호출 시마다 생성되는 단위.
      • 지역변수: 메소드 내에서 선언된 변수.
      • 매개변수: 메소드 호출 시 전달된 값.
      • 연산 중간 값: 연산 결과 저장.
  • 구조
    • LIFO(Last In, First Out)로 작동
    • 메소드 호출 시 스택 프레임 생성 -> 메소드 종료 시 제거.
  • 특징
    • 각 Thread 마다 독립적으로 생성.
    • 메모리 할당과 해제가 빠름.

4.PC Register

  • 현재 실행 중인 명령어의 조소를 저장하는 메모리 영역
  • JVM의 모든 명령은 순차적으로 실행되기 때문에 이 정보가 필요함
  • 저장 내용
    • 명령어 주소 : 현재 실행중인 JVM 명령어의 메모리 위치
  • 특징
    • 각 Thread 마다 독립적으로 생성
    • Java code 와 Native code 모두에 적용됨.

5. Native Method Stack

  • Java 코드가 아닌, JVM 이 실행하는 네이티브 코드(C, C++)와 관련된 메모리를 관리.
  • JNI(Java Native Interface)를 통해 호출되는 네이티브 메소드에서 사용.
  • 저장 내용
    • 네이티브 메소드의 호출 정보와 실행에 필요한 데이터.
  • 특징
    • 각 쓰레드마다 독립적으로 생성

정리

  1. Method Area: 클래스 메타데이터, static 변수 저장
  2. Heap Area: 객체와 인스턴스 변수 저장
  3. Stack Area: 메소드 호출과 관련된 데이터 저장
  4. PC Register: 현재 실행중인 명령어의 주소 저장.
  5. Native Mtehod Stack: 네이티브 코드 실행과 관련된 메모리.
반응형

+ Recent posts